You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by jl...@apache.org on 2010/10/28 13:26:32 UTC

svn commit: r1028261 - in /ofbiz/branches/jquery/framework: common/webcommon/WEB-INF/actions/includes/ common/webcommon/includes/ images/webapp/images/ widget/templates/

Author: jleroux
Date: Thu Oct 28 11:26:32 2010
New Revision: 1028261

URL: http://svn.apache.org/viewvc?rev=1028261&view=rev
Log:
Implements the description in lookup which so far was missed in migration.

It works well in all browsers; though I had to add a String.trim() function because IE8 does not implement trim yet. BWT, it was the 1st time I used the integrated IE8 debugger and crossed an issue to have it to work :(.
Also
* In Chrome the description is not at right of the lookup but below. 
* When loading and the field has no value a small yellow colored square appears at right of the lookup (all browsers), should not be a bid deal to fix later...

Also adds a new feature which allows to set a dependent field using autocomplete in lookups (was only working with lookup, not with autocomplete). Convenient when, for instance, you want to allow you users to handle names instead of Ids but need to set an Id key in a hidden field. Demonstrated with Geo in example/control/FormWidgetExamples.
Note: for this new feature at some point I wondered if I should not introduce a class plugin. But finally decided to go my own way with prototypes (actually following jQuery spirit, javascript and prototype are powerful, just another way of thinking about classes)

Modified:
    ofbiz/branches/jquery/framework/common/webcommon/WEB-INF/actions/includes/FindAutocompleteOptions.groovy
    ofbiz/branches/jquery/framework/common/webcommon/includes/ajaxAutocompleteOptions.ftl
    ofbiz/branches/jquery/framework/images/webapp/images/fieldlookup.js
    ofbiz/branches/jquery/framework/images/webapp/images/getDependentDropdownValues.js
    ofbiz/branches/jquery/framework/images/webapp/images/selectall.js
    ofbiz/branches/jquery/framework/widget/templates/htmlFormMacroLibrary.ftl

Modified: ofbiz/branches/jquery/framework/common/webcommon/WEB-INF/actions/includes/FindAutocompleteOptions.groovy
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/common/webcommon/WEB-INF/actions/includes/FindAutocompleteOptions.groovy?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/common/webcommon/WEB-INF/actions/includes/FindAutocompleteOptions.groovy (original)
+++ ofbiz/branches/jquery/framework/common/webcommon/WEB-INF/actions/includes/FindAutocompleteOptions.groovy Thu Oct 28 11:26:32 2010
@@ -35,7 +35,12 @@ def displayFields = context.displayField
 
 def searchValueFieldName = parameters.term;
 def fieldValue = null;
-if (searchValueFieldName) fieldValue = searchValueFieldName;
+if (searchValueFieldName) {
+    fieldValue = searchValueFieldName; 
+} else if (parameters.searchValueFieldName) {
+    fieldValue = parameters.get(parameters.searchValueFieldName);
+    context.description = "true";
+}
 
 def searchType = context.searchType;
 def displayFieldsSet = null;
@@ -43,7 +48,11 @@ def displayFieldsSet = null;
 if (searchFields && fieldValue) {
     def searchFieldsList = StringUtil.toList(searchFields);
     displayFieldsSet = StringUtil.toSet(displayFields);
-    returnField = searchFieldsList[0]; //default to first element of searchFields
+    if (context.description && fieldValue instanceof java.lang.String) {
+        returnField = parameters.searchValueFieldName;
+    } else {
+        returnField = searchFieldsList[0]; //default to first element of searchFields
+    }
     displayFieldsSet.add(returnField); //add it to select fields, in case it is missing
     context.returnField = returnField;
     context.displayFieldsSet = displayFieldsSet;

Modified: ofbiz/branches/jquery/framework/common/webcommon/includes/ajaxAutocompleteOptions.ftl
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/common/webcommon/includes/ajaxAutocompleteOptions.ftl?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/common/webcommon/includes/ajaxAutocompleteOptions.ftl (original)
+++ ofbiz/branches/jquery/framework/common/webcommon/includes/ajaxAutocompleteOptions.ftl Thu Oct 28 11:26:32 2010
@@ -16,6 +16,22 @@ KIND, either express or implied.  See th
 specific language governing permissions and limitations
 under the License.
 -->
+<#if description?exists>
+    <#if autocompleteOptions?exists>
+        <#list autocompleteOptions as autocompleteOption>
+            <#assign displayString = ""/>
+            <#list displayFieldsSet as key>
+                <#assign field = autocompleteOption.get(key)?if_exists>
+                <#if field?has_content>
+                    <#if (key != context.returnField)>
+                        <#assign displayString = displayString + field + " ">
+                    </#if>
+                </#if>
+            </#list>
+            <#if (displayString?trim?has_content )>${displayString?trim}</#if>
+        </#list>
+    </#if>
+<#else>
 <script type="text/javascript">
 var autocomp = [
     <#if autocompleteOptions?exists>
@@ -25,7 +41,7 @@ var autocomp = [
             <#assign displayString = ""/>
             <#assign returnField = ""/>
             <#-- <#list autocompleteOption.keySet() as key> instead use the field order of display fields -->
-                <#list context.displayFieldsSet as key>
+                <#list displayFieldsSet as key>
                 <#assign field = autocompleteOption.get(key)?if_exists>
                 <#if field?has_content>
                     <#if (key == context.returnField)>
@@ -45,4 +61,5 @@ var autocomp = [
         </#list>
     </#if>
 ];
-</script>
\ No newline at end of file
+</script>
+</#if>

Modified: ofbiz/branches/jquery/framework/images/webapp/images/fieldlookup.js
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/images/webapp/images/fieldlookup.js?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/images/webapp/images/fieldlookup.js (original)
+++ ofbiz/branches/jquery/framework/images/webapp/images/fieldlookup.js Thu Oct 28 11:26:32 2010
@@ -26,6 +26,8 @@ var mx, my;
 var ACTIVATED_LOOKUP = null;
 var LOOKUP_DIV = null;
 var INITIALLY_COLLAPSED = null;
+var SHOW_DESCRIPTION = false;
+
 
 function moveobj(evt) {
     if (NS4 || NS6) {
@@ -193,9 +195,10 @@ function ConstructLookup(requestUrl, inp
 
     // createAjax autocomplete
     if (ajaxUrl != "" && showDescription != "") {
+         SHOW_DESCRIPTION = showDescription;
         //write the new input box id in the ajaxUrl Array
-        ajaxUrl = ajaxUrl.replace(ajaxUrl.substring(0, ajaxUrl.indexOf(",")), newInputBoxId)
-        new ajaxAutoCompleter(ajaxUrl, showDescription);
+        ajaxUrl = ajaxUrl.replace(ajaxUrl.substring(0, ajaxUrl.indexOf(",")), newInputBoxId);
+        new ajaxAutoCompleter(ajaxUrl, showDescription, formName);
     }
     
     var positioning = null;
@@ -538,7 +541,7 @@ function lookupAjaxRequest(request) {
     // get request arguments
     var arg = request.substring(request.indexOf('?')+1,(request.length));    
     lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
-    $("#" + lookupId).load(request, arg, function(data) { 
+    jQuery("#" + lookupId).load(request, arg, function(data) { 
         if (data.search(/loginform/) != -1) {
             window.location.href = window.location.href;
             return;
@@ -628,6 +631,11 @@ function set_value (value) {
     var target = obj_caller.target;
     
     write_value(value, target);
+    field = jQuery("#" + target.attr('id'));
+    field.trigger("lookup:changed");
+    if (field.change != null) {
+        field.click().change()
+    }
     
     closeLookup();
 }
@@ -644,6 +652,7 @@ function set_values (value, value2) {
     var target2 = obj_caller.target2;
     write_value(value, target);
     write_value(value2, target2)
+    if (SHOW_DESCRIPTION) setLookDescription(target.attr("id"), value + " " + value2, "", "");
     
     closeLookup();
 }
@@ -658,7 +667,13 @@ function write_value (value, target) {
 
 function set_multivalues(value) {
     obj_caller.target.value = value;
-    obj_caller.target.fire("lookup:changed");
+    field = jQuery("#" + target.attr('id')); // TODO: Not tested (should be ok)we need to fix 1st the window lookup (see OFBIZ-3933)
+    field.trigger("lookup:changed"); //  If we decide to keep it (only used in Example, though it's needed also for Themes and Languages but not the same way)
+    if (field.change != null) {
+        field.click().change()
+    }
+     
+
     var thisForm = obj_caller.target.form;
     var evalString = "";
     
@@ -684,36 +699,45 @@ function closeLookup() {
 }
 
 //load description for lookup fields 
-function lookupDescriptionLoaded(fieldId, url, params) {
+var lookupDescriptionLoaded = function(fieldId, url, params, formName) {
+  this.init(fieldId, url, params, formName);
+}
 
-    this.fieldId = fieldId;
-    this.url = url;
-    this.params = params;
-    this.updateLookup();
-    $(fieldId).observe('change', this.updateLookup.bind(this));
-    $(fieldId).observe('lookup:changed', this.updateLookup.bind(this));
+jQuery.extend(lookupDescriptionLoaded.prototype, {
 
+   init: function(fieldId, url, params, formName) {
+     this.fieldId = fieldId;
+     this.url = url;
+     this.params = params;
+     this.formName = formName;
+   },
+   update: function(){
+     var tooltipElement = jQuery("#" + this.fieldId + '_lookupDescription');
+     if (tooltipElement.length) {//first remove current description
+         tooltipElement.remove();
+     }
+      //actual server call
+      var fieldName = this.params.substring(this.params.indexOf("searchValueFieldName"));
+      fieldName = fieldName.substring(fieldName.indexOf("=") + 1);
+      var fieldSerialized = jQuery("input[name=" + fieldName  + "]", jQuery("form[name=" + this.formName  + "]")).serialize();
+      this.allParams = this.params + '&' + fieldSerialized + '&' + 'searchType=EQUALS';
+      _fieldId = this.fieldId;
+
+     jQuery.ajax({
+       url: this.url,
+       type: "POST",
+       data: this.allParams,
+       async: false,
+       success: function(result){
+         // This would be far more reliable if we would remove the widget boundaries in LookupDecorator using widgetVerbose in context
+        setLookDescription(_fieldId, result.split("ajaxAutocompleteOptions.ftl -->")[1].trim().split("<!--")[0].trim(), "", "");
+      }
+    });
+  }
+});
 
-    this.updateLookup = function() {
-        var tooltipElement = $(this.fieldId + '_lookupDescription');
-        if (tooltipElement) {//first remove current description
-            tooltipElement.remove();
-        }
-        if (!$F(this.fieldId)) {
-            return;
-        }
-        //actual server call
-        var allParams = this.params + '&' + $(this.fieldId).serialize() + '&' + 'searchType=EQUALS'
-        new Ajax.Request(this.url,{parameters: allParams, onSuccess: this.updateFunction.bind(this)});
-    }, 
-    
-    this.updateFunction = function(transport) {
-        var wrapperElement = new Element('div').insert(transport.responseText);
-        if('UL'!= wrapperElement.firstDescendant().tagName || (wrapperElement.firstDescendant().childElements().length != 1)) {    
-            return;
-        }
-        Element.cleanWhitespace(wrapperElement);
-        Element.cleanWhitespace(wrapperElement.down());
-        setLookDescription(this.fieldId, wrapperElement.firstDescendant().firstDescendant().innerHTML);
-    }            
-};
\ No newline at end of file
+if(typeof String.prototype.trim !== 'function') { // Needed because IE8 does not implement trim yet
+  String.prototype.trim = function() {
+    return this.replace(/^\s+|\s+$/g, ''); 
+  }
+}
\ No newline at end of file

Modified: ofbiz/branches/jquery/framework/images/webapp/images/getDependentDropdownValues.js
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/images/webapp/images/getDependentDropdownValues.js?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/images/webapp/images/getDependentDropdownValues.js (original)
+++ ofbiz/branches/jquery/framework/images/webapp/images/getDependentDropdownValues.js Thu Oct 28 11:26:32 2010
@@ -67,7 +67,7 @@ function getDependentDropdownValues(requ
 		        })
 	        };
             // Hide/show the dependent drop-down if hide=true else simply disable/enable
-            if ((!list) || (list.size() < 1) || ((list.size() == 1) && list[0].indexOf("_NA_") >=0)) {
+            if ((!list) || (list.length < 1) || ((list.length == 1) && list[0].indexOf("_NA_") >=0)) {
             	jQuery(target).attr('disabled', 'disabled');
             	if (hide) {
 	                if (jQuery(target).is(':visible')) {

Modified: ofbiz/branches/jquery/framework/images/webapp/images/selectall.js
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/images/webapp/images/selectall.js?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/images/webapp/images/selectall.js (original)
+++ ofbiz/branches/jquery/framework/images/webapp/images/selectall.js Thu Oct 28 11:26:32 2010
@@ -384,7 +384,8 @@ function ajaxSubmitFormUpdateAreas(form,
  * @param areaCsvString The area CSV string. The CSV string is a flat array in the
  * form of: areaId, target, target parameters [, areaId, target, target parameters...].
 */
-function ajaxAutoCompleter(areaCsvString, showDescription) {
+
+function ajaxAutoCompleter(areaCsvString, showDescription, formName) {
    var areaArray = areaCsvString.replace(/&amp;/g,'&').split(",");
    var numAreas = parseInt(areaArray.length / 3);
 
@@ -397,7 +398,7 @@ function ajaxAutoCompleter(areaCsvString
           }
 
           jQuery("#" + div).autocomplete({
-           source: function(request, response) {
+            source: function(request, response) {
                 jQuery.ajax({
                     url: url,
                     async: false,
@@ -409,52 +410,47 @@ function ajaxAutoCompleter(areaCsvString
                         response(autocomp);
                     }
                 })
+            },
+            select: function(event, ui) {
+               jQuery("#" + areaArray[0]).html(ui.item)
+               if (showDescription) {
+                  setLookDescription(areaArray[0] ,ui.item.label, areaArray[2], formName)
+                }
             }
         });
+        if (showDescription) {
+          var lookupDescriptionLoader = new lookupDescriptionLoaded(areaArray[i], areaArray[i + 1], areaArray[i + 2], formName);
+          lookupDescriptionLoader.update();
+          jQuery("#" + areaArray[i]).bind('change lookup:changed', function(){
+            lookupDescriptionLoader.update();
+          });
+        }
    }
 }
 
-function setSelection(text, li) {
-    text.value = li.id;
-    var delay = function() { jQuery("#" + text).trigger("lookup:changed"); };
-    setTimeout(delay, 100);
-}
-
-function setLookDescription(textFieldId, description) {
+function setLookDescription(textFieldId, description, params, formName) {
     if (description) {
         var start = description.lastIndexOf(' [');
         if (start != -1) {
-        /* this breaks many existing fields, so commenting for now: assumes main field is the name field and id field is hidden, determines Name/Id fields based on name instead of using description-field-name attribute
-            // To allow to set a dependent Id field when using a Name field as a lookup (the fields must have the same prefix, eg: partyName, partyId)
-            // It uses the description (Id) shown with the Name. Hence the Lookup screen must be set in order to show a description in the autocomplete part. 
-            // It seems this is not always easy notably when you need to show at least 2 parts for the Name (eg Person). 
-            // At least it easy to set and it works well for simples case for now (eg PartyGroup)            
-            var dependentId = textFieldId.replace(/Name/, "Id"); // Raw but ok for now, needs safe navigation...
-            // I did not find another way since Ajax.Autocompleter can't update another field
-            // The alternative would be navigation to the next hidden field, at least it would avoid the mandatory Id/Name pair
-            // But it's more difficult to demonstrate in Example component
-            // dependentId = (textFieldId.next('div').down('input[type=hidden]'); 
-            $(dependentId).clear();
-            var dependentIdValue = (description.substring(start + 1, description.length).replace(/\[/g, "")).replace(/\]/g, "");
-            if ($(dependentId)) {            
-                $(dependentId).value = dependentIdValue;
-            }
-         */
-             
             description = description.substring(0, start);
-        /*
-            $(dependentId).value = description;
-         */
+            
+            // This sets a possible dependent field. It depends on the searchFields order which makes sense anyway
+            var dependentField = params.substring(params.indexOf("searchValueFieldName"));
+            dependentField = jQuery("#" + formName + "_" + dependentField.substring(dependentField.indexOf("=") + 1));            
+            var dependentFieldValue = description.substring(0, description.lastIndexOf(' '))
+            if (dependentField.length) {            
+                dependentField.val(dependentFieldValue);
+            }
         }
     }
-    var lookupWrapperEl = jQuery("#" + textFieldId).closest(jQuery('.field-lookup'));
-    if (lookupWrapperEl) {
-        var tooltipElement = jQuery("#" + textFieldId + '_lookupDescription');
-        if (!tooltipElement) {
+    var lookupWrapperEl = jQuery("#" + textFieldId).closest('.field-lookup');
+    if (lookupWrapperEl.length) {
+        tooltipElement = jQuery("#" + textFieldId + '_lookupDescription')
+        if (!tooltipElement.length) {
             tooltipElement = jQuery("<span id='" + textFieldId + "_lookupDescription' class='tooltip'></span>");
         }
         tooltipElement.html(description);
-        tooltipElement.append(lookupWrapperEl);
+        lookupWrapperEl.append(tooltipElement);
     }
 }
 

Modified: ofbiz/branches/jquery/framework/widget/templates/htmlFormMacroLibrary.ftl
URL: http://svn.apache.org/viewvc/ofbiz/branches/jquery/framework/widget/templates/htmlFormMacroLibrary.ftl?rev=1028261&r1=1028260&r2=1028261&view=diff
==============================================================================
--- ofbiz/branches/jquery/framework/widget/templates/htmlFormMacroLibrary.ftl (original)
+++ ofbiz/branches/jquery/framework/widget/templates/htmlFormMacroLibrary.ftl Thu Oct 28 11:26:32 2010
@@ -480,6 +480,15 @@ ${item.description}</span>
     </#if>
     );"></a><#rt>
 <#else>
+    <#if ajaxEnabled?has_content && ajaxEnabled>
+      <#if !ajaxUrl?contains("searchValueFieldName=")>
+          <#if descriptionFieldName?has_content && showDescription == "true">
+            <#local ajaxUrl = ajaxUrl + "&amp;searchValueFieldName=" + descriptionFieldName />
+          <#else>
+            <#local ajaxUrl = ajaxUrl + "&amp;searchValueFieldName=" + name />
+          </#if>
+      </#if>
+    </#if>
     <script type="text/javascript">
         jQuery(document).ready(function(){
             new ConstructLookup("${fieldFormName}", "${id}", document.${formName?html}.${name?html}, <#if descriptionFieldName?has_content>document.${formName?html}.${descriptionFieldName}<#else>null</#if>, "${formName?html}", "${width}", "${height}", "${position}", "${fadeBackground}", <#if ajaxEnabled?has_content && ajaxEnabled>"${ajaxUrl}", "${showDescription}"<#else>"", ""</#if>);