6 Replies Latest reply on Feb 10, 2011 10:23 AM by yagish

    a4j:jsFunction in IE6/7 breaks when html:form's prependId="f

    yagish

      In RichFaces3.2.2SR1, a4j:jsFunction generates an HTML script, which breaks in IE6/7, but works in FireFox. The issue is the way the jsFunction is rendered.

      Here is a sample of how the script is rendered in Ajax4JSF and in RichFaces when html:form's prependId attribute is false.

      <a4j:jsFunction name="func1" and id="func1" action="doSomething()"/>

      Notice that the name and id fields are kept same.

      In Ajax4JSF, this will render as -
      script id="func1" type="text/javascript"
      function func1(){.........};
      /script

      In RichFaces, this renders as -
      script id="func1" type="text/javascript">
      func1 = function(){.........};
      /script

      Having the id of script tag and the func1 prototype name as same creates the problem. IE6/7 while parsing the script tag gives an error - "Object does not supports this property".

      In RichFaces the renderer for jsFunction is AjaxFunctionRendererBase. This renderer's getFunction() method has changed from Ajax4JSF and generates this inappropriate javascript code.

      A sample to try in IE6/7 - (Uses Facelets, can get rid of them)

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:a4j="http://richfaces.org/a4j">




      <a4j:log popup="false" level="ALL" style="width: 800px; height: 300px;"></a4j:log>

      <f:view>
      <rich:panel header="Simple Echo">
      <h:inputText size="50" value="#{bean.text}" >
      <a4j:support event="onkeyup" reRender="rep"/>
      </h:inputText>
      <h:outputText value="#{bean.text}" id="rep"/>

      <a4j:jsFunction id="startSession" name="startSession" action="#{bean.startSession}" oncomplete="alert('I am done');"/>

      </rich:panel>

      </f:view>




        • 1. Re: a4j:jsFunction in IE6/7 breaks when html:form's prependI
          nbelaevski

          Hi,

          With the new style of rendering you can easily assign function to complex variable, e.g.:

          <h:form prependId="false">
           <rich:panel header="Simple Echo">
           <h:inputText size="50" value="#{bean.text}">
           <a4j:support event="onkeyup" reRender="rep" />
           </h:inputText>
           <h:outputText value="#{bean.text}" id="rep" />
          
           <script>
           var funcs = new Array();
           </script>
          
           <a4j:jsFunction id="startSession" name="funcs[0]"
           action="#{bean.startSession}" oncomplete="alert('I am done');" />
          
           <script>
           funcs[0]();
           </script>
          
           </rich:panel>
           </h:form>


          • 2. Re: a4j:jsFunction in IE6/7 breaks when html:form's prependI
            yagish

            Thanks nbelaevski.
            Your suggestion is similar to using different values for "id" and the "name" attributes. I have tried that and it does work. Also, changing the prependId attribute of html:form works, since it prepends the "id" with the form name, making it different from name attribute. (This does breaks the existing javascript though :( )

            My constraint is, I am porting our application from using Ajax4JSF to RichFaces3.2.2. So making this change in each JSF file, would require me to change every Javascript as well.

            I was trying to create a different renderer for the jsFunction component for RichFaces, but unfortunately its not easily configurable (or I dont know the correct way as yet). Another approach I am trying is to create a custom component and renderer and use that instead of a4j:jsFunction. This also is a big change, and not the best way of resolving this issue.

            I am trying to figure out a solution with the minimal impact. Would appreciate any help.

            Thanks
            Yagish Sharma

            • 3. Re: a4j:jsFunction in IE6/7 breaks when html:form's prependI
              nbelaevski
              • 4. Re: a4j:jsFunction in IE6/7 breaks when html:form's prependI
                yagish

                Here is a workaround to fix this issue.

                Create a new class extending the FunctionRenderer in RichFaces, and over-ride the getFunction method -

                public class NewAjaxFunctionRenderer extends FunctionRenderer{
                 /*
                 * (non-Javadoc)
                 *
                 * @see org.ajax4jsf.framework.renderer.RendererBase#getComponentClass()
                 */
                
                 public static final String RENDERER_TYPE = "org.cas.AjaxFunctionRenderer";
                 protected Class getComponentClass() {
                 return HtmlAjaxFunction.class;
                 }
                
                 public String getFunction(FacesContext context, UIAjaxFunction component) {
                 StringBuffer script = new StringBuffer();
                 JSFunctionDefinition func = new JSFunctionDefinition();
                 func.setName(component.getName());
                 // Create AJAX Submit function.
                 JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(
                 component, context,AjaxRendererUtils.AJAX_FUNCTION_NAME);
                 Map options = AjaxRendererUtils.buildEventOptions(context, component);
                 Map parameters = (Map) options.get("parameters");
                 if (null == parameters) {
                 parameters = new HashMap();
                 options.put("parameters", parameters);
                 }
                 ajaxFunction.addParameter(JSReference.NULL);
                 ajaxFunction.addParameter(options);
                 // Fill parameters.
                 for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
                 UIComponent child = (UIComponent) it.next();
                 if (child instanceof UIParameter) {
                 UIParameter parameter = ((UIParameter) child);
                 String name = parameter.getName();
                 func.addParameter(name);
                 // Put parameter name to AJAX.Submit parameter, with default value.
                 JSReference reference = new JSReference(name);
                 if (null != parameter.getValue()) {
                 reference = new JSReference(name + "||"
                 + ScriptUtils.toScript(parameters.get(name)));
                
                 }
                 // Replace parameter value to reference.
                 parameters.put(name, reference);
                 }
                 }
                 func.addToBody(ajaxFunction.toScript());
                 func.appendScript(script);
                 return script.toString();
                 }
                }


                In faces-config.xml add the new renderer for a4j:jsFunction -

                <renderer>
                 <component-family>org.ajax4jsf.components.AjaxFunction</component-family>
                 <renderer-type>
                 org.ajax4jsf.components.AjaxFunctionRenderer
                 </renderer-type>
                 <renderer-class>
                 org.test.NewAjaxFunctionRenderer
                 </renderer-class>
                 </renderer>


                • 5. Re: a4j:jsFunction in IE6/7 breaks when html:form's prependI
                  vatoslokos83

                  Hi,

                   

                  I have the same issue in our system. We are using version 3.3.0 of richfaces and it seems that the NewAjaxFunctionRenderer that I added wasn't invoked.

                  I did  the same things that mentioned here: Createed a new Class and added the renderer to face-config.xml file.

                   

                  Can someone help me to understand what should be done in order to make it invoked.

                   

                   

                  Thanks for any help.

                  • 6. a4j:jsFunction in IE6/7 breaks when html:form's prependId="f
                    yagish

                    Hi,

                      You will have to check in the faces-config in the richfaces jar, and see whats the component-family and renderer-type for AjaxFunctionRenderer is defined. Then you can over-write that with your custom renderer-class in your faces-config.xml. Hope this helps.

                     

                    yagish