[ 
https://issues.apache.org/jira/browse/TOMAHAWK-1157?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12604734#action_12604734
 ] 

Leonardo Uribe commented on TOMAHAWK-1157:
------------------------------------------


This problem is a little bit complex, so I'll detail the steps creating the 
solution.

Checking this problem in deep, the first conclusion was that the problem is 
related to the way that trinidad render the hidden field javax.faces.ViewState 
(do not render the id, so the dojo extension api do not add this param to the 
ajax call used to retrieve the suggested values for inputSuggestAjax and 
tableSuggestAjax).

After some discussion, the suggested solution was to use some algorithm to 
retrieve the field using its name instead its id. 

inputSuggestAjax and tableSuggestAjax components only sends the value that the 
user is typing, and based only on this value returns a list of suggested 
values. 

Other components like ajaxChildComboBox calls directly dojo.io.bind and set its 
formNode with the parent form of the component. The result is that all input 
values inside the form are added to the request, including 
javax.faces.ViewState. 

But in this special case, send all input values are not necessary. The proposed 
solution is do a modification of 

org.apache.myfaces.custom.dojoextensions.resource.FacesIO.js 

file. An original copy and discussion of this transport can be seen here:

http://cagataycivici.wordpress.com/2007/01/15/creating_a_custom_dojo_transport/

The idea is catch the param "affectedAjaxComponent" encoded in the dataUrl used 
to retrieve the suggestions list, and using this id use an algorithm to 
retrieve the parent form and send the right javax.faces.ViewState parameter. An 
example of the script rendered defining the dojo inputSuggestAjax is here:

<script type="text/javascript">var j_id11_dojoControl = 
dojo.widget.createWidget("extensions:InputSuggestAjax",{mode:'remote',textInputId:'j_id4:j_id8',autoComplete:true,
dataUrl:'/myfaces-example-tt-facelets/inputSuggestAjax.jsf?affectedAjaxComponent=j_id4:j_id8&charset=utf-8&j_id4:j_id8=%{searchString}'},
dojo.byId('j_id11'));
</script>

The copy of the new proposed file commented is shown below:

dojo.provide("extensions.FacesIO");

dojo.io.FacesTransport = new function() {
    this.canHandle = function(kwArgs) {
        return this.isClientStateSaving(kwArgs) && 
dojo.io.XMLHTTPTransport.canHandle(kwArgs);
    }

    this.bind = function(request) {
        if (this.isClientStateSaving(request)) {
            request.method = "post";
            this.addJsfState(request);
        }
        return dojo.io.XMLHTTPTransport.bind(request);
    }

    this.isClientStateSaving = function(kwArgs) {
        //First check if we have a component where we can retrieve it
        //without using its id.
        var affectedAjaxComponent = 
this.getParamValueFromUrl(kwArgs.url,"affectedAjaxComponent");
        if (affectedAjaxComponent)
        {
            var formElement = 
dojo.dom.getAncestorsByTag(document.getElementById(affectedAjaxComponent), 
"form", true);            
            return formElement["javax.faces.ViewState"];
        }    
        return dojo.byId("javax.faces.ViewState");
    }

    this.addJsfState = function(request) {
        request.content = request.content || {};
        
        //This is a hack to make work s:inputSuggestAjax and s:tableSuggestAjax
        // with trinidad. The idea is obtain the request param 
affectedAjaxComponent
        //encoded in the url, and with this id
        
        //previously the way to do this was:
        //request.content = request.content || {};
        //this.addInputValue(request.content, "javax.faces.ViewState");
        //but trinidad does not render the id on this hidden field, which causes
        //problems on this code.
        
        var affectedAjaxComponent = 
this.getParamValueFromUrl(request.url,"affectedAjaxComponent");
        
        if (affectedAjaxComponent)
        {
            //Find the affectedAjaxComponent using its id, then its parent form
            //and finally the tag with name javax.faces.ViewState
            //Remember that each form has its own child with            
            var formElement = 
dojo.dom.getAncestorsByTag(document.getElementById(affectedAjaxComponent), 
"form", true);

            //request.content["javax.faces.ViewState"] = 
formElement["javax.faces.ViewState"].value;            
            if (request.postContent){
                request.postContent = request.postContent + 
'&javax.faces.ViewState='+ formElement["javax.faces.ViewState"].value;
            }else{
                request.postContent = 'javax.faces.ViewState='+ 
formElement["javax.faces.ViewState"].value;
            }            
        }
        else
        {
            this.addInputValue(request.content, "javax.faces.ViewState");       
 
        }
    }
    
    this.getParamValueFromUrl = function(url,param) {
        var startIndexParams = url.indexOf("?"); 
        if ( startIndexParams > -1 ){
            var paramList = url.substr(startIndexParams);
            var aQueryString = paramList.split("&");
            for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
                if (aQueryString[iParam].indexOf(param + "=") > -1 ){
                    var aParam = aQueryString[iParam].split("=");
                    return aParam[1];
                }
            }
         }
         return false;
    } 

    this.addInputValue = function (content, inputName) {
        var control = dojo.byId(inputName);
        if (!control || !control.value)
            return;
        content[inputName] = control.value;
    }

    dojo.io.transports.addTransport("FacesTransport");
    dojo.io.transports.reverse();
}

Suggestions are welcome! I'll commit this if no objections.


