2

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;
    }
}
falsarella
  • 12,217
  • 9
  • 69
  • 115
Lester
  • 1,830
  • 1
  • 27
  • 44

3 Answers3

3

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.
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you for your answer. I could apply your code right away. I'm not really happy myself being dependent on the clients data. Actually I use the distance matrix service of google maps javascript api. That must be executed client-side and the data provided is supposed to alter which elements are shown on my page. – Lester Dec 04 '12 at 19:32
2

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>
falsarella
  • 12,217
  • 9
  • 69
  • 115
  • first, thank you for your answer. I always find myself oversimplifying code. actually the javascript calculates something on client-side, the server "doesn't know". now I want the server to somehow "read" the value of the `` and use it for the ``'s `rendered`-attribute for the current iteration. – Lester Dec 04 '12 at 15:51
  • I updated my question to make clear we need some data from client-side. – Lester Dec 04 '12 at 15:58
  • OK, you resolved the problem with BalusC's way, but you could just do what I've proposed with no need of javascript - and you would get what you asked, unless you depend on other logic that wasn't brought to us, as BalusC pointed. Thank you, anyway.. ^^ Great to see that you solved. – falsarella Dec 05 '12 at 14:24
  • Yeah, thank you! And sorry for not making my question from the headline more clear in the code and problem description and thus misleading you. – Lester Dec 05 '12 at 22:44
1

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.

dognose
  • 20,360
  • 9
  • 61
  • 107
  • Thanks for your answer. I picked BalusC's answer because it provides code that I could immediately apply, although your theory lesson is definitely helpful and enlightening, too. – Lester Dec 04 '12 at 19:27