سؤال

I get the boolean value into the <h:inputText> but I can't find a way to get it into the rendered-attribute of the <h:panelGroup>. I also don't see a way to use a bean value, because every iteration would need one on it's own.

this is my jsf code:

<ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
    <script type="text/javascript">         
        showItem("#{item.id}","#{iteration.index}");
    </script>
    <h:inputText id="rendered"/>
    <h:panelGroup layout="block" rendered="???">
        Iteration #{iteration.index} rendered
    </h:panelGroup>
</ui:repeat>

this is my javascript:

function showItem(item,iteration){
    if((clientSideValue==something){
        document.getElementById("iterateItems"+":"+iteration+":"+"rendered").value = true;
    }
    else{
        document.getElementById("iterateItems"+":"+iteration+":"+"rendered").value = false;
    }
}
هل كانت مفيدة؟

المحلول

JavaScript runs in client side and works on the HTML DOM tree which is retrieved from the server side (and is in your particular case produced by JSF). JavaScript thus expects that the desired HTML element which you'd like to show/hide is always present in the HTML DOM tree.

JSF runs in server side and produces HTML code based on the JSF component tree (the "view"). When the rendered attribute of a JSF component evaluates to false, no HTML code would be produced for the given component and thus nothing would end up in the HTML DOM tree and thus nothing would be available to be selected by JavaScript's document.getElementById().

Your concrete functional requirement for which you thought that this would be the solution is unclear, so it's hard to propose the right solution for your concrete problem. But provided that you're absolutely positive that the show/hide needs to be performed in the client side (by JavaScript) instead of the server side (by JSF), then you should be using CSS' display property for this which you can toggle between block and none.

Here's a basic kickoff example, assuming that you want to initially hide it:

<ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
    <script type="text/javascript">         
        showItem(#{iteration.index});
    </script>
    <h:inputText id="rendered" />
    <div id="foo#{iteration.index}" style="display:none">
        Iteration #{iteration.index} shown
    </div>
</ui:repeat>

with

function showItem(index) {
    var div = document.getElementById("foo" + index);

    if (someCondition) {
        div.style.display = "block"; // Show it.
    } else {
        div.style.display = "none"; // Hide it.
    }
}

نصائح أخرى

Don't mix server-side script with client-side script!

Just use the EL as you want:

<ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
    <h:panelGroup layout="block" rendered="#{item.id le 1}">
        Iteration #{iteration.index} rendered
    </h:panelGroup>
</ui:repeat>

That is not possible: The JSF-Tags - especially the rendered Attribute are used during the RenderResponse Phase of JSF. When the final HTML has been generated, there is no more rendered attribute - the HTML Element containing that attribute is either rendered or not.

So, if you need to do something depending on client's values, you would need to transfer that value to your server.

A workaround would be to set the css-property display:none. But note, that this will JUST not display the element. It is STILL available in the Page Source.

If you are working with Javascript, you should really look at the final Sourcecode. The JSF Tags are resolved and even auto-generated IDs like 23:58:23 are not always the same for a certain element.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top