This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
expression/src/modules/xforms/xforms.py

1798 lines
69 KiB
Python

# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""XForms Module"""
import libxml2
import expression.core.elements as elements
import expression.core.environs as environs
import expression.core.html as html
import expression.core.locations as locations
import expression.core.logs as logs
import expression.core.namespaces as namespaces
import expression.core.stations as stations
import expression.core.widgets as widgets
import expression.core.xmlschemas as xmlschemas
class Element(elements.Element):
pass
class WidgetElement(widgets.WidgetMixin, Element):
def generateXmlContext(self, context, layout):
return False
def generateHtmlContextControlAlert(self, context, layout):
modelContext = self.getModelContext(context)
alert = self.getAlert(context, modelContext)
if alert is None:
return False
return alert.generateHtmlContextMessage(context, layout)
def generateHtmlContextControlHelp(self, context, layout):
help = self.help
if help is None:
return False
return help.generateHtmlContextMessage(context, layout)
def generateHtmlContextControlHint(self, context, layout):
hint = self.hint
if hint is None:
return False
return hint.generateHtmlContextMessage(context, layout)
def generateHtmlContextControlLabel(self, context, layout):
label = self.label
if label is None:
return False
return label.generateHtmlContextMessage(context, layout)
def getAlert(self, context, modelContext):
alertNodes = self.evaluateXpath("xforms:alert")
if not alertNodes:
return None
alertNode = alertNodes[0]
return self.newElement(alertNode)
def getFieldName(self, context, modelContext):
return self.getParent().getFieldName(context, modelContext)
def getHelp(self):
helpNodes = self.evaluateXpath("xforms:help")
if not helpNodes:
return None
helpNode = helpNodes[0]
return self.newElement(helpNode)
def getHint(self):
hintNodes = self.evaluateXpath("xforms:hint")
if not hintNodes:
return None
hintNode = hintNodes[0]
return self.newElement(hintNode)
def getComputedId(self, context, modelContext):
return self.getParent().getComputedId(context, modelContext)
def getInstanceData(self, context, modelContext):
instanceElement = modelContext.getInstanceElement()
valueNodes = instanceElement.evaluateXpath(self.getInstanceDataXpath(
context, modelContext))
if not valueNodes:
return None
return instanceElement.newElement(valueNodes[0])
def getInstanceDataNode(self, context, modelContext):
valueNodes = self.getInstanceDataNodes(context, modelContext)
if not valueNodes:
return None
return valueNodes[0]
def getInstanceDataNodes(self, context, modelContext):
instance = modelContext.getInstance()
valueNodes = instance.evaluateXpath(self.getInstanceDataXpath(context, modelContext))
return valueNodes
def getInstanceDataType(self, context, modelContext):
# FIXME: What to use for getTypeAtXpath first argument and
# TypeContext second argument? Is it really modelContext?
schemasContext = modelContext.schemas
if schemasContext is None:
return xmlschemas.TypeContext(
xmlschemas.String(), modelContext, previous = modelContext)
instanceElementType = modelContext.getInstanceElementType()
if instanceElementType is None:
return xmlschemas.TypeContext(
xmlschemas.String(), modelContext, previous = modelContext)
instanceDataType = instanceElementType.getTypeAtXpath(
modelContext, self.getInstanceDataXpath(context, modelContext))
if instanceDataType is None:
return xmlschemas.TypeContext(
xmlschemas.String(), modelContext, previous = modelContext)
return instanceDataType
def getInstanceDataXpath(self, context, modelContext):
bindIdNodes = self.evaluateXpath("@bind")
if bindIdNodes:
bindId = bindIdNodes[0].content
bind = modelContext.getBindById(bindId)
if bind is not None:
return "*/%s" % bind.nodeset
modelIdNodes = self.evaluateXpath("@model")
if modelIdNodes:
xpath = ""
elif self.getParent():
xpath = self.getParent().getChildInstanceDataXpath(context, modelContext)
else:
xpath = ""
nodesetNodes = self.evaluateXpath("@nodeset")
if nodesetNodes:
ref = nodesetNodes[0].content
# Quick & dirty hack, so that XForms expressions like:
# <xforms:repeat nodeset="yep:andcriteria | yep:falsecriteria">
# <xform:input>...</xforms:input>
# </xforms:repeat>
# give the following XPath:
# "(yep:andcriteria | yep:falsecriteria)[0]"
# "(yep:andcriteria | yep:falsecriteria)[1]"
# instead of:
# "yep:andcriteria | yep:falsecriteria[0]"
# "yep:andcriteria | yep:falsecriteria[1]"
if "|" in ref:
ref = "(%s)" % ref
else:
refNodes = self.evaluateXpath("@ref")
if refNodes:
ref = refNodes[0].content
else:
ref = ""
if xpath and ref:
xpath = "%s/%s" % (xpath, ref)
else:
xpath = "%s%s" % (xpath, ref)
return xpath
def getLabel(self):
labelNodes = self.evaluateXpath("xforms:label")
if not labelNodes:
return None
labelNode = labelNodes[0]
return self.newElement(labelNode)
def getRealNode(self, context, modelContext):
"""The real node is either the node of this element or the one refered
by the single-node binding attributes."""
# Works only for Single-node binding attributes. Don't use getRealNode
# for elements with node-set binding attributes.
instanceDataXpath = None
bindIdNodes = self.evaluateXpath("@bind")
if bindIdNodes:
bindId = bindIdNodes[0].content
bind = modelContext.getBindById(bindId)
if bind is not None:
instanceDataXpath = "*/%s" % bind.nodeset
refNodes = self.evaluateXpath("@ref")
if refNodes:
ref = refNodes[0].content
modelIdNodes = self.evaluateXpath("@model")
if modelIdNodes:
instanceDataXpath = ""
elif self.getParent():
instanceDataXpath = self.getParent().getChildInstanceDataXpath(
context, modelContext)
else:
instanceDataXpath = ""
if instanceDataXpath:
instanceDataXpath = "%s/%s" % (instanceDataXpath, ref)
else:
instanceDataXpath = ref
if instanceDataXpath is None:
return self.node
instance = modelContext.getInstance()
instanceDataNodes = instance.evaluateXpath(instanceDataXpath)
if not instanceDataNodes:
return self.node
return instanceDataNodes[0]
def newContext(self, specimen, *attributes, **keywords):
return WidgetElementContext(self, specimen, *attributes, **keywords)
def submitContext(self, context):
pass
help = property(getHelp)
hint = property(getHint)
label = property(getLabel)
class WidgetElementContext(html.WidgetElementContext):
pass
class Control(WidgetElement):
"""XForms Control."""
def generateXmlContext(self, context, layout):
# Generate a HTML form either when formCreationNeeded is True or when
# it is not specified (when a XForms control is encountered it is by
# default inside a form).
if context.formCreationNeeded is None or context.formCreationNeeded:
form = html.form(
action = locations.cleanUpUrl(context.getHttpPostUri(), "sessionToken"),
enctype = "multipart/form-data", method = "post")
oldFormCreationNeeded = context.formCreationNeeded
context.formCreationNeeded = False
context.inForm = True
filled = self.generateHtmlContextControl(context, form)
context.formCreationNeeded = oldFormCreationNeeded
context.inForm = False
if filled:
if not environs.getVar("canUseCookie") or environs.getVar("testCookieSupport"):
session = environs.getVar("session")
if session is not None and session.publishToken:
form.append(html.input(
name = "sessionToken", type = "hidden", value = session.token))
layout.append(form)
return filled
else:
return self.generateHtmlContextControl(context, layout)
def generateHtmlContextControl(self, context, layout):
inForm = context.inForm
modelContext = self.getModelContext(context)
relevant = self.isRelevant(context, modelContext)
if not inForm and not relevant:
return False
filled = False
if relevant:
groupingElementClass = self.htmlControlGroupingElementClass
groupingElement = groupingElementClass(class_ = self.getHtmlControlClass(context))
if self.generateHtmlContextControlLabel(context, groupingElement):
filled = True
groupingElementFilled = False
if inForm:
if self.generateHtmlContextControlHelp(context, groupingElement):
groupingElementFilled = True
if self.generateHtmlContextControlHint(context, groupingElement):
groupingElementFilled = True
if self.isReadOnly(context, modelContext):
if self.generateHtmlContextControlCoreReadOnly(context, groupingElement):
groupingElementFilled = True
elif self.generateHtmlContextControlCoreForm(context, groupingElement):
groupingElementFilled = True
if self.generateHtmlContextControlAlert(context, groupingElement):
groupingElementFilled = True
elif self.generateHtmlContextControlCoreStatic(context, groupingElement):
groupingElementFilled = True
if groupingElementFilled:
layout.append(groupingElement)
filled = True
# do not show irrelevant field values in html source, and no need to submit them
#elif inForm:
# if self.generateHtmlContextControlCoreHidden(context, layout):
# filled = True
return filled
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
layout.append(html.input(
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext), type = "text",
value = self.getFieldValue(context)))
return True
def generateHtmlContextControlCoreHidden(self, context, layout):
modelContext = self.getModelContext(context)
layout.append(html.input(
name = self.getFieldName(context, modelContext), type = "hidden",
value = self.getFieldValue(context)))
return True
def generateHtmlContextControlCoreReadOnly(self, context, layout):
filled = False
# no need to submit read-only field values -> no need for a hidden input field
#if self.generateHtmlContextControlCoreHidden(context, layout):
# filled = True
if self.generateHtmlContextControlCoreStatic(context, layout):
filled = True
return filled
def generateHtmlContextControlCoreStatic(self, context, layout):
filled = False
htmlValueNodes = self.getHtmlValueNodes(context)
if htmlValueNodes:
for htmlValueNode in htmlValueNodes:
layout.append(htmlValueNode)
filled = True
return filled
def generatePlainTextContext(self, context):
return self.generatePlainTextContextControl(context)
def generatePlainTextContextControl(self, context):
modelContext = self.getModelContext(context)
if not self.isRelevant(context, modelContext):
return u""
label = self.label
if label is None:
labelText = u""
else:
labelText = label.generatePlainTextContext(context)
coreText = self.generatePlainTextContextControlCore(context)
if labelText and coreText:
return u"%s %s" % (labelText, coreText)
else:
return u"%s%s" % (labelText, coreText)
def generatePlainTextContextControlCore(self, context):
modelContext = self.getModelContext(context)
valueNode = self.getInstanceDataNode(context, modelContext)
if valueNode is None:
return u""
valueType = self.getInstanceDataType(context, modelContext)
return valueType.convertValueNodeToPlainText(valueNode)
def getAlert(self, context, modelContext):
alerts = modelContext.alerts
if alerts is not None:
computedId = self.getComputedId(context, modelContext)
if computedId in alerts:
return AutomaticalAlert(alerts[computedId])
return WidgetElement.getAlert(self, context, modelContext)
def getAppearance(self):
nodes = self.evaluateXpath("@appearance")
if nodes:
return nodes[0].content
else:
return None
def getBind(self, context, modelContext):
bindNodes = self.evaluateXpath("@bind")
if bindNodes:
bindId = bindNodes[0].content
bind = modelContext.getBindById(bindId)
else:
refNodes = self.evaluateXpath("@nodeset | @ref")
if not refNodes:
return WidgetElement.getBind(self, context, modelContext)
bind = modelContext.getBindByInstanceDataXpath(
self.getInstanceDataXpath(context, modelContext))
return bind
def getComputedId(self, context, modelContext):
# FIXME: The try is a quick & dirty hack for the first group label of a description.
try:
instanceDataXpath = self.getRootInstanceDataXpath(context, modelContext)
except AttributeError:
logs.debug("getComputedId(%s, %s, %s): getInstanceDataXpath failed" % (
self, context, modelContext))
return ""
return instanceDataXpath.replace(":", "_")
def getFieldName(self, context, modelContext):
# FIXME: The try is a quick & dirty hack for the first group label of a description.
try:
instanceDataXpath = self.getRootInstanceDataXpath(context, modelContext)
except AttributeError:
logs.debug("getFieldName(%s, %s, %s): getInstanceDataXpath failed" % (
self, context, modelContext))
return ""
return instanceDataXpath.replace(":", "_")
def getFieldValue(self, context):
modelContext = self.getModelContext(context)
valueNode = self.getInstanceDataNode(context, modelContext)
if valueNode is None:
fieldValue = ""
else:
valueType = self.getInstanceDataType(context, modelContext)
fieldValue = valueType.convertValueNodeToHtmlAttributeValue(
valueNode)
return fieldValue
def getHtmlControlClass(self, context):
modelContext = self.getModelContext(context)
computedId = self.getComputedId(context, modelContext)
type = None
valueType = self.getInstanceDataType(context, modelContext)
if isinstance(valueType, xmlschemas.TypeContext):
type = "xsd-%s" % valueType.prototype.__class__.__name__.lower()
controlClass = "%s-%s" % (
namespaces.getName(self.node.ns().content),
self.node.name
)
specimenClass = "%s-%s" % (
namespaces.getName(context.specimen.node.ns().content),
context.specimen.node.name
)
ref = self.node.prop("ref")
if ref:
ref = ref.replace(":", "-").replace("/", "_")
customClass = self.node.prop("class")
required = None
if self.isRequired(context, modelContext):
required = "requiredField"
classes = [
controlClass,
specimenClass,
computedId,
ref,
type,
customClass,
required
]
return " ".join([c for c in classes if c])
def getHtmlControlGroupingElementClass(self):
return html.div
def getHtmlValueNodes(self, context):
modelContext = self.getModelContext(context)
valueNode = self.getInstanceDataNode(context, modelContext)
if valueNode is None:
return []
valueType = self.getInstanceDataType(context, modelContext)
if valueType is None:
return []
return valueType.convertValueNodeToHtmlNodes(valueNode)
def getModelId(self):
modelIdNodes = self.evaluateXpath("@model")
if modelIdNodes:
return modelIdNodes[0].content
return WidgetElement.getModelId(self)
def isReadOnly(self, context, modelContext):
bind = self.getBind(context, modelContext)
if bind is None:
return False
return bind.isReadOnly(
context, modelContext, self.getInstanceDataXpath(context, modelContext))
def isRelevant(self, context, modelContext):
bind = self.getBind(context, modelContext)
if bind is None:
return True
return bind.isRelevant(
context, modelContext, self.getInstanceDataXpath(context, modelContext))
def isRequired(self, context, modelContext):
bind = self.getBind(context, modelContext)
if bind is None:
return False
return bind.isRequired(
context, modelContext, self.getInstanceDataXpath(context, modelContext))
# FIXME: should also look in the schema: "xsd:element[not(@minOccurs) or @minOccurs > 0] | xsd:attribute[@use='required']"
def setFieldValue(self, context, modelContext, fieldValue):
valueNode = self.getInstanceDataNode(context, modelContext)
# FIXME
# assert valueNode is not None
# FIXME: Handle None fieldValue properly.
if valueNode is not None and fieldValue is not None:
# Note: Don't use setContent, because for some nodes it tries to
# convert entities references.
# valueNode.setContent(fieldValue)
if valueNode.children is not None:
childNode = valueNode.children
childNode.unlinkNode()
childNode.freeNodeList()
valueNode.addChild(valueNode.doc.newDocText(fieldValue))
## def setValueNode(self, context, modelContext, valueNode):
## nodes = environs.getVar("currentActionHandler").evaluateXpath(
## self.getInstanceDataXpath(context, modelContext))
## if nodes:
## node = nodes[0]
## node.replaceNode(valueNode)
## node.freeNode()
## else:
## self.node.addChild(valueNode)
def submitContext(self, context):
modelContext = self.getModelContext(context)
if self.isRelevant(context, modelContext) and not self.isReadOnly(context, modelContext):
submission = environs.getVar("submission")
fieldName = self.getFieldName(context, modelContext)
value = submission.getField(fieldName)
valueType = self.getInstanceDataType(context, modelContext)
if valueType is None:
logs.info("""Missing type for value "%s" in field "%s".""" % (value, fieldName))
try:
content = valueType.convertSubmissionValueToContent(value)
except ValueError:
computedId = self.getComputedId(context, modelContext)
modelContext.setErrorLabel(computedId, "emptyValue", N_("Unrecognized Value: %s") % value)
else:
context.specimen.setContentAtXpath(
self.getInstanceDataXpath(context, modelContext), content)
if not content and self.isRequired(context, modelContext):
computedId = self.getComputedId(context, modelContext)
modelContext.setErrorLabel(computedId, "emptyValue", N_("Missing Value"))
htmlControlGroupingElementClass = property(
getHtmlControlGroupingElementClass)
modelId = property(getModelId)
class Message(WidgetElement):
translatable = True
def generateHtmlContextMessage(self, context, layout):
span = html.span(class_ = self.getHtmlMessageClass())
if not self.generateHtmlContextMessageChildren(context, span):
return False
layout.append(span)
return True
def generateHtmlContextMessageChildren(self, context, layout):
filled = False
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
childNode = realNode.children
while childNode is not None:
if childNode.type in ("cdata", "text"):
content = childNode.content
layout.append(content)
filled = True
childNode = childNode.next
continue
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
if element.generateXmlContext(context, layout):
filled = True
childNode = childNode.next
return filled
def getHtmlMessageClass(self):
return self.node and self.node.prop("class") or self.htmlMessageClass
class Alert(Message):
htmlMessageClass = "xforms-alert"
class AutomaticalAlert(Alert):
message = None
def __init__(self, message):
# Dont' call inherited.
if message is not None:
self.message = message
def generateHtmlContextMessageChildren(self, context, layout):
# Dont' call inherited.
filled = False
if self.message:
layout.append(_(self.message))
filled = True
return filled
class Bind(Element):
def buildXformsModelContext(self, context):
nodeset = self.nodeset
if context.bindsByNodeset is None:
context.bindsByNodeset = {}
context.bindsByNodeset[nodeset] = self
id = self.id
if id is not None:
if context.bindsById is None:
context.bindsById = {}
context.bindsById[id] = self
def getNodeset(self):
sourceNodes = self.evaluateXpath("@nodeset")
if sourceNodes:
return sourceNodes[0].content
else:
return None
def isReadOnly(self, context, modelContext, instanceDataXpath):
sourceNodes = self.evaluateXpath("@readonly")
if sourceNodes:
formula = sourceNodes[0].content
instance = modelContext.getInstance()
# Note: we can't use instanceData as base for evaluateXpath,
# because it can be None. So we use instance, but we should change
# the paths in formula so that they are relative to instance
# instead of instanceData (dirty hack needed because of a stupid
# XForms design decision). FIXME: TODO
return bool(instance.evaluateXpath(formula))
else:
return False
def isRelevant(self, context, modelContext, instanceDataXpath):
sourceNodes = self.evaluateXpath("@relevant")
if sourceNodes:
formula = sourceNodes[0].content
instance = modelContext.getInstance()
# Note: we can't use instanceData as base for evaluateXpath,
# because it can be None. So we use instance, but we should change
# the paths in formula so that they are relative to instance
# instead of instanceData (dirty hack needed because of a stupid
# XForms design decision). FIXME: TODO
return bool(instance.evaluateXpath(formula))
else:
return True
def isRequired(self, context, modelContext, instanceDataXpath):
sourceNodes = self.evaluateXpath("@required")
if sourceNodes:
formula = sourceNodes[0].content
instance = modelContext.getInstance()
# Note: we can't use instanceData as base for evaluateXpath,
# because it can be None. So we use instance, but we should change
# the paths in formula so that they are relative to instance
# instead of instanceData (dirty hack needed because of a stupid
# XForms design decision). FIXME: TODO
return bool(instance.evaluateXpath(formula))
else:
return False
def getTypeName(self):
sourceNodes = self.evaluateXpath("@type")
if sourceNodes:
return sourceNodes[0].content
else:
return None
nodeset = property(getNodeset)
class Choices(WidgetElement):
def generateHtmlContextControlCheckBoxesForm(
self, context, layout, checkedValues):
filled = False
li = html.li(class_ = "xforms-choices")
liFilled = False
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
ulFilled = False
ul = html.ul()
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlCheckBoxesForm(
context, ul, checkedValues):
ulFilled = True
if ulFilled:
li.append(ul)
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlCheckBoxesStatic(
self, context, layout, checkedValues):
filled = False
li = html.li(class_ = "xforms-choices")
liFilled = False
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
ulFilled = False
ul = html.ul()
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlCheckBoxesStatic(
context, ul, checkedValues):
ulFilled = True
if ulFilled:
li.append(ul)
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlOptionsForm(self, context, layout, value):
filled = False
optgroup = html.optgroup(class_ = "xforms-choices")
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlOptionsForm(
context, optgroup, value):
filled = True
if filled:
self.label.generateHtmlContextMessageChildren(context, optgroup)
layout.append(optgroup)
return filled
def generateHtmlContextControlOptionsStatic(self, context, layout, value):
filled = False
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlOptionsStatic(
context, layout, value):
filled = True
return filled
def generateHtmlContextControlRadiosForm(self, context, layout, value):
filled = False
li = html.li(class_ = "xforms-choices")
liFilled = False
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
ulFilled = False
ul = html.ul()
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlRadiosForm(
context, ul, value):
ulFilled = True
if ulFilled:
li.append(ul)
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlRadiosStatic(self, context, layout, value):
filled = False
itemOrChoicesNodes = self.evaluateXpath("xforms:item | xforms:choices")
for itemOrChoicesNode in itemOrChoicesNodes:
element = self.newElement(itemOrChoicesNode)
if element.generateHtmlContextControlRadiosStatic(
context, layout, value):
filled = True
return filled
class Group(Control):
def generateHtmlContextControlCore(self, context, layout):
filled = False
childNode = self.node.children
while childNode is not None:
if childNode.type in ("cdata", "text"):
layout.append(childNode.content)
filled = True
childNode = childNode.next
continue
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
if element.generateXmlContext(context, layout):
filled = True
childNode = childNode.next
return filled
def generateHtmlContextControlCoreForm(self, context, layout):
return self.generateHtmlContextControlCore(context, layout)
def generateHtmlContextControlCoreHidden(self, context, layout):
return self.generateHtmlContextControlCore(context, layout)
def generateHtmlContextControlCoreReadOnly(self, context, layout):
return self.generateHtmlContextControlCore(context, layout)
def generateHtmlContextControlCoreStatic(self, context, layout):
return self.generateHtmlContextControlCore(context, layout)
def submitContext(self, context):
childNode = self.node.children
while childNode is not None:
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
elementContext = element.newContext(context.specimen, previous = context)
elementContext.submit()
childNode = childNode.next
class Help(Message):
htmlMessageClass = "xforms-help"
class Hint(Message):
htmlMessageClass = "xforms-hint"
class Input(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
fieldName = self.getFieldName(context, modelContext)
id = self.getComputedId(context, modelContext)
valueType = self.getInstanceDataType(context, modelContext)
if isinstance(valueType.prototype, xmlschemas.DateTime):
layout.append(html.input(
id = id, maxlength = "16", name = fieldName,
size = "16", type = "text",
value = self.getFieldValue(context)))
layout.append(html.img(
id= "%s_trigger" % id,
src = context.constructUri("/javascript/jscalendar/img.png"),
style = "cursor: pointer;",
title = _("Date Selector"),
onload = """Calendar.setup({
inputField: "%s",
ifFormat: "%%d/%%m/%%Y %%H:%%M",
button: "%s_trigger",
singleClick: true,
showsTime: true
})
""" % (id, id),
onmouseout="this.style.background=''",
onmouseover = "this.style.background='';"))
elif isinstance(valueType.prototype, xmlschemas.Date):
layout.append(html.input(
id = id, maxlength = "10", name = fieldName,
size = "10", type = "text",
value = self.getFieldValue(context)))
layout.append(html.img(
id= "%s_trigger" % id,
src = context.constructUri("/javascript/jscalendar/img.png"),
style = "cursor: pointer;",
title = _("Date Selector"),
onload = """Calendar.setup({
inputField: "%s",
ifFormat: "%%d/%%m/%%Y",
button: "%s_trigger",
singleClick: true
})
""" % (id, id),
onmouseout="this.style.background=''",
onmouseover = "this.style.background='';"))
elif isinstance(valueType.prototype, xmlschemas.Boolean):
input = html.input(id = id, name = fieldName, type = "checkbox", value = "1")
if self.getFieldValue(context) in ("1", "true"):
input.node.setProp("checked", "true")
layout.append(input)
else:
layout.append(html.input(
id = id, name = fieldName, type = "text",
value = self.getFieldValue(context)))
return True
class Instance(Element):
_rootElement = None
def buildXformsModelContext(self, context):
if context.defaultInstance is None:
context.defaultInstance = self
id = self.id
if id is not None:
if context.instancesById is None:
context.instancesById = {}
context.instancesById[id] = self
def getRootElement(self):
if self._rootElement is None:
rootNode = self.getRootNode()
if rootNode is None:
return None
# There doesn't exist any URI path to access a rootElement => no uriPathFragment.
self._rootElement = elements.newElement(rootNode, previous = self, owner = self)
rootElement = self._rootElement
return rootElement
def getRootNode(self):
rootNodes = self.evaluateXpath("*")
if not rootNodes:
return None
return rootNodes[0]
class DummyInstance(object):
"""This Instance class is used to encapsulate an Expression element, so that it behaves like
an XForms instance."""
_rootElement = None
def __init__(self, rootElement):
self._rootElement = rootElement
def buildXformsModelContext(self, context):
if context.defaultInstance is None:
context.defaultInstance = self
id = self.id
if id is not None:
if context.instancesById is None:
context.instancesById = {}
context.instancesById[id] = self
def evaluateXpath(self, xpath, contextNode = None):
return self._rootElement.evaluateXpath(xpath, contextNode)
def getRootElement(self):
return self._rootElement
def serialize(self):
return self._rootElement.serialize()
class Item(WidgetElement):
def generateHtmlContextControlCheckBoxesForm(
self, context, layout, checkedValues):
filled = False
li = html.li(class_ = "xforms-item")
liFilled = False
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
if self.value.generateHtmlContextValueCheckBoxForm(
context, li, checkedValues):
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlCheckBoxesStatic(self, context, layout, checkedValues):
modelContext = self.getModelContext(context)
value = self.value
if value.getRealNode(context, modelContext).content not in checkedValues:
return False
filled = False
li = html.li(class_ = "xforms-item")
liFilled = False
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
if value.generateHtmlContextValueCheckBoxStatic(context, li, checkedValues):
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlOptionsForm(self, context, layout, value):
filled = False
if self.value.generateHtmlContextValueOptionForm(
context, layout, value):
filled = True
return filled
def generateHtmlContextControlOptionsStatic(self, context, layout, value):
filled = False
if self.value.generateHtmlContextValueOptionStaticSimple(
context, layout, value
):
filled = True
return filled
def generateHtmlContextControlRadiosForm(self, context, layout, value):
filled = False
li = html.li(class_ = "xforms-item")
liFilled = False
if self.generateHtmlContextControlHelp(context, li):
liFilled = True
if self.generateHtmlContextControlHint(context, li):
liFilled = True
if self.value.generateHtmlContextValueRadioForm(context, li, value):
liFilled = True
if self.generateHtmlContextControlAlert(context, li):
liFilled = True
if self.generateHtmlContextControlLabel(context, li):
liFilled = True
if liFilled:
layout.append(li)
filled = True
return filled
def generateHtmlContextControlRadiosStatic(self, context, layout, value):
modelContext = self.getModelContext(context)
value = self.value
if value.getRealNode(context, modelContext).content != value:
return False
filled = False
if self.generateHtmlContextControlHelp(context, layout):
filled = True
if self.generateHtmlContextControlHint(context, layout):
filled = True
if value.generateHtmlContextValueRadioStatic(context, layout, value):
filled = True
if self.generateHtmlContextControlAlert(context, layout):
filled = True
if self.generateHtmlContextControlLabel(context, layout):
filled = True
return filled
def getComputedId(self, context, modelContext):
value = self.value.getRealNode(context, modelContext).content
return "%s_%s" % (self.getParent().getComputedId(context, modelContext), value)
def getValue(self):
valueNodes = self.evaluateXpath("xforms:value")
if not valueNodes:
return None
valueNode = valueNodes[0]
return self.newElement(valueNode)
value = property(getValue)
class Label(Message):
htmlMessageClass = "xforms-label"
def generateHtmlContextMessage(self, context, layout):
label = html.label(class_ = self.getHtmlMessageClass())
if context.inForm:
modelContext = self.getModelContext(context)
id = self.getComputedId(context, modelContext)
if id:
label.node.setProp("for", id)
if not self.generateHtmlContextMessageChildren(context, label):
return False
layout.append(label)
return True
class Model(WidgetElement):
def buildXformsContext(self, context):
modelContext = ModelContext(
self, context, previous = context, uriPathFragment = "model")
if context.xformsDefaultModel is None:
context.xformsDefaultModel = modelContext
id = self.id
if id is not None:
if context.xformsModelsById is None:
context.xformsModelsById = {}
context.xformsModelsById[id] = modelContext
schemaLocations = self.schemaLocations
for schemaLocation in schemaLocations:
schemaAbsolutePath = self.convertRelativeLocationToAbsolutePath(schemaLocation)
if schemaAbsolutePath is None:
logs.debug('Missing schema file "%s".' % schemaLocation)
continue
schemaHolder = xmlschemas.getSchemaHolder(schemaAbsolutePath)
if schemaHolder is None:
logs.debug('Missing schema file "%s".' % schemaLocation)
continue
schema = schemaHolder.getRootElement()
if environs.getVar("debug"):
if schema.validateElement(context.specimen.node):
logs.debug("%s is valid against %s." % (context.specimen, schema))
else:
logs.warning("%s is NOT valid against %s." % (context.specimen, schema))
if modelContext.schemas is None:
modelContext.schemas = xmlschemas.SchemasContext(
modelContext.specimen, previous = modelContext, uriPathFragment = "schemas")
schemasContext = modelContext.schemas
if schemasContext.schemas is None:
schemasContext.schemas = []
schemasContext.schemas.append(schema)
childNode = self.node.children
while childNode is not None:
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
element.buildXformsModelContext(modelContext)
childNode = childNode.next
def generateXmlContext(self, context, layout):
self.buildXformsContext(context)
return False
def getInstanceNode(self, schemaNameWithNamespace):
instanceNodes = self.evaluateXpath(
"xforms:instance/%s" % schemaNameWithNamespace)
if not instanceNodes:
return None
return instanceNodes[0]
def getModelId(self):
return self.id
def getSchemaLocations(self):
schemaLocationsNodes = self.evaluateXpath("@schema")
if not schemaLocationsNodes:
return []
schemaLocations = schemaLocationsNodes[0].content
return schemaLocations.split()
def getSubmissionNode(self, id = None):
if id is None:
submissionNodes = self.evaluateXpath(
"xforms:submission[@id = '%s']" % id.replace("'", "&apos;"))
else:
submissionNodes = self.evaluateXpath("xforms:submission")
if not submissionNodes:
return None
return submissionNodes[0]
modelId = property(getModelId)
schemaLocations = property(getSchemaLocations)
class ModelContext(stations.AbstractContext):
alerts = None
bindsById = None
bindsByNodeset = None
defaultInstance = None
embedder = None
embedderContext = None
errors = None
instancesById = None
schemas = None
def getBindById(self, id):
if self.bindsById is not None and id in self.bindsById:
return self.bindsById[id]
else:
return None
def getBindByInstanceDataXpath(self, instanceDataXpath):
if self.bindsByNodeset is None \
or not instanceDataXpath in self.bindsByNodeset:
return None
return self.bindsByNodeset[instanceDataXpath]
def getInstance(self):
id = None # FIXME
if id is None:
instance = self.defaultInstance
else:
instance = self.instancesById[id]
return instance
def getInstanceElement(self):
instance = self.getInstance()
if instance is None:
return None
return instance.getRootElement()
def getInstanceElementType(self):
instanceElement = self.getInstanceElement()
instanceElementType = instanceElement.type
if instanceElementType is not None:
return instanceElementType
if self.schemas is not None:
return self.schemas.getValueType(instanceElement)
return None
def setErrorLabel(self, computedId, symbol, label, override = False):
if self.errors is None:
self.errors = {}
if computedId not in self.errors or override:
self.errors[computedId] = symbol
if self.alerts is None:
self.alerts = {}
if computedId not in self.alerts or override:
self.alerts[computedId] = label
class Output(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
layout.append(html.span(self.getFieldValue(context)))
return True
def generateHtmlContextControlRequired(self, context, layout):
return False
def getHtmlControlGroupingElementClass(self):
return html.span
def isReadOnly(self, context, modelContext):
return True
def isRequired(self, context, modelContext):
return False
def submitContext(self, context):
pass
htmlControlGroupingElementClass = property(
getHtmlControlGroupingElementClass)
class Range(Input):
pass
class Repeat(Control):
index = None
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
countName = "%s-count" % self.getFieldName(context, modelContext)
count = 0
valueNodes = self.getInstanceDataNodes(context, modelContext)
count = max(0, count, len(valueNodes))
layout.append(html.input(name = countName, type = "hidden", value = str(count)))
ul = html.ul(class_ = "multi")
layout.append(html.div(ul))
filled = False
for i in range(count):
#~ if i >= len(valueNodes):
#~ self.index = None
#~ else:
#~ self.index = i
self.index = i
li = html.li()
ul.append(li)
childNode = self.node.children
while childNode is not None:
if childNode.type in ("cdata", "text"):
li.append(childNode.content)
childNode = childNode.next
continue
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
filled |= element.generateXmlContext(context, li)
childNode = childNode.next
return filled
def generateHtmlContextControlCoreHidden(self, context, layout):
filled = False
modelContext = self.getModelContext(context)
countName = "%s-count" % self.getFieldName(context, modelContext)
count = 0
valueNodes = self.getInstanceDataNodes(context, modelContext)
count = max(0, count, len(valueNodes))
layout.append(html.input(name = countName, type = "hidden", value = str(count)))
for i in range(len(valueNodes)):
self.index = i
childNode = self.node.children
while childNode is not None:
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
if element.generateHtmlContextControlCoreHidden(context, layout):
filled = True
childNode = childNode.next
return filled
def generateHtmlContextControlCoreStatic(self, context, layout):
filled = False
modelContext = self.getModelContext(context)
valueNodes = self.getInstanceDataNodes(context, modelContext)
if not valueNodes:
return filled
ul = html.ul(class_ = "multi")
for i in range(len(valueNodes)):
self.index = i
li = html.li()
ul.append(li)
childNode = self.node.children
while childNode is not None:
if childNode.type in ("cdata", "text"):
li.append(childNode.content)
filled = True
childNode = childNode.next
continue
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
if element.generateXmlContext(context, li):
filled = True
childNode = childNode.next
if filled:
layout.append(ul)
return filled
def getFieldValue(self, context):
return None
def getChildInstanceDataXpath(self, context, modelContext):
return "%s[%d]" % (self.getInstanceDataXpath(context, modelContext), self.index + 1)
def submitContext(self, context):
modelContext = self.getModelContext(context)
countName = "%s-count" % self.getFieldName(context, modelContext)
count = 0
submission = environs.getVar("submission")
if submission.hasField(countName):
try:
count = int(submission.getField(countName))
except (TypeError, ValueError):
pass
for i in range(count):
self.index = i
childNode = self.node.children
while childNode is not None:
if childNode.type != "element":
childNode = childNode.next
continue
element = self.newElement(childNode)
elementContext = element.newContext(context.specimen, previous = context)
elementContext.submit()
childNode = childNode.next
class Secret(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
layout.append(html.input(
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext), type = "password",
value = self.getFieldValue(context)))
return True
def generateHtmlContextControlCoreStatic(self, context, layout):
layout.append("*" * len(self.getFieldValue(context)))
return True
class Select(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
""" Renders as an HTML checkbox list appended to layout.
Returns whether something was appended to layout.
"""
selectedValues = self.getSelectedValues(context)
filled = False
ul = html.ul()
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlCheckBoxesForm(context, ul, selectedValues)
if filled:
layout.append(ul)
return filled
def generateHtmlContextControlCoreStatic(self, context, layout):
""" Renders as an HTML read-only list appended to layout.
Returns whether something was appended to layout.
"""
selectedValues = self.getSelectedValues(context)
filled = False
ul = html.ul()
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlCheckBoxesStatic(context, ul, selectedValues)
if filled:
layout.append(ul)
return filled
def getAvailableValues(self, context):
""" Returns a list with all available values.
"""
return [node.content for node in self.evaluateXpath(".//xforms:value")]
def getSelectedValues(self, context):
""" Returns the list of selected value strings.
"""
node = self.getInstanceDataNode(context, self.getModelContext(context))
return node and node.content.split(" ") or []
def getItemOrChoiceElements(self, context):
""" Returns a list of elements that provide methods:
- generateHtmlContextControlCheckBoxesForm
- generateHtmlContextControlCheckBoxesStatic
"""
return [self.newElement(node) for node in self.evaluateXpath("xforms:item | xforms:choices")]
def submitContext(self, context):
""" Updates the context specimen with submitted data for this control.
Sets an error if no data was submitted.
"""
submission = environs.getVar("submission")
modelContext = self.getModelContext(context)
fieldName = self.getFieldName(context, modelContext)
splitedValue = []
if submission.hasField(fieldName):
submissionValue = submission.getField(fieldName)
for itemValue in self.getAvailableValues(context):
if isinstance(submissionValue, list) and itemValue in submissionValue \
or itemValue == submissionValue:
splitedValue.append(itemValue)
context.specimen.setContentAtXpath(
self.getInstanceDataXpath(context, modelContext),
" ".join(splitedValue)
)
if not splitedValue and self.isRequired(context, modelContext):
computedId = self.getComputedId(context, modelContext)
modelContext.setErrorLabel(computedId, "emptyValue", N_("Missing Value"))
class Select1(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
""" Renders and appends to layout either as an HTML radio button list, or an HTML select control.
Returns whether something was appended to layout.
"""
modelContext = self.getModelContext(context)
value = self.getSelectedValue(context)
filled = False
appearance = self.getAppearance()
if appearance == "full":
ul = html.ul()
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlRadiosForm(context, ul, value)
if filled:
layout.append(ul)
else: # appearance == "minimal"
select = html.select(
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext)
)
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlOptionsForm(context, select, value)
if filled:
layout.append(select)
return filled
def generateHtmlContextControlCoreStatic(self, context, layout):
""" Renders and appends to layout as a list.
Returns whether something was appended to layout.
"""
modelContext = self.getModelContext(context)
value = self.getSelectedValue(context)
filled = False
appearance = self.getAppearance()
if appearance == "full":
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlRadiosStatic(context, layout, value)
else: # appearance == "minimal"
for element in self.getItemOrChoiceElements(context):
filled |= element.generateHtmlContextControlOptionsStatic(context, layout, value)
return filled
def getAvailableValues(self, context):
""" Returns a list with all available values.
"""
return [node.content for node in self.evaluateXpath(".//xforms:value")]
def getItemOrChoiceElements(self, context):
""" Returns a list of elements that provide methods:
- generateHtmlContextControlRadiosForm
- generateHtmlContextControlOptionsForm
- generateHtmlContextControlRadiosStatic
- generateHtmlContextControlOptionsStatic
"""
return [self.newElement(node) for node in self.evaluateXpath("xforms:item | xforms:choices")]
def getSelectedValue(self, context):
""" Returns the selected value.
"""
node = self.getInstanceDataNode(context, self.getModelContext(context))
return node and node.content or None
def submitContext(self, context):
""" Updates the context specimen with submitted data for this control.
Sets an error if the submitted value is not available.
Sets an error if no data was submitted.
"""
submission = environs.getVar("submission")
modelContext = self.getModelContext(context)
fieldName = self.getFieldName(context, modelContext)
value = submission.getField(fieldName, default = "")
context.specimen.setContentAtXpath(self.getInstanceDataXpath(context, modelContext), value)
if value not in self.getAvailableValues(context):
computedId = self.getComputedId(context, modelContext)
modelContext.setErrorLabel(
computedId, "wrongValue", N_("Wrong Value"))
elif not value and self.isRequired(context, modelContext):
computedId = self.getComputedId(context, modelContext)
modelContext.setErrorLabel(
computedId, "emptyValue", N_("Missing Value"))
class Submission(Element):
def buildXformsModelContext(self, context):
# FIXME: TODO
pass
class Submit(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
layout.append(html.input(
class_ = "button", name = self.getSubmissionId(), type = "submit",
value = self.label.node.content))
return True
def generateHtmlContextControlCoreStatic(self, context, layout):
label = self.label
if label is None:
return False
a = html.a(class_ = 'button', href = self.getSubmissionActionUri(
context))
if not label.generateHtmlContextMessageChildren(context, a):
return False
layout.append(a)
return True
def generateHtmlContextControlCoreHidden(self, context, layout):
return False
def generateHtmlContextControlLabel(self, context, layout):
return False
def getSubmissionActionUri(self, context):
# FIXME: TODO
return None
submissionId = self.getSubmissionId()
submissionNode = self.getModel(context).getSubmission(submissionId)
if submissionNode is None:
return None
actionNodes = self.evaluateXpath("@action", submissionNode)
if not actionNodes:
return None
return context.constructUri(actionNodes[0].content)
def getSubmissionId(self):
submissionIdNodes = self.evaluateXpath("@submission")
if submissionIdNodes:
submissionId = submissionIdNodes[0].content
else:
submissionId = None
return submissionId
def getFieldValue(self, context):
return None
class TextArea(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
if self.getAppearance() == "full":
attributes = {"cols": "80", "rows": "10"}
else:
attributes = {"cols": "60", "rows": "4"}
layout.append(html.textarea(
self.getFieldValue(context),
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext), **attributes))
return True
class Trigger(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
# Unlike Submit Control, a Trigger never submits the form even inside
# a form.
label = self.label
if label is None:
return False
a = html.a(
class_ = 'button', href = self.getLoadResourceUri(context))
if not label.generateHtmlContextMessageChildren(context, a):
return False
layout.append(a)
return True
def generateHtmlContextControlCoreStatic(self, context, layout):
label = self.label
if label is None:
return False
a = html.a(
class_ = 'button', href = self.getLoadResourceUri(context))
if not label.generateHtmlContextMessageChildren(context, a):
return False
layout.append(a)
return True
def generateHtmlContextControlCoreHidden(self, context, layout):
return False
def generateHtmlContextControlLabel(self, context, layout):
return False
def getFieldValue(self, context):
return None
def getLoadResourceUri(self, context):
loadNodes = self.evaluateXpath("xforms:load[@ev:event='DOMActivate']")
if not loadNodes:
return None
loadNode = loadNodes[0]
resourceNodes = self.evaluateXpath("@resource", loadNode)
if not resourceNodes:
refNodes = self.evaluateXpath("@ref", loadNode)
if not refNodes:
return None
ref = refNodes[0].content
## resourceNodes = self.getInstanceDataNodes(context, subXpath = ref)
modelContext = self.getModelContext(context)
instanceDataNode = self.getInstanceDataNode(context, modelContext)
if instanceDataNode is None:
return None
instance = modelContext.getInstance()
resourceNodes = instance.evaluateXpath(ref, contextNode = instanceDataNode)
if not resourceNodes:
return None
resource = resourceNodes[0].content
return context.constructUri(resource)
class Upload(Control):
def generateHtmlContextControlCoreForm(self, context, layout):
modelContext = self.getModelContext(context)
fieldName = self.getFieldName(context, modelContext)
computedId = self.getComputedId(context, modelContext)
layout.append(html.input(
id_ = computedId, name = fieldName, type = "file"))
return True
class Value(WidgetElement):
def generateHtmlContextValueCheckBoxForm(self, context, layout, checkedValues):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue in checkedValues:
attributes = {"checked": "checked"}
else:
attributes = {}
layout.append(html.input(
class_ = "xforms-value",
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext), type = "checkbox",
value = itemValue, **attributes))
return True
def generateHtmlContextValueCheckBoxStatic(self, context, layout, checkedValues):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue in checkedValues:
class_ = "xforms-value-checkbox-checked"
else:
class_ = "xforms-value-checkbox-unchecked"
layout.append(html.span(class_ = class_))
return True
def generateHtmlContextValueOptionForm(self, context, layout, value):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue == value:
attributes = {"selected": "selected"}
else:
attributes = {}
option = html.option(
class_ = "xforms-value", value = itemValue, **attributes)
layout.append(option)
self.getParent().label.generateHtmlContextMessageChildren(context, option)
return True
def generateHtmlContextValueOptionStatic(self, context, layout, value):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue == value:
class_ = "xforms-value-option-selected"
else:
class_ = "xforms-value-option-unselected"
span = html.span(class_ = class_)
layout.append(span)
self.getParent().label.generateHtmlContextMessageChildren(context, span)
return True
def generateHtmlContextValueOptionStaticSimple(self, context, layout, value):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue == value:
span = html.span()
layout.append(span)
self.getParent().label.generateHtmlContextMessageChildren(context, span)
return True
return False
def generateHtmlContextValueRadioForm(self, context, layout, value):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue == value:
attributes = {"checked": "checked"}
else:
attributes = {}
layout.append(html.input(
class_ = "xforms-value",
id = self.getComputedId(context, modelContext),
name = self.getFieldName(context, modelContext), type = "radio",
value = itemValue, **attributes))
return True
def generateHtmlContextValueRadioStatic(self, context, layout, value):
modelContext = self.getModelContext(context)
realNode = self.getRealNode(context, modelContext)
itemValue = realNode.content
if itemValue == value:
class_ = "xforms-value-radio-checked"
else:
class_ = "xforms-value-radio-unchecked"
layout.append(html.span(class_ = class_))
return True
elements.registerElement(namespaces.xforms.uri, "alert", Alert)
elements.registerElement(namespaces.xforms.uri, "bind", Bind)
elements.registerElement(namespaces.xforms.uri, "choices", Choices)
elements.registerElement(namespaces.xforms.uri, "group", Group)
elements.registerElement(namespaces.xforms.uri, "help", Help)
elements.registerElement(namespaces.xforms.uri, "hint", Hint)
elements.registerElement(namespaces.xforms.uri, "input", Input)
elements.registerElement(namespaces.xforms.uri, "instance", Instance)
elements.registerElement(namespaces.xforms.uri, "item", Item)
elements.registerElement(namespaces.xforms.uri, "label", Label)
elements.registerElement(namespaces.xforms.uri, "model", Model)
elements.registerElement(namespaces.xforms.uri, "output", Output)
elements.registerElement(namespaces.xforms.uri, "range", Range)
elements.registerElement(namespaces.xforms.uri, "repeat", Repeat)
elements.registerElement(namespaces.xforms.uri, "secret", Secret)
elements.registerElement(namespaces.xforms.uri, "select", Select)
elements.registerElement(namespaces.xforms.uri, "select1", Select1)
elements.registerElement(namespaces.xforms.uri, "submission", Submission)
elements.registerElement(namespaces.xforms.uri, "submit", Submit)
elements.registerElement(namespaces.xforms.uri, "textarea", TextArea)
elements.registerElement(namespaces.xforms.uri, "trigger", Trigger)
elements.registerElement(namespaces.xforms.uri, "upload", Upload)
elements.registerElement(namespaces.xforms.uri, "value", Value)