ICEfaces
  1. ICEfaces
  2. ICE-6327

Ajax support for commandButton and commandLink with f:param

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Beta2
    • Fix Version/s: 2.0.1
    • Component/s: Bridge
    • Labels:
      None
    • Environment:
      ICEfaces 2.0
    • Workaround Description:
      use f:setPropertyActionListener rather than f:param

      Description


      <f:param> can be added to both commandLink and commandButton, for instance in "basic":


              <h:commandButton id="button1" value="Show/Hide"
                               actionListener="#{basic.toggle}">
              </h:commandButton>
              <h:commandButton id="button1param" value="Show/Hide"
                               actionListener="#{basic.toggle}">
                  <f:param name="commandparam" value="buttonparam" />
              </h:commandButton>
              <h:commandLink id="link1param" value="Show/Hide"
                               actionListener="#{basic.toggle}">
                  <f:param name="commandparam" value="linkparam" />
              </h:commandLink>

      This should still yield Ajax interaction, but a full page refresh is observed with the commandLink and commandButton with f:param.

        Activity

        Hide
        Ted Goddard added a comment -

        Generated markup is as follows (includes commandLink with no param as well):

        <input id="button1" name="button1" type="submit" value="Show/Hide" />

        <input id="button1param" name="button1param" onclick="mojarra.jsfcljs(document.getElementById('form1'),

        {'button1param':'button1param','commandparam':'buttonparam'}

        ,'');return false" type="submit" value="Show/Hide" />

        <a href="#" id="link1" onclick="mojarra.jsfcljs(document.getElementById('form1'),

        {'link1':'link1','commandparam':'linkparam'}

        ,'');return false">Show/Hide</a>

        <a href="#" id="linknoparam" onclick="mojarra.jsfcljs(document.getElementById('form1'),

        {'linknoparam':'linknoparam'}

        ,'');return false">Show/Hide</a>

        Show
        Ted Goddard added a comment - Generated markup is as follows (includes commandLink with no param as well): <input id="button1" name="button1" type="submit" value="Show/Hide" /> <input id="button1param" name="button1param" onclick="mojarra.jsfcljs(document.getElementById('form1'), {'button1param':'button1param','commandparam':'buttonparam'} ,'');return false" type="submit" value="Show/Hide" /> <a href="#" id="link1" onclick="mojarra.jsfcljs(document.getElementById('form1'), {'link1':'link1','commandparam':'linkparam'} ,'');return false">Show/Hide</a> <a href="#" id="linknoparam" onclick="mojarra.jsfcljs(document.getElementById('form1'), {'linknoparam':'linknoparam'} ,'');return false">Show/Hide</a>
        Hide
        Mark Collette added a comment -

        With ace:fileEntry, it supplants the regular ICEfaces form capture on submit mechanism, and uses it's own instead. It has a similar problem with h:commandButton and h:commandLink with f:param.

        A regular h:commandButton with type="submit" does not render any javascript, and uses the browser's default form submission, which invokes onsubmit before submit. An h:commandButton with an f:param renders an onclick handler that calls a JSF javascript function, that programmatically calls submit. When that happens, onsubmit is not called. Browsers do not invoke on submit when submit is programmatically called. One solution would be for JSF's javascript function to call onsubmit itself.

        Show
        Mark Collette added a comment - With ace:fileEntry, it supplants the regular ICEfaces form capture on submit mechanism, and uses it's own instead. It has a similar problem with h:commandButton and h:commandLink with f:param. A regular h:commandButton with type="submit" does not render any javascript, and uses the browser's default form submission, which invokes onsubmit before submit. An h:commandButton with an f:param renders an onclick handler that calls a JSF javascript function, that programmatically calls submit. When that happens, onsubmit is not called. Browsers do not invoke on submit when submit is programmatically called. One solution would be for JSF's javascript function to call onsubmit itself.
        Hide
        Ted Goddard added a comment -

        Mojarra submit function:

        mojarra.jsfcljs = function jsfcljs(f, pvp, t) {
        mojarra.apf(f, pvp);
        var ft = f.target;
        if (t)

        { f.target = t; }

        f.submit();
        f.target = ft;
        mojarra.dpf(f);
        };

        This should automatically benefit from ICEfaces Ajax features.

        Show
        Ted Goddard added a comment - Mojarra submit function: mojarra.jsfcljs = function jsfcljs(f, pvp, t) { mojarra.apf(f, pvp); var ft = f.target; if (t) { f.target = t; } f.submit(); f.target = ft; mojarra.dpf(f); }; This should automatically benefit from ICEfaces Ajax features.
        Hide
        Ted Goddard added a comment -

        ice.captureSubmit() does not appear to be active for mojarra.jsfcljs(). Will it be difficult to include this as well?

        Show
        Ted Goddard added a comment - ice.captureSubmit() does not appear to be active for mojarra.jsfcljs(). Will it be difficult to include this as well?
        Hide
        Mircea Toma added a comment - - edited

        I tried 'scopes' test with one of the buttons having defined a f:param, the captureSumbit functionality works just fine in this case the submit being sent through an AJAX request.
        When trying 'basic' test I can see that the code put in for ICE-5651 kicks in. The form in 'basic' test case has a component with its AJAX functionality disabled (the 'reload' button). The code in fullSubmit function wrongly assumes that the form should use the native submit if any of the components has its AJAX functionality disabled.

        Show
        Mircea Toma added a comment - - edited I tried 'scopes' test with one of the buttons having defined a f:param, the captureSumbit functionality works just fine in this case the submit being sent through an AJAX request. When trying 'basic' test I can see that the code put in for ICE-5651 kicks in. The form in 'basic' test case has a component with its AJAX functionality disabled (the 'reload' button). The code in fullSubmit function wrongly assumes that the form should use the native submit if any of the components has its AJAX functionality disabled.
        Hide
        Ted Goddard added a comment -

        Maybe a regression? Full form submit should only apply to those components in the "disabled" list.

        Show
        Ted Goddard added a comment - Maybe a regression? Full form submit should only apply to those components in the "disabled" list.
        Hide
        Mircea Toma added a comment -

        When f:param is used for JSF decorates the 'onclick' event handler of the element triggering the submission with mojarra.jsfcljs function. The mojarra.jsfcljs function will add temporarely hidden fields to hold the defined parameters and then call form.submit() function to submit the form. When this happens the element triggering the submission is not passed into the submit() function, the form takes its place. In fullsubmit function the code determining which elements have their AJAX functionality disabled gets confused when the form itself is passed in.

        Show
        Mircea Toma added a comment - When f:param is used for JSF decorates the 'onclick' event handler of the element triggering the submission with mojarra.jsfcljs function. The mojarra.jsfcljs function will add temporarely hidden fields to hold the defined parameters and then call form.submit() function to submit the form. When this happens the element triggering the submission is not passed into the submit() function, the form takes its place. In fullsubmit function the code determining which elements have their AJAX functionality disabled gets confused when the form itself is passed in.
        Hide
        Mircea Toma added a comment -

        Fixed algorithm for determining which elements have their AJAX submission disabled so that it works even when the form element itself is passed in as submitting element. Introduced isAjaxDisabled private function to better capture and isolate the used algorithm. Removed redundant code that triggers the native browser form submission in application.js, used just the approach found in fullSubmit function.

        Show
        Mircea Toma added a comment - Fixed algorithm for determining which elements have their AJAX submission disabled so that it works even when the form element itself is passed in as submitting element. Introduced isAjaxDisabled private function to better capture and isolate the used algorithm. Removed redundant code that triggers the native browser form submission in application.js, used just the approach found in fullSubmit function.
        Hide
        Mircea Toma added a comment -

        It seems that h:form component does not accept the f:ajax facet since it throws an exception when configured so. Also looking in the JSF 2.0 spec there is no mentioning of any change in behavior of the h:form when f:ajax is present, only its included components can have their AJAX behavior changed.
        Wrapping the entire h:form in <f:ajax disable="true"> facet has as effect the disabling of AJAX for all the included components. Testing this use case shows that the list of disabled components is properly sent to the client.

        Considering that the spec doesn't specify any change in behavior for the h:form when configured with f:ajax facet and since the h:form does not accept the f:ajax facet anyway creating a test case that would verify h:form behavior in the presence of the facet is futile.

        Show
        Mircea Toma added a comment - It seems that h:form component does not accept the f:ajax facet since it throws an exception when configured so. Also looking in the JSF 2.0 spec there is no mentioning of any change in behavior of the h:form when f:ajax is present, only its included components can have their AJAX behavior changed. Wrapping the entire h:form in <f:ajax disable="true"> facet has as effect the disabling of AJAX for all the included components. Testing this use case shows that the list of disabled components is properly sent to the client. Considering that the spec doesn't specify any change in behavior for the h:form when configured with f:ajax facet and since the h:form does not accept the f:ajax facet anyway creating a test case that would verify h:form behavior in the presence of the facet is futile.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Ted Goddard
          • Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: