1

I've have problem when it comes to rendering some of my components in my jsf application. The problem is when i use jQuery on my page for example hiding the button. When the page reRenders the button come back to its original form which is supposed to be hidden.

Has someone has expertise on this matter that will be able to help me find a suitable solution or there is some principles here or techniques which was i blindly misunderstood?

Thanks. :)

Ellie Fabrero
  • 791
  • 2
  • 16
  • 41

2 Answers2

2

The problem is when I use jQuery on my page for example hiding the button. When the page reRenders the button come back to its original form which is supposed to be hidden.

Don't use jQuery to manipulate the DOM, but use JSF Ajax instead to manipulate the DOM.

E.g.

<h:form>
    <h:selectBooleanCheckbox value="#{bean.checked}">
        <f:ajax render="buttons" />
    </h:selectBooleanCheckbox>

    <h:panelGroup id="buttons">
        <h:commandButton value="Submit" rendered="#{bean.checked}" />
    </h:panelGroup>
</h:form>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

We were facing the same issue under IceFaces 1.8.2. The problem is that the server side application does not know about your client side changes to the DOM. We solved it for us by applying marker classes to the elements we wanted to manipulate with jQuery. We used the generic client side callback for DOM-Updates (onAsynchronousReceive under IceFaces 1.8.x) to reapply our script.

Unfortunately not RichFaces specific:

<h:outputText value="my text" styleClass="doSomethingWithThisAfterDOMUpdate" />

And somewhere in your page markup (we are using jQuery bound to j instead of $):

<script type="text/javascript">

    // do somehting the first time
    j(".doSomethingWithThisAfterDOMUpdate").css('display', 'none'); 

    Ice.onAsynchronousReceive("document:body", function() {

        // do it again after each asynchronous receive
        j(".doSomethingWithThisAfterDOMUpdate").css('display', 'none');
    });
</script>

BUT: Be careful applying listeners to elements in the callback. If the element does not get replaced, you assign the same listeners a second, third, fourth time...

Under JSF2 AJAX became part of the spec. You might have a look at the client side method addOnEvent which could be the generic counter part of Ice.onAsynchronousReceive.

However, not all component frameworks seem to use the client side implementation of the spec to perform their DOM updates (i.e. PrimeFaces).

But I guess the principle becomes clear. You need to rerun the script after the DOM Element got replaced :)

Tim Brückner
  • 1,928
  • 2
  • 16
  • 27
  • 1
    Since I am only able to comment my own answers: BalusC is right, if there is a JSF way to do it, you should use it. Almost every component has a rendered flag for example so using jQuery to show and hide stuff, does not make that much sense. Perhaps I should have chosen a different example. Nevertheless, there are some cases where it goes beyond hiding and showing stuff, when components do not provide all of the functionality you need. Then you have a chance to fix stuff in the DOM, like adding a title attribute to an element if the custom component itself does not render one... – Tim Brückner Jan 19 '12 at 15:15