diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index 0e7ad90457..f16dcd5d18 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -469,11 +469,8 @@ public final class FormsService ? ((Document)n).getDocumentElement() : n).getNodeName() + " to " + (output instanceof StringWriter - ? "string" - : output)); - final StringWriter sw = new StringWriter(); - t.transform(new DOMSource(n), new StreamResult(sw)); - LOGGER.debug(sw.toString()); + ? "string" + : output)); } t.transform(new DOMSource(n), new StreamResult(output)); } @@ -486,7 +483,7 @@ public final class FormsService /** utility function for serializing a node */ public void writeXML(final Node n, final File output) - throws IOException + throws IOException { this.writeXML(n, new FileWriter(output)); } diff --git a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java index 538e83ced5..a5cb843c36 100644 --- a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java +++ b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java @@ -468,9 +468,9 @@ public class SchemaFormBuilder * @throws org.chiba.tools.schemabuilder.FormBuilderException * If an error occurs building the XForm. */ - public Document buildForm(final Document instanceDocument, - final Document schemaDocument, - String rootElementName) + public Document buildXForm(final Document instanceDocument, + final Document schemaDocument, + String rootElementName) throws FormBuilderException { final XSModel schema = this.loadSchema(schemaDocument); @@ -561,6 +561,13 @@ public class SchemaFormBuilder XMLSCHEMA_INSTANCE_NS_PREFIX, XMLSCHEMA_INSTANCE_NS); instanceElement.appendChild(importedInstanceRootElement); + + final Element prototypeInstanceElement = + xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "instance"); + modelSection.appendChild(prototypeInstanceElement); + this.setXFormsId(prototypeInstanceElement, "instance_prototype"); + prototypeInstanceElement.appendChild(defaultInstanceRootElement); } Element formContentWrapper = this.wrapper.createGroupContentWrapper(formSection); @@ -611,7 +618,7 @@ public class SchemaFormBuilder this.createTriggersForRepeats(xForm); final Comment comment = - xForm.createComment("This XForm was automatically generated by " + this.getClass().getName() + + xForm.createComment("This XForm was generated by " + this.getClass().getName() + " on " + (new Date()) + " from the '" + rootElementName + "' element of the '" + this.targetNamespace + "' XML Schema."); xForm.getDocumentElement().insertBefore(comment, @@ -639,6 +646,12 @@ public class SchemaFormBuilder DEFAULT_SELECTONE_UI_CONTROL_LONG_PROP); } + public void removePrototypeNodes(final Element instanceDocumentElement) + { + + } + + /** * Returns the most-specific built-in base type for the provided type. */ @@ -1594,27 +1607,41 @@ public class SchemaFormBuilder relative = true; } - if (!relative) //create the bind in case it is a repeat + if (!relative) { if (LOGGER.isDebugEnabled()) + { LOGGER.debug("addElement: bind is not relative for " + elementDecl.getName()); + } } else { + //create the bind in case it is a repeat if (LOGGER.isDebugEnabled()) + { LOGGER.debug(">>>Adding empty bind for " + typeName); + } // create the element and add it to the model. - Element bindElement = + final Element bindElement = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "bind"); - String bindId = this.setXFormsId(bindElement); + final String bindId = this.setXFormsId(bindElement); bindElement.setAttributeNS(SchemaFormBuilder.XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "nodeset", pathToRoot); modelSection.appendChild(bindElement); + if (typeName != null) + { + this.startBindElement(bindElement, + schema, + controlType, + null, + pathToRoot, + this.getOccurance(elementDecl)); + } } //addComplexType(xForm,modelSection, formSection,(ComplexType)controlType,elementDecl,pathToRoot, relative); @@ -1813,28 +1840,38 @@ public class SchemaFormBuilder return found; } - private boolean doesAttributeComeFromExtension(XSAttributeUse attr, XSComplexTypeDefinition controlType) + private boolean doesAttributeComeFromExtension(XSAttributeUse attr, + XSComplexTypeDefinition controlType) { if (LOGGER.isDebugEnabled()) + { LOGGER.debug("doesAttributeComeFromExtension for " + attr.getAttrDeclaration().getName() + " and controlType=" + controlType.getName()); - boolean comesFromExtension = false; - if (controlType.getDerivationMethod() == XSConstants.DERIVATION_EXTENSION) { - XSTypeDefinition baseType = controlType.getBaseType(); - if (baseType.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) { - XSComplexTypeDefinition complexType = (XSComplexTypeDefinition) baseType; - if (this.isAttributeDeclaredIn(attr, complexType, true)) { - if (LOGGER.isDebugEnabled()) - LOGGER.debug("doesAttributeComeFromExtension: yes"); - comesFromExtension = true; - } else { //recursive call - if (LOGGER.isDebugEnabled()) - LOGGER.debug("doesAttributeComeFromExtension: recursive call on previous level"); - comesFromExtension = this.doesAttributeComeFromExtension(attr, complexType); - } - } } - return comesFromExtension; + + if (controlType.getDerivationMethod() != XSConstants.DERIVATION_EXTENSION) + { + return false; + } + + final XSTypeDefinition baseType = controlType.getBaseType(); + if (baseType.getTypeCategory() != XSTypeDefinition.COMPLEX_TYPE) + { + return false; + } + + final XSComplexTypeDefinition complexType = (XSComplexTypeDefinition) baseType; + if (this.isAttributeDeclaredIn(attr, complexType, true)) + { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("doesAttributeComeFromExtension: yes"); + return true; + } + + //recursive call + if (LOGGER.isDebugEnabled()) + LOGGER.debug("doesAttributeComeFromExtension: recursive call on previous level"); + return this.doesAttributeComeFromExtension(attr, complexType); } /** @@ -1970,7 +2007,7 @@ public class SchemaFormBuilder else { //add it normally - final String elementName = getElementName(element, xForm); + final String elementName = this.getElementName(element, xForm); final String path = (pathToRoot.length() == 0 ? elementName @@ -1992,16 +2029,27 @@ public class SchemaFormBuilder element.getTypeDefinition(), path); + LOGGER.debug("adding " + (this.getOccurance(element).maximum == 1 + ? 1 + : this.getOccurance(element).minimum + 1) + + " default instance element for " + elementName); // update the default instance - if (this.getOccurance(element).minimum == 0) + if (this.getOccurance(element).maximum == 1) { defaultInstanceElement.appendChild(newDefaultInstanceElement.cloneNode(true)); } else { - for (int i = 0; i < this.getOccurance(element).minimum; i++) + for (int i = 0; i < this.getOccurance(element).minimum + 1; i++) { - defaultInstanceElement.appendChild(newDefaultInstanceElement.cloneNode(true)); + final Element e = (Element)newDefaultInstanceElement.cloneNode(true); + if (i == this.getOccurance(element).minimum) + { + e.setAttributeNS(SchemaFormBuilder.ALFRESCO_NS, + SchemaFormBuilder.ALFRESCO_NS_PREFIX + "prototype", + "true"); + } + defaultInstanceElement.appendChild(e); } } } @@ -2033,11 +2081,12 @@ public class SchemaFormBuilder return formSection; if (LOGGER.isDebugEnabled()) - LOGGER.debug("DEBUG: AddRepeatIfNecessary for multiple element for type " + + LOGGER.debug("AddRepeatIfNecessary for multiple element for type " + controlType.getName() + ", maxOccurs=" + o.maximum); final Element repeatSection = - xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "repeat"); + xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "repeat"); //bind instead of repeat //repeatSection.setAttributeNS(SchemaFormBuilder.XFORMS_NS,SchemaFormBuilder.XFORMS_NS_PREFIX + "nodeset",pathToRoot); @@ -2080,16 +2129,14 @@ public class SchemaFormBuilder formSection.appendChild(controlWrapper); //add a group inside the repeat? - // Element group = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, - //this.SchemaFormBuilder.XFORMS_NS_PREFIX + "group"); - //this.setXFormsId(group); - //repeatSection.appendChild(group); - //repeatSection = group; - return repeatSection; + final Element group = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "group"); + this.setXFormsId(group); + repeatSection.appendChild(group); + return group; } /** - * if "createBind", a bind is created, otherwise bindId is used */ private void addSimpleType(final Document xForm, final Element modelSection, @@ -2103,12 +2150,17 @@ public class SchemaFormBuilder { if (LOGGER.isDebugEnabled()) + { LOGGER.debug("addSimpleType for " + controlType.getName() + " (owningElementName=" + owningElementName + ")"); + } if (owner != null) + { LOGGER.debug("owner is " + owner.getClass() + ", name is " + owner.getName()); + } + // create the element and add it to the model. Element bindElement = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "bind"); @@ -2147,20 +2199,22 @@ public class SchemaFormBuilder contentWrapper = this.wrapper.createGroupContentWrapper(repeatSection); //if there is a repeat -> create another bind with "." -// Element bindElement2 = -// xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, -// SchemaFormBuilder.XFORMS_NS_PREFIX + "bind"); -// String bindId2 = this.setXFormsId(bindElement2); -// bindElement2.setAttributeNS(SchemaFormBuilder.XFORMS_NS, -// SchemaFormBuilder.XFORMS_NS_PREFIX + "nodeset", -// "."); -// bindElement.appendChild(bindElement2); -// -// bindElement = bindElement2; -// bindId = bindId2; + Element bindElement2 = + xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "bind"); + String bindId2 = this.setXFormsId(bindElement2); + bindElement2.setAttributeNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "nodeset", + "."); + bindElement.appendChild(bindElement2); + + bindElement = bindElement2; + bindId = bindId2; } - final String caption = owner != null ? createCaption(owner) : createCaption(owningElementName); + final String caption = (owner != null + ? this.createCaption(owner) + : this.createCaption(owningElementName)); final Element formControl = this.createFormControl(xForm, schema, caption, @@ -2174,10 +2228,10 @@ public class SchemaFormBuilder // if this is a repeatable then set ref to point to current element // not sure if this is a workaround or this is just the way XForms works... // - if (!repeatSection.equals(formSection)) - formControl.setAttributeNS(SchemaFormBuilder.XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "ref", - "."); +// if (!repeatSection.equals(formSection)) +// formControl.setAttributeNS(SchemaFormBuilder.XFORMS_NS, +// SchemaFormBuilder.XFORMS_NS_PREFIX + "ref", +// "."); Element hint = createHint(xForm, owner); if (hint != null) @@ -2995,14 +3049,15 @@ public class SchemaFormBuilder // static string (see bug #1172541 on sf.net) String nodeset = pathToRoot; - if (o.isRepeated() && o.minimum == 0) + if (o.isRepeated()) nodeset = pathToRoot + "[position() != last()]"; bindElement.setAttributeNS(SchemaFormBuilder.XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "nodeset", nodeset); - if (!"anyType".equals(controlType.getName())) + if (!"anyType".equals(controlType.getName()) && + controlType instanceof XSSimpleTypeDefinition) { String typeName = this.getXFormsTypeName(bindElement.getOwnerDocument(), schema, @@ -3014,11 +3069,11 @@ public class SchemaFormBuilder } final short constraintType = - (owner instanceof XSElementDeclaration + (owner != null && owner instanceof XSElementDeclaration ? ((XSElementDeclaration)owner).getConstraintType() - : (owner instanceof XSAttributeDeclaration + : (owner != null && owner instanceof XSAttributeDeclaration ? ((XSAttributeDeclaration)owner).getConstraintType() - : (owner instanceof XSAttributeUse + : (owner != null && owner instanceof XSAttributeUse ? ((XSAttributeUse)owner).getConstraintType() : XSConstants.VC_NONE))); @@ -3042,8 +3097,7 @@ public class SchemaFormBuilder bindElement.setAttributeNS(ALFRESCO_NS, ALFRESCO_NS_PREFIX + "minimum", String.valueOf(o.minimum)); - } - + } if (o.maximum > 1) { //if 1 or unbounded -> no constraint @@ -3051,7 +3105,6 @@ public class SchemaFormBuilder bindElement.setAttributeNS(ALFRESCO_NS, ALFRESCO_NS_PREFIX + "maximum", String.valueOf(o.maximum)); - } final String constraint = (minConstraint != null && maxConstraint != null diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java index d84dfcc09c..ca94279ab3 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java @@ -70,21 +70,22 @@ public class XFormsBean { private static final Log LOGGER = LogFactory.getLog(XFormsBean.class); - private Form tt; + private Form form; private FormProcessor.InstanceData instanceData = null; private ChibaBean chibaBean; + private SchemaFormBuilder schemaFormBuilder = null; private final LinkedList eventLog = new LinkedList(); /** @return the form */ public Form getForm() { - return this.tt; + return this.form; } /** @param tt the template type */ - public void setForm(final Form tt) + public void setForm(final Form form) { - this.tt = tt; + this.form = form; } /** @param instanceData the instance data being modified. */ @@ -100,26 +101,55 @@ public class XFormsBean public void init() throws XFormsException { - LOGGER.debug("initializing " + this + " with tt " + tt.getName()); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("initializing " + this + " with form " + this.form.getName()); + } this.chibaBean = new ChibaBean(); final FacesContext facesContext = FacesContext.getCurrentInstance(); final ExternalContext externalContext = facesContext.getExternalContext(); final HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); + XFormsBean.storeCookies(request.getCookies(), this.chibaBean); + final HttpSession session = (HttpSession)externalContext.getSession(true); final AVMBrowseBean browseBean = (AVMBrowseBean) session.getAttribute("AVMBrowseBean"); - LOGGER.debug("avm cwd is " + browseBean.getCurrentPath()); - - XFormsBean.storeCookies(request.getCookies(), this.chibaBean); + final String cwdAVMPath = browseBean.getCurrentPath(); + final String baseUrl = (request.getScheme() + "://" + + request.getServerName() + ':' + + request.getServerPort() + + request.getContextPath()); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("building xform for schema " + form.getName() + + " with baseUrl " + baseUrl + + " root element " + form.getSchemaRootElementName() + + " avm cwd " + cwdAVMPath); + } + this.schemaFormBuilder = + new SchemaFormBuilder("/ajax/invoke/XFormsBean.handleAction", + SchemaFormBuilder.SUBMIT_METHOD_POST, + new XHTMLWrapperElementsBuilder(), + baseUrl); + try { - final Document form = this.buildXForm(instanceData.getContent(), - tt, - browseBean.getCurrentPath(), - request); - this.chibaBean.setXMLContainer(form); + final Document schemaDocument = this.form.getSchema(); + this.rewriteInlineURIs(schemaDocument, cwdAVMPath); + final Document xformsDocument = + this.schemaFormBuilder.buildXForm(instanceData.getContent(), + schemaDocument, + this.form.getSchemaRootElementName()); + + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("generated xform: " + + FormsService.getInstance().writeXMLToString(xformsDocument)); + } + + this.chibaBean.setXMLContainer(xformsDocument); final EventTarget et = (EventTarget) this.chibaBean.getXMLContainer().getDocumentElement(); @@ -179,9 +209,8 @@ public class XFormsBean LOGGER.debug(this + ".getXForm()"); final FacesContext context = FacesContext.getCurrentInstance(); final ResponseWriter out = context.getResponseWriter(); - LOGGER.debug("building xform for " + this.tt.getName()); - final Node form = this.chibaBean.getXMLContainer(); - FormsService.getInstance().writeXML(form, out); + final Node xformsDocument = this.chibaBean.getXMLContainer(); + FormsService.getInstance().writeXML(xformsDocument, out); } /** @@ -269,6 +298,7 @@ public class XFormsBean context.getExternalContext().getRequest(); final FormsService formsService = FormsService.getInstance(); final Document result = formsService.parseXML(request.getInputStream()); + this.schemaFormBuilder.removePrototypeNodes(result.getDocumentElement()); this.instanceData.setContent(result); final ResponseWriter out = context.getResponseWriter(); @@ -432,48 +462,19 @@ public class XFormsBean } } - /** - * Generates the xforms based on the schema. - */ - private Document buildXForm(Document xmlContent, - final Form tt, - final String cwdAvmPath, - final HttpServletRequest request) - throws FormBuilderException, - IOException, - SAXException - { - final Document schemaDocument = tt.getSchema(); - this.rewriteInlineURIs(schemaDocument, cwdAvmPath); - final String baseUrl = (request.getScheme() + "://" + - request.getServerName() + ':' + - request.getServerPort() + - request.getContextPath()); - LOGGER.debug("using baseUrl " + baseUrl + " for schemaformbuilder"); - final SchemaFormBuilder builder = - new SchemaFormBuilder("/ajax/invoke/XFormsBean.handleAction", - SchemaFormBuilder.SUBMIT_METHOD_POST, - new XHTMLWrapperElementsBuilder(), - baseUrl); - LOGGER.debug("building xform for schema " + tt.getName()); - final Document result = builder.buildForm(xmlContent, - schemaDocument, - tt.getSchemaRootElementName()); - LOGGER.debug("generated xform: " + result); - // LOGGER.debug(ts.writeXMLToString(result)); - return result; - } - private Node getEventLog() { - final FormsService ts = FormsService.getInstance(); - final Document result = ts.newDocument(); + final FormsService formsService = FormsService.getInstance(); + final Document result = formsService.newDocument(); final Element eventsElement = result.createElement("events"); result.appendChild(eventsElement); for (XFormsEvent xfe : this.eventLog) { final String type = xfe.getType(); - LOGGER.debug("adding event " + type + " to the event log"); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("adding event " + type + " to the event log"); + } final Element target = (Element)xfe.getTarget(); final Element eventElement = result.createElement(type); @@ -487,8 +488,12 @@ public class XFormsBean for (Object name : properties) { final Object value = xfe.getContextInfo((String)name); - LOGGER.debug("adding property {" + name + - ":" + value + "} to event " + type); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("adding property {" + name + + ":" + value + "} to event " + type); + } + final Element propertyElement = result.createElement("property"); eventElement.appendChild(propertyElement); propertyElement.setAttribute("name", name.toString()); @@ -498,6 +503,12 @@ public class XFormsBean } } this.eventLog.clear(); + + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("generated event log:\n" + + formsService.writeXMLToString(result)); + } return result; } diff --git a/source/web/scripts/ajax/xforms.js b/source/web/scripts/ajax/xforms.js index 75d92a8a10..c0955f3f41 100644 --- a/source/web/scripts/ajax/xforms.js +++ b/source/web/scripts/ajax/xforms.js @@ -360,7 +360,9 @@ dojo.declare("alfresco.xforms.TextField", this.widget.setAttribute("id", this.id + "-widget"); this.widget.setAttribute("value", initial_value); if (this.xform.getType(this.xformsNode) == "string") + { this.widget.style.width = "100%"; + } this.domNode.appendChild(this.widget); if (this.isReadonly()) @@ -375,7 +377,10 @@ dojo.declare("alfresco.xforms.TextField", }, setValue: function(value) { - this.widget.setAttribute("value", value); + if (!this.widget) + this.setInitialValue(value); + else + this.widget.value = value; }, getValue: function() { @@ -1544,6 +1549,12 @@ dojo.declare("alfresco.xforms.XForm", { dojo.debug("loading " + xformsNode.childNodes[i].nodeName + " into " + parentWidget.id); + if (xformsNode.childNodes[i].getAttribute(ALFRESCO_NS_PREFIX + ":prototype") == "true") + { + dojo.debug(xformsNode.childNodes[i].getAttribute("id") + + " is a prototype, ignoring"); + continue; + } var w = this.createWidget(xformsNode.childNodes[i]); if (w != null) { @@ -1657,7 +1668,7 @@ dojo.declare("alfresco.xforms.XForm", }, _handleEventLog: function(events) { - var prototypeClones = []; + var prototypeClone = null; for (var i = 0; i < events.childNodes.length; i++) { if (events.childNodes[i].nodeType != dojo.dom.ELEMENT_NODE) @@ -1684,6 +1695,7 @@ dojo.declare("alfresco.xforms.XForm", } case "chiba-state-changed": { + dojo.debug("handleStateChanged(" + xfe.targetId + ")"); xfe.getTarget().setModified(true); xfe.getTarget().setValid(xfe.properties["valid"] == "true"); xfe.getTarget().setRequired(xfe.properties["required"] == "true"); @@ -1691,6 +1703,7 @@ dojo.declare("alfresco.xforms.XForm", xfe.getTarget().setEnabled(xfe.properties["enabled"] == "true"); if ("value" in xfe.properties) { + dojo.debug("setting " + xfe.getTarget().id + " = " + xfe.properties["value"]); xfe.getTarget().setValue(xfe.properties["value"]); } break; @@ -1702,27 +1715,26 @@ dojo.declare("alfresco.xforms.XForm", dojo.debug("handlePrototypeCloned(" + xfe.targetId + ", " + originalId + ", " + prototypeId + ")"); - - var prototypeNode = _findElementById(this.xformsNode, originalId); - var binding = this.getBinding(prototypeNode); - var prototypeToClone = null; - for (var w in binding.widgets) + var clone = null; + var prototypeNode = _findElementById(this.xformsNode, prototypeId); + if (prototypeNode) { - if (binding.widgets[w] instanceof alfresco.xforms.Repeat) - { - var chibaData = _getElementsByTagNameNS(binding.widgets[w].xformsNode, - CHIBA_NS, - CHIBA_NS_PREFIX, "data"); - if (chibaData.length == 0) - continue; - prototypeToClone = dojo.dom.firstElement(chibaData[chibaData.length - 1]); - } + dojo.debug("cloning prototype " + prototypeNode.getAttribute("id")); + clone = prototypeNode.cloneNode(true); + } + else + { + dojo.debug("cloning prototype " + originalId); + var prototypeNode = _findElementById(this.xformsNode, originalId); + clone = prototypeNode.cloneNode(true); + var clone = prototypeNode.ownerDocument.createElement("xforms:group"); + clone.setAttribute("xforms:appearance", "repeated"); + for (var j = 0; j < prototypeNode.childNodes.length; j++) + { + clone.appendChild(prototypeNode.childNodes[j].cloneNode(true)); + } + clone.setAttribute("id", prototypeId); } - if (!prototypeToClone) - throw new Error("unable to find prototype for " + originalId); - dojo.debug("cloning prototype " + prototypeToClone.getAttribute("id")); - var clone = prototypeToClone.cloneNode(true); - clone.setAttribute("id", prototypeId); // if (true || originalId == xfe.targetId) // var clone = xfe.getTarget().handlePrototypeCloned(prototypeId); // else @@ -1731,7 +1743,8 @@ dojo.declare("alfresco.xforms.XForm", // var clone = originalWidget.widget.handlePrototypeCloned(prototypeId); // } - prototypeClones.push(clone); + clone.parentClone = prototypeClone; + prototypeClone = clone; break; } case "chiba-id-generated": @@ -1739,31 +1752,37 @@ dojo.declare("alfresco.xforms.XForm", var originalId = xfe.properties["originalId"]; dojo.debug("handleIdGenerated(" + xfe.targetId + ", " + originalId + ")"); - var clone = prototypeClones[prototypeClones.length - 1]; - var node = _findElementById(clone, originalId); - if (node) - { - dojo.debug("applying id " + xfe.targetId + - " to " + node.nodeName + "(" + originalId + ")"); - node.setAttribute("id", xfe.targetId); - } - else + var node = _findElementById(prototypeClone, originalId); + if (!node) throw new Error("unable to find " + originalId + " in clone " + dojo.dom.innerXML(clone)); + dojo.debug("applying id " + xfe.targetId + + " to " + node.nodeName + "(" + originalId + ")"); + node.setAttribute("id", xfe.targetId); + if (prototypeClone.parentClone) + { + var e = _findElementById(prototypeClone.parentClone, originalId); + if (e) + { + e.setAttribute(ALFRESCO_NS_PREFIX + ":prototype", "true"); + } + } break; } case "chiba-item-inserted": { var position = Number(xfe.properties["position"]) - 1; var originalId = xfe.properties["originalId"]; - var clone = prototypeClones.pop(); - if (prototypeClones.length == 0) - xfe.getTarget().handleItemInserted(clone, position); + var clone = prototypeClone; + prototypeClone = clone.parentClone; + if (prototypeClone) + { + var parentRepeat = _findElementById(prototypeClone, xfe.targetId); + parentRepeat.appendChild(clone); + } else { - var parentClone = prototypeClones[prototypeClones.length - 1]; - var parentRepeat = _findElementById(parentClone, xfe.targetId); - parentRepeat.appendChild(clone); + xfe.getTarget().handleItemInserted(clone, position); } break; } @@ -1830,9 +1849,9 @@ dojo.declare("alfresco.xforms.XForm", function _findElementById(node, id) { - dojo.debug("looking for " + id + - " in " + node.nodeName + - "(" + node.getAttribute("id") + ")"); +// dojo.debug("looking for " + id + +// " in " + (node ? node.nodeName : null) + +// "(" + (node ? node.getAttribute("id") : null) + ")"); if (node.getAttribute("id") == id) return node; for (var i = 0; i < node.childNodes.length; i++) @@ -2074,6 +2093,10 @@ setValue: function(v) setReadonly: function(r) { this.readonly = r; + if (this.selectButton) + this.selectButton.disabled = this.readonly; + else if (this.readonly) + this._showSelectedValue(); }, render: function() { @@ -2094,17 +2117,17 @@ _showSelectedValue: function() this.node.appendChild(d.createTextNode(this.value == null ? "" : this.value)); - var selectButton = d.createElement("input"); - this.node.appendChild(selectButton); - selectButton.filePickerWidget = this; - selectButton.type = "button"; - selectButton.value = this.value == null ? "Select" : "Change"; - selectButton.enabled = this.readonly; - selectButton.style.marginLeft = "10px"; - selectButton.style.position = "absolute"; - selectButton.style.right = "10px"; - selectButton.style.top = (.5 * this.node.offsetHeight) - (.5 * selectButton.offsetHeight) + "px"; - dojo.event.connect(selectButton, + this.selectButton = d.createElement("input"); + this.node.appendChild(this.selectButton); + this.selectButton.filePickerWidget = this; + this.selectButton.type = "button"; + this.selectButton.value = this.value == null ? "Select" : "Change"; + this.selectButton.disabled = this.readonly; + this.selectButton.style.marginLeft = "10px"; + this.selectButton.style.position = "absolute"; + this.selectButton.style.right = "10px"; + this.selectButton.style.top = (.5 * this.node.offsetHeight) - (.5 * this.selectButton.offsetHeight) + "px"; + dojo.event.connect(this.selectButton, "onclick", function(event) {