Assign expression "value" instead of "method expression" in JSF
In my composite component, I repeat a list<list<javaDetailClass>> . I get all the <h:commandButon> attribute values through a value expression, for example #{iterator.value} . But the problem is with the action attribute, where the action accepts only method expression . whereas I can only assign a value expression there, as a result we get a MethodNotFoundException
<cc:interface> <cc:attribute name="formElements" /> </cc:interface> <cc:implementation> <c:forEach items="#{cc.attrs.formElements}" var="element"> <c:forEach items="#{element}" var="iterator"> <h:commandButton id="#{iterator.id}" value="#{iterator.value}" action="#{iterator.action}"> </h:commandButton> </c:forEach> </c:forEach> </cc:implementation> Can someone help me fix this? Thanks in advance.
UPDATE
it will be a class of detail in my situation,
package com.stackoverflow.test; public class TestData { /*Properties based on the implementation of your composite. Change type where it is needed*/ private String id; private String value; private String attributeName; private String action; public TestData() { } /*Getters and setters omitted*/ } Bean.java just contains an ArrayList from an ArrayList. The constructor simply created five TestData objects and assigns some default values to its attributes.
package com.stackoverflow.test; import java.util.ArrayList; import javax.faces.bean.*; @ManagedBean @RequestScoped public class Bean { private ArrayList<ArrayList<TestData>> list = new ArrayList<ArrayList<TestData>>(); public Bean() { ArrayList<TestData> testDataList = new ArrayList<TestData>(); TestData data; for(int i = 0; i < 5; i++) { data = new TestData(); data.setId("ID" + i); data.setValue("VALUE" + i); data.setAttributeName("ATTRIBUTE" + i); /**this sets the action attribute of TestData with a API from some other managed bean**/ data.setAction("someOtherManagedbean.someactionAPI"); testDataList.add(data); } list.add(testDataList); } public ArrayList<ArrayList<TestData>> getList() { return list; } public void setList(ArrayList<ArrayList<TestData>> list) { this.list = list; } }
index.html simply calls the composite, setting the value "# {bean.list} to the name attribute
I assume that your TestData.java has the following method public String getAction() (since I see setAction(String) ) and not public String action() . Therefore, the reason you get a MethodNotFoundException is because you are pointing the wrong method name to the action attribute. In your case, it should be iterator.getAction , not iterator.action . You specify only abbreviated names when an attribute expects a value expression. The interface below has been changed.
<cc:interface> <cc:attribute name="formElements" /> </cc:interface> <cc:implementation> <c:forEach items="#{cc.attrs.formElements}" var="element"> <c:forEach items="#{element}" var="iterator"> <h:commandButton id="#{iterator.id}" value="#{iterator.value}" action="#{iterator.getAction}"> </h:commandButton> </c:forEach> </c:forEach> </cc:implementation>