Author: apatel
Date: Wed Jun 25 21:23:57 2008 New Revision: 671723 URL: http://svn.apache.org/viewvc?rev=671723&view=rev Log: Adding Autocompleter options to form widget dropdown. More improvements to come. Modified: ofbiz/trunk/framework/example/widget/example/ExampleAjaxScreens.xml ofbiz/trunk/framework/example/widget/example/ExampleForms.xml ofbiz/trunk/framework/images/webapp/images/selectall.js ofbiz/trunk/framework/widget/dtd/widget-form.xsd ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java Modified: ofbiz/trunk/framework/example/widget/example/ExampleAjaxScreens.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/widget/example/ExampleAjaxScreens.xml?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/example/widget/example/ExampleAjaxScreens.xml (original) +++ ofbiz/trunk/framework/example/widget/example/ExampleAjaxScreens.xml Wed Jun 25 21:23:57 2008 @@ -24,6 +24,7 @@ <screen name="AjaxExample"> <section> <actions> + <set field="layoutSettings.styleSheets[+0]" value="/images/prototypejs/scriptaculouscontrols.css" global="true"/> <set field="headerItem" value="AjaxExample"/> <set field="titleProperty" value="PageTitleFindExample"/> <set field="exampleCtx" from-field="parameters"/> Modified: ofbiz/trunk/framework/example/widget/example/ExampleForms.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/widget/example/ExampleForms.xml?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/example/widget/example/ExampleForms.xml (original) +++ ofbiz/trunk/framework/example/widget/example/ExampleForms.xml Wed Jun 25 21:23:57 2008 @@ -125,6 +125,23 @@ have these settings. --> <form name="EditExampleBackgroundSubmit" type="single" extends="EditExample" target="updateExampleAjax"> <alt-target use-when="example==null" target="createExampleAjax"/> + <field name="exampleTypeId" title="${uiLabelMap.CommonType}" id-name="exampleTypeId"> + <drop-down allow-empty="false"> + <auto-complete/> + <entity-options entity-name="ExampleType" description="${description}"> + <entity-order-by field-name="description"/> + </entity-options> + </drop-down> + </field> + <field name="statusId" use-when="example==null" title="${uiLabelMap.CommonStatus}" id-name="statusId"> + <drop-down allow-empty="false"> + <auto-complete/> + <entity-options entity-name="StatusItem" description="${description}"> + <entity-constraint name="statusTypeId" value="EXAMPLE_STATUS"/> + <entity-order-by field-name="sequenceId"/> + </entity-options> + </drop-down> + </field> <on-event-update-area event-type="submit" area-id="ListExamplesAjax" area-target="ListExampleFormOnly"/> </form> Modified: ofbiz/trunk/framework/images/webapp/images/selectall.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/selectall.js?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/selectall.js (original) +++ ofbiz/trunk/framework/images/webapp/images/selectall.js Wed Jun 25 21:23:57 2008 @@ -323,6 +323,29 @@ } } +/** Enable auto-completion for dorp-down elements. + * @param areaId The id of the drop-down + * @param data Choices for Autocompleter.Local + * @param options +*/ + +function ajaxAutoCompleteDropDown(element, data, options) { + var key = []; + var description = []; + for (var i=0; i < data.length; i++) { + currData = data[i]; + key[i] = currData[0]; + description[i] = currData[1]; + } + var update = element + "_autoCompleterOptions"; + $(element).insert({after: '<div class="autocomplete"' + 'id=' + update + '></div>'}); + new Autocompleter.Local($(element), update, description, {autoSelect: options.autoSelect, frequency: options.frequency, minChars: options.minChars, choices: options.choices, partialSearch: options.partialSearch, partialChars: options.partialChars, ignoreCase: options.ignoreCase, fullSearch: options.fullSearch, afterUpdateElement: setKeyAsParameter}); + + function setKeyAsParameter() { + $(element).value = key[description.indexOf($F(element))]; + } +} + /** Toggle area visibility on/off. * @param link The <a> element calling this function * @param areaId The id of the HTML container to toggle Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original) +++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Wed Jun 25 21:23:57 2008 @@ -612,6 +612,7 @@ <xs:element name="drop-down" substitutionGroup="AllFields"> <xs:complexType> <xs:sequence> + <xs:element ref="auto-complete" minOccurs="0" maxOccurs="1"/> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="entity-options"/> <xs:element ref="list-options"/> @@ -623,15 +624,6 @@ </xs:complexType> </xs:element> <xs:attributeGroup name="attlist.drop-down"> - <xs:attribute name="type" default="traditional"> - <xs:simpleType> - <xs:restriction base="xs:token"> - <xs:enumeration value="traditional"/> - <xs:enumeration value="auto-complete-server"/> - <!-- <xs:enumeration value="auto-complete-client"/> something to consider for the future --> - </xs:restriction> - </xs:simpleType> - </xs:attribute> <xs:attribute name="allow-empty" default="false"> <xs:simpleType> <xs:restriction base="xs:token"> @@ -1008,6 +1000,49 @@ </xs:attributeGroup> <!-- ================== FIELD SUB-ELEMENTS ==================== --> + <xs:element name="auto-complete"> + <xs:complexType> + <xs:attributeGroup ref="attlist.auto-complete"/> + </xs:complexType> + </xs:element> + <xs:attributeGroup name="attlist.auto-complete"> + <xs:attribute name="auto-select" default="false"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true"/> + <xs:enumeration value="false"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute type="xs:integer" name="frequency" default="0.4"/> + <xs:attribute type="xs:positiveInteger" name="min-chars" default="1"/> + <xs:attribute type="xs:positiveInteger" name="choices" default="10"/> + <xs:attribute name="partial-search" default="true"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true"/> + <xs:enumeration value="false"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute type="xs:positiveInteger" name="partial-chars" default="2"/> + <xs:attribute name="ignore-case" default="true"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true"/> + <xs:enumeration value="false"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="full-search" default="false"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true"/> + <xs:enumeration value="false"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> <xs:element name="entity-constraint"> <xs:complexType> <xs:attributeGroup ref="attlist.entity-constraint"/> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java (original) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java Wed Jun 25 21:23:57 2008 @@ -2197,6 +2197,92 @@ this.useWhen = new FlexibleStringExpander(string); } } + + public static class AutoComplete { + protected String autoSelect; + protected String frequency; + protected String minChars; + protected String choices; + protected String partialSearch; + protected String partialChars; + protected String ignoreCase; + protected String fullSearch; + + public AutoComplete(Element element) { + this.autoSelect = element.getAttribute("auto-select"); + this.frequency = element.getAttribute("frequency"); + this.minChars = element.getAttribute("min-chars"); + this.choices = element.getAttribute("choices"); + this.partialSearch = element.getAttribute("partial-search"); + this.partialChars = element.getAttribute("partial-chars"); + this.ignoreCase = element.getAttribute("ignore-case"); + this.fullSearch = element.getAttribute("full-search"); + } + + public String getAutoSelect() { + return this.autoSelect; + } + + public String getFrequency() { + return this.frequency; + } + + public String getMinChars() { + return this.minChars; + } + + public String getChoices() { + return this.choices; + } + + public String getPartialSearch() { + return this.partialSearch; + } + + public String getPartialChars() { + return this.partialChars; + } + + public String getIgnoreCase() { + return this.ignoreCase; + } + + public String getFullSearch() { + return this.fullSearch; + } + + public void setAutoSelect(String string) { + this.autoSelect = string; + } + + public void setFrequency(String string) { + this.frequency = string; + } + + public void setMinChars(String string) { + this.minChars = string; + } + + public void setChoices(String string) { + this.choices = string; + } + + public void setPartialSearch(String string) { + this.partialSearch = string; + } + + public void setPartialChars(String string) { + this.partialChars = string; + } + + public void setIgnoreCase(String string) { + this.ignoreCase = string; + } + + public void setFullSearch(String string) { + this.fullSearch = string; + } + } public static class TextField extends FieldInfo { protected int size = 25; @@ -2575,6 +2661,7 @@ protected FlexibleStringExpander currentDescription; protected SubHyperlink subHyperlink; protected int otherFieldSize = 0; + protected AutoComplete autoComplete; protected DropDownField() { super(); @@ -2615,6 +2702,11 @@ if (subHyperlinkElement != null) { this.subHyperlink = new SubHyperlink(subHyperlinkElement); } + + Element autoCompleteElement = UtilXml.firstChildElement(element, "auto-complete"); + if (autoCompleteElement != null) { + this.autoComplete = new AutoComplete(autoCompleteElement); + } } public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) throws IOException { @@ -2663,6 +2755,14 @@ this.subHyperlink = newSubHyperlink; } + public AutoComplete getAutoComplete() { + return this.autoComplete; + } + + public void setAutoComplete(AutoComplete newAutoComplete) { + this.autoComplete = newAutoComplete; + } + public int getOtherFieldSize() { return this.otherFieldSize; } Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java?rev=671723&r1=671722&r2=671723&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java (original) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java Wed Jun 25 21:23:57 2008 @@ -582,11 +582,18 @@ public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException { ModelFormField modelFormField = dropDownField.getModelFormField(); ModelForm modelForm = modelFormField.getModelForm(); + ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete(); + boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled; + List allOptionValues = dropDownField.getAllOptionValues(context, modelForm.getDelegator(context)); String event = modelFormField.getEvent(); String action = modelFormField.getAction(context); - writer.append("<select"); + if (ajaxEnabled) { + writer.append("<input type=\"text\""); + } else { + writer.append("<select"); + } appendClassNames(writer, context, modelFormField); @@ -600,129 +607,155 @@ writer.append(idName); writer.append('"'); } - - if (dropDownField.isAllowMultiple()) { - writer.append(" multiple=\"multiple\""); - } - int otherFieldSize = dropDownField.getOtherFieldSize(); - String otherFieldName = dropDownField.getParameterNameOther(context); - if (otherFieldSize > 0) { - //writer.append(" onchange=\"alert('ONCHANGE, process_choice:' + process_choice)\""); - //writer.append(" onchange='test_js()' "); - writer.append(" onchange=\"process_choice(this,document."); - writer.append(modelForm.getName()); - writer.append("."); - writer.append(otherFieldName); - writer.append(")\" "); - } - - - if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) { - writer.append(" "); - writer.append(event); - writer.append("=\""); - writer.append(action); - writer.append('"'); - } - - writer.append(" size=\"" + dropDownField.getSize() + "\">"); + if (ajaxEnabled) { + writer.append("/>"); + + appendWhitespace(writer); + writer.append("<script language=\"JavaScript\" type=\"text/javascript\">"); + appendWhitespace(writer); + writer.append("var data = ["); + Iterator optionValueIter = allOptionValues.iterator(); + int count = 0; + while (optionValueIter.hasNext()) { + count++; + ModelFormField.OptionValue optionValue = (ModelFormField.OptionValue) optionValueIter.next(); + writer.append("['"+optionValue.getKey()+"',"); + writer.append(" '"+optionValue.getDescription()+"']"); + if (count != allOptionValues.size()) { + writer.append(", "); + } + } + writer.append("];"); + appendWhitespace(writer); + writer.append("ajaxAutoCompleteDropDown('"+idName+"', data, {autoSelect: "+autoComplete.getAutoSelect()+", frequency: "+autoComplete.getFrequency()+", minChars: "+autoComplete.getMinChars()+", choices: "+autoComplete.getChoices()+", partialSearch: "+autoComplete.getPartialSearch()+", partialChars: "+autoComplete.getPartialChars()+", ignoreCase: "+autoComplete.getIgnoreCase()+", fullSearch: "+autoComplete.getFullSearch()+"});"); + appendWhitespace(writer); + writer.append("</script>"); + } else { + if (dropDownField.isAllowMultiple()) { + writer.append(" multiple=\"multiple\""); + } + + int otherFieldSize = dropDownField.getOtherFieldSize(); + String otherFieldName = dropDownField.getParameterNameOther(context); + if (otherFieldSize > 0) { + //writer.append(" onchange=\"alert('ONCHANGE, process_choice:' + process_choice)\""); + //writer.append(" onchange='test_js()' "); + writer.append(" onchange=\"process_choice(this,document."); + writer.append(modelForm.getName()); + writer.append("."); + writer.append(otherFieldName); + writer.append(")\" "); + } - String currentValue = modelFormField.getEntry(context); - List allOptionValues = dropDownField.getAllOptionValues(context, modelForm.getDelegator(context)); - // if the current value should go first, stick it in - if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) { - writer.append("<option"); - writer.append(" selected=\"selected\""); - writer.append(" value=\""); - writer.append(currentValue); - writer.append("\">"); - String explicitDescription = dropDownField.getCurrentDescription(context); - if (UtilValidate.isNotEmpty(explicitDescription)) { - writer.append(explicitDescription); - } else { - writer.append(ModelFormField.FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues)); + if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) { + writer.append(" "); + writer.append(event); + writer.append("=\""); + writer.append(action); + writer.append('"'); } - writer.append("</option>"); - // add a "separator" option - writer.append("<option value=\""); - writer.append(currentValue); - writer.append("\">---</option>"); - } + writer.append(" size=\"" + dropDownField.getSize() + "\">"); - // if allow empty is true, add an empty option - if (dropDownField.isAllowEmpty()) { - writer.append("<option value=\"\"> </option>"); - } + String currentValue = modelFormField.getEntry(context); - // list out all options according to the option list - Iterator optionValueIter = allOptionValues.iterator(); - while (optionValueIter.hasNext()) { - ModelFormField.OptionValue optionValue = (ModelFormField.OptionValue) optionValueIter.next(); - String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context); - writer.append("<option"); - // if current value should be selected in the list, select it - if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) { - writer.append(" selected=\"selected\""); - } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) { + // if the current value should go first, stick it in + if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) { + writer.append("<option"); writer.append(" selected=\"selected\""); + writer.append(" value=\""); + writer.append(currentValue); + writer.append("\">"); + String explicitDescription = dropDownField.getCurrentDescription(context); + if (UtilValidate.isNotEmpty(explicitDescription)) { + writer.append(explicitDescription); + } else { + writer.append(ModelFormField.FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues)); + } + writer.append("</option>"); + + // add a "separator" option + writer.append("<option value=\""); + writer.append(currentValue); + writer.append("\">---</option>"); + } + + // if allow empty is true, add an empty option + if (dropDownField.isAllowEmpty()) { + writer.append("<option value=\"\"> </option>"); + } + + // list out all options according to the option list + Iterator optionValueIter = allOptionValues.iterator(); + while (optionValueIter.hasNext()) { + ModelFormField.OptionValue optionValue = (ModelFormField.OptionValue) optionValueIter.next(); + String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context); + writer.append("<option"); + // if current value should be selected in the list, select it + if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) { + writer.append(" selected=\"selected\""); + } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) { + writer.append(" selected=\"selected\""); + } + writer.append(" value=\""); + writer.append(optionValue.getKey()); + writer.append("\">"); + writer.append(optionValue.getDescription()); + writer.append("</option>"); } - writer.append(" value=\""); - writer.append(optionValue.getKey()); - writer.append("\">"); - writer.append(optionValue.getDescription()); - writer.append("</option>"); - } - writer.append("</select>"); + writer.append("</select>"); + - // Adapted from work by Yucca Korpela - // http://www.cs.tut.fi/~jkorpela/forms/combo.html - if (otherFieldSize > 0) { - - String fieldName = modelFormField.getParameterName(context); - Map dataMap = modelFormField.getMap(context); - if (dataMap == null) { - dataMap = context; - } - Object otherValueObj = dataMap.get(otherFieldName); - String otherValue = (otherValueObj == null) ? "" : otherValueObj.toString(); + // Adapted from work by Yucca Korpela + // http://www.cs.tut.fi/~jkorpela/forms/combo.html + if (otherFieldSize > 0) { - writer.append("<noscript>"); - writer.append("<input type='text' name='"); - writer.append(otherFieldName); - writer.append("'/> "); - writer.append("</noscript>"); - writer.append("\n<script type='text/javascript' language='JavaScript'><!--"); - writer.append("\ndisa = ' disabled';"); - writer.append("\nif(other_choice(document."); - writer.append(modelForm.getName()); - writer.append("."); - writer.append(fieldName); - writer.append(")) disa = '';"); - writer.append("\ndocument.write(\"<input type="); - writer.append("'text' name='"); - writer.append(otherFieldName); - writer.append("' value='"); - writer.append(otherValue); - writer.append("' size='"); - writer.append(Integer.toString(otherFieldSize)); - writer.append("' "); - writer.append("\" +disa+ \" onfocus='check_choice(document."); - writer.append(modelForm.getName()); - writer.append("."); - writer.append(fieldName); - writer.append(")'/>\");"); - writer.append("\nif(disa && document.styleSheets)"); - writer.append(" document."); - writer.append(modelForm.getName()); - writer.append("."); - writer.append(otherFieldName); - writer.append(".style.visibility = 'hidden';"); - writer.append("\n//--></script>"); + String fieldName = modelFormField.getParameterName(context); + Map dataMap = modelFormField.getMap(context); + if (dataMap == null) { + dataMap = context; + } + Object otherValueObj = dataMap.get(otherFieldName); + String otherValue = (otherValueObj == null) ? "" : otherValueObj.toString(); + + writer.append("<noscript>"); + writer.append("<input type='text' name='"); + writer.append(otherFieldName); + writer.append("'/> "); + writer.append("</noscript>"); + writer.append("\n<script type='text/javascript' language='JavaScript'><!--"); + writer.append("\ndisa = ' disabled';"); + writer.append("\nif(other_choice(document."); + writer.append(modelForm.getName()); + writer.append("."); + writer.append(fieldName); + writer.append(")) disa = '';"); + writer.append("\ndocument.write(\"<input type="); + writer.append("'text' name='"); + writer.append(otherFieldName); + writer.append("' value='"); + writer.append(otherValue); + writer.append("' size='"); + writer.append(Integer.toString(otherFieldSize)); + writer.append("' "); + writer.append("\" +disa+ \" onfocus='check_choice(document."); + writer.append(modelForm.getName()); + writer.append("."); + writer.append(fieldName); + writer.append(")'/>\");"); + writer.append("\nif(disa && document.styleSheets)"); + writer.append(" document."); + writer.append(modelForm.getName()); + writer.append("."); + writer.append(otherFieldName); + writer.append(".style.visibility = 'hidden';"); + writer.append("\n//--></script>"); + } } + this.makeHyperlinkString(writer, dropDownField.getSubHyperlink(), context); this.appendTooltip(writer, context, modelFormField); |
Free forum by Nabble | Edit this page |