private void handleItemCompact( ContentHandler contentHandler, String optionQName, XFormsValueControl xformsControl, boolean isMultiple, Item item) throws SAXException { final String itemClasses = getItemClasses(item, null); final AttributesImpl optionAttributes = getAttributes(XMLUtils.EMPTY_ATTRIBUTES, itemClasses, null); // Add item attributes to option addItemAttributes(item, optionAttributes); optionAttributes.addAttribute( "", "value", "value", ContentHandlerHelper.CDATA, item.getExternalValue(pipelineContext)); // Figure out whether what items are selected boolean isSelected = isSelected(pipelineContext, handlerContext, xformsControl, isMultiple, item); if (isSelected) optionAttributes.addAttribute( "", "selected", "selected", ContentHandlerHelper.CDATA, "selected"); // xhtml:option contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "option", optionQName, optionAttributes); final String label = item.getLabel(); if (label != null) contentHandler.characters(label.toCharArray(), 0, label.length()); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "option", optionQName); }
public static void handleItemFull( PipelineContext pipelineContext, HandlerContext handlerContext, ContentHandler contentHandler, AttributesImpl reusableAttributes, Attributes attributes, String xhtmlPrefix, String spanQName, XFormsContainingDocument containingDocument, XFormsValueControl xformsControl, String effectiveId, String itemEffectiveId, boolean isMultiple, String type, Item item, boolean isFirst) throws SAXException { // Whether this is selected boolean isSelected = isSelected(pipelineContext, handlerContext, xformsControl, isMultiple, item); // xhtml:span enclosing input and label final String itemClasses = getItemClasses(item, isSelected ? "xforms-selected" : "xforms-deselected"); final AttributesImpl spanAttributes = getAttributes(reusableAttributes, XMLUtils.EMPTY_ATTRIBUTES, itemClasses, null); // Add item attributes to span addItemAttributes(item, spanAttributes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, spanAttributes); { { // xhtml:input final String inputQName = XMLUtils.buildQName(xhtmlPrefix, "input"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "id", "id", ContentHandlerHelper.CDATA, itemEffectiveId); reusableAttributes.addAttribute("", "type", "type", ContentHandlerHelper.CDATA, type); // Get group name from selection control if possible, otherwise use effective id final String name = (!isMultiple && xformsControl instanceof XFormsSelect1Control) ? ((XFormsSelect1Control) xformsControl).getGroupName() : effectiveId; reusableAttributes.addAttribute("", "name", "name", ContentHandlerHelper.CDATA, name); reusableAttributes.addAttribute( "", "value", "value", ContentHandlerHelper.CDATA, item.getExternalValue(pipelineContext)); if (!handlerContext.isTemplate() && xformsControl != null) { if (isSelected) { reusableAttributes.addAttribute( "", "checked", "checked", ContentHandlerHelper.CDATA, "checked"); } if (isFirst) { // Handle accessibility attributes handleAccessibilityAttributes(attributes, reusableAttributes); } } handleDisabledAttribute(reusableAttributes, containingDocument, xformsControl); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName, reusableAttributes); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName); } // We don't output the label within <input></input>, because XHTML won't display it. final String label = item.getLabel(); if (label != null) { // allow null label to tell not to output the <label> element at all reusableAttributes.clear(); outputLabelFor( handlerContext, reusableAttributes, itemEffectiveId, itemEffectiveId, LHHAC.LABEL, "label", label, false, false); // TODO: may be HTML for full appearance } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); }
public void outputContent( String uri, String localname, Attributes attributes, String effectiveId, final XFormsValueControl xformsSelect1Control, Itemset itemset, final boolean isMultiple, final boolean isFull, boolean isBooleanInput) throws SAXException { final ContentHandler contentHandler = handlerContext.getController().getOutput(); final AttributesImpl containerAttributes = getContainerAttributes( uri, localname, attributes, effectiveId, xformsSelect1Control, !isFull); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); if (!isStaticReadonly(xformsSelect1Control)) { if (isFull) { // Full appearance outputFull( uri, localname, attributes, effectiveId, xformsSelect1Control, itemset, isMultiple, isBooleanInput); } else { if (isOpenSelection) { if (isAutocomplete) { // Create xhtml:span final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, containerAttributes); { { // Create xhtml:input final String inputQName = XMLUtils.buildQName(xhtmlPrefix, "input"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "type", "type", ContentHandlerHelper.CDATA, "text"); reusableAttributes.addAttribute( "", "name", "name", ContentHandlerHelper.CDATA, "xforms-select1-open-input-" + effectiveId); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-select1-open-input"); reusableAttributes.addAttribute( "", "autocomplete", "autocomplete", ContentHandlerHelper.CDATA, "off"); final String value = (xformsSelect1Control == null) ? null : xformsSelect1Control.getValue(pipelineContext); // NOTE: With open selection, we send all values to the client but not encrypt them // because the client matches on values reusableAttributes.addAttribute( "", "value", "value", ContentHandlerHelper.CDATA, (value == null) ? "" : value); handleDisabledAttribute( reusableAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName, reusableAttributes); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName); } { // Create xhtml:select final String selectQName = XMLUtils.buildQName(xhtmlPrefix, "select"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-select1-open-select"); if (isCompact) reusableAttributes.addAttribute( "", "multiple", "multiple", ContentHandlerHelper.CDATA, "multiple"); // Handle accessibility attributes handleAccessibilityAttributes(attributes, reusableAttributes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName, reusableAttributes); final String optionQName = XMLUtils.buildQName(xhtmlPrefix, "option"); handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, EMPTY_TOP_LEVEL_ITEM); if (itemset != null) { for (final Item item : itemset.toList()) { if (item.getValue() != null) handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, item); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); } else { // We do not support other appearances or regular open selection for now throw new ValidationException( "Open selection currently only supports the xxforms:autocomplete appearance.", new ExtendedLocationData( handlerContext.getLocationData(), "producing markup for xforms:" + localname + " control", (xformsSelect1Control != null) ? xformsSelect1Control.getControlElement() : null)); } } else if (isTree) { // xxforms:tree appearance // Create xhtml:div with tree info final String divQName = XMLUtils.buildQName(xhtmlPrefix, "div"); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, containerAttributes); if (itemset != null) { // can be null if the control is non-relevant outputJSONTreeInfo(xformsSelect1Control, itemset, isMultiple, contentHandler); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } else if (isMenu) { // xxforms:menu appearance // Create enclosing xhtml:div final String divQName = XMLUtils.buildQName(xhtmlPrefix, "div"); final String ulQName = XMLUtils.buildQName(xhtmlPrefix, "ul"); final String liQName = XMLUtils.buildQName(xhtmlPrefix, "li"); final String aQName = XMLUtils.buildQName(xhtmlPrefix, "a"); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, containerAttributes); if (itemset != null) { // can be null if the control is non-relevant // Create xhtml:div with initial menu entries { itemset.visit( contentHandler, new ItemsetListener() { private boolean groupJustStarted = false; public void startLevel(ContentHandler contentHandler, Item item) throws SAXException { final boolean isTopLevel = item == null; reusableAttributes.clear(); final String divClasses = isTopLevel ? "yuimenubar" : "yuimenu"; reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, divClasses); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "bd"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); reusableAttributes.clear(); // NOTE: We just decide to put item classes on <ul> final String classes = isTopLevel ? "first-of-type" : getItemClasses(item, "first-of-type"); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, classes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "ul", ulQName, reusableAttributes); groupJustStarted = true; } public void endLevel(ContentHandler contentHandler) throws SAXException { contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "ul", ulQName); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); groupJustStarted = false; } public void startItem(ContentHandler contentHandler, Item item, boolean first) throws SAXException { final String liClasses; { final StringBuilder sb = new StringBuilder(item.isTopLevel() ? "yuimenubaritem" : "yuimenuitem"); if (groupJustStarted) sb.append(" first-of-type"); liClasses = getItemClasses(item, sb.toString()); } reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, liClasses); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "li", liQName, reusableAttributes); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "href", "href", ContentHandlerHelper.CDATA, "#"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "a", aQName, reusableAttributes); final String text = item.getLabel(); contentHandler.characters(text.toCharArray(), 0, text.length()); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "a", aQName); groupJustStarted = false; } public void endItem(ContentHandler contentHandler) throws SAXException { contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "li", liQName); groupJustStarted = false; } }); } // Create xhtml:div with tree info reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-initially-hidden"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); if (itemset != null) { // can be null if the control is non-relevant outputJSONTreeInfo(xformsSelect1Control, itemset, isMultiple, contentHandler); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } else { // Create xhtml:select final String selectQName = XMLUtils.buildQName(xhtmlPrefix, "select"); containerAttributes.addAttribute( "", "name", "name", ContentHandlerHelper.CDATA, effectiveId); // necessary for noscript mode if (isCompact) containerAttributes.addAttribute( "", "multiple", "multiple", ContentHandlerHelper.CDATA, "multiple"); // Handle accessibility attributes handleAccessibilityAttributes(attributes, containerAttributes); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName, containerAttributes); { final String optionQName = XMLUtils.buildQName(xhtmlPrefix, "option"); final String optGroupQName = XMLUtils.buildQName(xhtmlPrefix, "optgroup"); if (itemset != null) { // Work in progress for in-bounds/out-of-bounds // if (!((XFormsSelect1Control) // xformsControl).isInBounds(items)) { // // Control is out of bounds so add first item with out // of bound value to handle this // handleItemCompact(contentHandler, optionQName, // xformsControl, isMultiple, // new // XFormsItemUtils.Item(XFormsProperties.isEncryptItemValues(containingDocument), // Collections.EMPTY_LIST, "", // xformsControl.getValue(pipelineContext), 1)); // } itemset.visit( contentHandler, new ItemsetListener() { private int optgroupCount = 0; public void startLevel(ContentHandler contentHandler, Item item) throws SAXException {} public void endLevel(ContentHandler contentHandler) throws SAXException { if (optgroupCount-- > 0) { // End xhtml:optgroup contentHandler.endElement( XMLConstants.XHTML_NAMESPACE_URI, "optgroup", optGroupQName); } } public void startItem(ContentHandler contentHandler, Item item, boolean first) throws SAXException { final String label = item.getLabel(); final String value = item.getValue(); if (value == null) { final String itemClasses = getItemClasses(item, null); final AttributesImpl optGroupAttributes = getAttributes(XMLUtils.EMPTY_ATTRIBUTES, itemClasses, null); if (label != null) optGroupAttributes.addAttribute( "", "label", "label", ContentHandlerHelper.CDATA, label); // Start xhtml:optgroup contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "optgroup", optGroupQName, optGroupAttributes); optgroupCount++; } else { handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, item); } } public void endItem(ContentHandler contentHandler) throws SAXException {} }); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName); } } } else { // Read-only mode final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, containerAttributes); if (!handlerContext.isTemplate()) { final String value = (xformsSelect1Control == null || xformsSelect1Control.getValue(pipelineContext) == null) ? "" : xformsSelect1Control.getValue(pipelineContext); final StringBuilder sb = new StringBuilder(); if (itemset != null) { int selectedFound = 0; for (final Item currentItem : itemset.toList()) { if (XFormsItemUtils.isSelected(isMultiple, value, currentItem.getValue())) { if (selectedFound > 0) sb.append(" - "); sb.append(currentItem.getLabel()); selectedFound++; } } } if (sb.length() > 0) { final String result = sb.toString(); contentHandler.characters(result.toCharArray(), 0, result.length()); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); } }