JSF and f:ajax for hiding/showing div

2019-05-27 05:12发布

问题:

I am thinking of making a hidable/showable menu on my web application. Before this, I used PHP and AJAX extensively for this purpose. However, since HTML element id is regenerated in JSF framework I found out that this method is no longer feasible at least in my scope.

I have read f:ajax tag in JSF and tried to implement it. Apparently no luck for me. It looks so easy but I still could not find out what I did wrong.

I have prepared a prototype to test the f-ajax tag functionality but no luck. Here is the code

   ` <h:body>
     <h:outputLabel>
        <h:outputText value="Click A" />
        <f:ajax event="click" render="textA"/>
    </h:outputLabel>
    <h:outputLabel>
        <h:outputText value="Click B" />
        <f:ajax event="click" render="textB"/>
    </h:outputLabel>
    <h:outputLabel>
        <h:outputText value="Click C" />
        <f:ajax event="click" render="textC"/>
    </h:outputLabel>

    <h:outputText id="textA" value="Click A" />
    <h:outputText id="textB" value="Click B" />
    <h:outputText id="textC" value="Click C" />
    </h:body>`

When I clicked the particular label, nothing happend. The textA, textB and textC elements are already rendered in the first place. What did I do wrong guys?

Thanks in advance.

回答1:

However, since HTML element id is regenerated in JSF framework

If that is so important, just specify fixed ids yourself. Each component has an id attribute for that. This way you should be able to use normal JS/jQuery frameworks whenever applicable.

As to the problem in the concrete question, here's a working example which should get you started.

<h:form>
    <f:ajax render="text">
        <h:commandLink value="Click A" action="#{bean.setShow('A')}" /><br/>
        <h:commandLink value="Click B" action="#{bean.setShow('B')}" /><br/>
        <h:commandLink value="Click C" action="#{bean.setShow('C')}" /><br/>
    </f:ajax>

    <h:panelGroup id="text">
        <h:outputText value="Clicked A" rendered="#{bean.show == 'A'}" />
        <h:outputText value="Clicked B" rendered="#{bean.show == 'B'}" />
        <h:outputText value="Clicked C" rendered="#{bean.show == 'C'}" />
    </h:panelGroup>
</h:form>

in combination with

@ManagedBean
@ViewScoped
public class Bean {

    private String show;

    public String getShow() {
        return show;
    }

    public void setShow(String show) {
        this.show = show;
    }

}


回答2:

reading your code I would first give some general suggestions:

  • As far as I know ajax works on input elements but not on outputLabel. Use h:commandLink or h:commandButton instead
  • outputText should not be inside outputLabel. outputLabel is not necessary here
  • the outputText elements at the bottom are always shown unless you use the rendered attribute: <h:outputText id="textA" value="Click" rendered="false" />. You can use some EL-expression to make the rendered-attribute conditional.

I think the best would be to start with the Java-EE-Tutorial to learn about the basic concepts of jsf.