> tableSuggestAjax not render with trinidad
> -----------------------------------------
>
>                 Key: TOMAHAWK-1157
>                 URL: https://issues.apache.org/jira/browse/TOMAHAWK-1157
>             Project: MyFaces Tomahawk
>          Issue Type: Bug
>    Affects Versions: 1.1.7-SNAPSHOT
>         Environment: Linux, Facelets, Trinidad, JSF RI 1.2
> <trinidadVersion>1.2.1</trinidadVersion>
> <riVersion>1.2_04-p02</riVersion>
> <dependency>
>                       <groupId>com.sun.facelets</groupId>
>                       <artifactId>jsf-facelets</artifactId>
>                       <version>1.1.12</version>
> </dependency>
>            Reporter: Tomas Cerny
>             Fix For: 1.1.7-SNAPSHOT
>
>
> When I use tag definition
> --------------facelets taglib---------------------------
> <tag>
>       <tag-name>tableSuggestAjax</tag-name>
>       <component>
>            
> <component-type>org.apache.myfaces.TableSuggestAjax</component-type>
>            <renderer-type>org.apache.myfaces.TableSuggestAjax</renderer-type>
>       </component>
>  </tag>
> --------------JSF--------------------------
>  <h:panelGrid id="panelG1">
>                         <h:panelGrid id="panelG2" columns="3"> 
>                                         <s:tableSuggestAjax var="item" 
> id="suggest" startRequest="1" 
>                                                    
> value="#{inputSuggestAjax.suggestValue}" betweenKeyUp="300"
>                                                    maxSuggestedItems="10"
>                                                    
> suggestedItemsMethod="#{inputSuggestAjax.list}" charset="utf-8">
>                                                   <t:column>
>                                                        <f:facet name="header">
>                                                            <s:outputText 
> value="First Name"/>
>                                                        </f:facet>
>                                                        <s:outputText 
> for="suggest" label="#{item.fname}"/>
>                                                    </t:column>
>                                                    <t:column>
>                                                        <f:facet name="header">
>                                                            <s:outputText 
> value="Last Name"/>
>                                                        </f:facet>
>                                                        <s:outputText 
> for="lname" label="#{item.lname}"/>
>                                                    </t:column>
>                                            
>                                   </s:tableSuggestAjax>
>                                </h:panelGrid>
>                        
>                          <t:inputText id="lname" />
>                        </h:panelGrid>
> ------------------Java-----------------------
> package edu.baylor.icpc.view.utils;
> import java.util.ArrayList;
> import java.util.List;
> public class InputSuggestAjax {
>     private String suggestValue = "ab";
>     public String getSuggestValue() {
>         return suggestValue;
>     }
>     public void setSuggestValue(String suggestValue) {
>         this.suggestValue = suggestValue;
>     }
>     
>     public class Foo {
>         
>         private String fname; 
>         private String lname;
>         
>         public Foo(String fname, String lname) {
>             super();
>             this.fname = fname;
>             this.lname = lname;
>         }
>         public String getLname() {
>             return lname;
>         }
>         public void setLname(String lname) {
>             this.lname = lname;
>         }
>         public String getFname() {
>             return fname;
>         }
>         public void setFname(String fname) {
>             this.fname = fname;
>         } 
>     }   
>     
>     public List<Foo> getList(String prefix, Integer maxSize) {
>         setSuggestValue(prefix);
>         return getList();
>     }
>     public List<Foo> getList(String prefix) {
>         setSuggestValue(prefix);
>         return getList();
>     }
>     public List<Foo> getList() {
>         List<Foo> list = new ArrayList<Foo>();
>         
>         if(suggestValue.startsWith("a")) {
>             list.add(new Foo("Adolf","Himler"));
>             list.add(new Foo("Alfonz","Himler"));
>             list.add(new Foo("Alfred","Himler"));
>             
>         } else if(suggestValue.startsWith("b")) {
>             list.add(new Foo("Bob","Himler"));
>             list.add(new Foo("Brok","Himler"));
>             list.add(new Foo("Bobo","Himler"));
>             
>         } else {
>             
>         }
>         
>         return list;
>     }
> }
> -----------------------------------------
> everything is rendered but 
> suggestedItemsMethod is ignored at all so it does not work
> -----------------------------------------
> When I add to the taglib
> -----------------------------------------
> <handler-class>InputSuggestAjaxComponentHandler</handler-class>
> OR
> <handler-class>
>                 facelets.InputSuggestAjaxComponentHandler
> </handler-class>
> -----------------------------------------
> component is not rendered and I see in my HTML <s:tableSuggestAjax ....
> -----------------------------------------
> log:
> Nov 29, 2007 7:21:39 PM 
> org.apache.myfaces.trinidadinternal.io.HtmlResponseWriter endElement
> SEVERE: Element End name:td does not match start name:s:tableSuggestAjax
> Nov 29, 2007 7:21:39 PM 
> org.apache.myfaces.trinidadinternal.io.HtmlResponseWriter endElement
> SEVERE: Element End name:tr does not match start name:td
> Nov 29, 2007 7:21:39 PM 
> org.apache.myfaces.trinidadinternal.io.HtmlResponseWriter endElement
> SEVERE: Element End name:s:tableSuggestAjax does not match start name:td
> Nov 29, 2007 7:21:39 PM 
> org.apache.myfaces.trinidadinternal.io.HtmlResponseWriter endElement
> SEVERE: Element End name:td does not match start name:tr
> Maybe I am missing something but I did exactly that is in your examples. 
> http://wiki.apache.org/myfaces/Use_Facelets_with_Tomahawk
> http://www.irian.at/myfaces-sandbox/tableSuggestAjax.jsp.source
> http://www.irian.at/cagatay-validation-sandbox/tableSuggestAjax.jsp.source
> http://wiki.java.net/bin/view/Projects/FaceletsTaglibsMyfacesSandbox?rev=12
> http://www.nabble.com/TableSuggestAjax-don't-work-anymore-after-a-reRender-from-Ajax4JSF-t3279629.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to