1

This is my second day working with JSF. Have no previous background in Java , Have Been working with Flex and C++ for quite some time. Some history so that everybody knows where im coming from . For a "rush" project i am running into an issue

<h:panelGroup id="txeTab" layout="block" class="txeTab">

        <h1>TXE</h1>
        <h:form id="txeForm">
            <h:panelGrid columns="3">
                <c:forEach  items="${txeConfBean.getListTable()}" var="property">
                    <h:outputLabel id="key" value="${property.key}"/>
                    <h:inputText  id="value" value="${property.value}" />
                    <h:commandButton value="Change" action='${txeConfBean.setProperty('key','value')}'/>
                </c:forEach>
            </h:panelGrid>
        </h:form>   
    </h:panelGroup>

and The Bean is as follows

public  HashMap <String,String> getListTable ()
{
    String[] keys = new String[super.keyData.size()];
    HashMap <String,String> retKeys = new HashMap <String, String>();
    super.keyData.toArray(keys);

    for (int i=0;i<keys.length;i++)
    {
        if(!keys[i].isEmpty())
        {
            retKeys.put(keys[i],getProperty(keys[i]));
        }
    }

    return retKeys;

}

im able to display the Key,value pairs recursively. But i want to update a specific key with new value once someone updated the h:inputText id="value" value="${property.value}" /> and press the command button the new value is written to. Need help in this regard . Googling it make me feel there are too many ways to do it. Need help. I am just unable to figure out what to pass to ${txeConfBean.setProperty('key','value')} How can i pass the value of both InputText and OutPutText to setProperty ?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Hani Q
  • 135
  • 2
  • 15

1 Answers1

5

The ${}, which is inherited from legacy JSP, can't do a "set" operation on a property. It can only do a "get" operation on the property.

If you want to support both "get" and "set" on a property, you need the #{}. Even more, in general in JSF, you should not use ${} anymore. Further, in order to get/set a map value by an input component, you have to reference the map value by its key using the brace notation as #{bean.map[key]}.

<h:form id="txeForm">
    <h:panelGrid columns="3">
        <c:forEach items="#{txeConfBean.listTable}" var="property">
            <h:outputLabel id="key" value="#{property.key}"/>
            <h:inputText id="value" value="#{txeConfBean.listTable[property.key]}" />
            <h:commandButton value="Change" />
        </c:forEach>
    </h:panelGrid>
</h:form>   

Note that the command button action is omitted. JSF/EL will "automagically" already call the map's put() method when the model value is about to be updated. It's unnecessary in this particular construct. Also note that in this construct, the entire form is submitted. You might want either to put the command button outside the table, or to use <f:ajax> to submit the current "row" only.

See also:


Unrelated to the concrete problem: you're doing the business job in a getter method. This is extremely inefficient in case the property is referenced in iterating components. Do the business job in (post)constructor instead. It'll be invoked only once. This way you can make the getter really a fullworthy getter.

public HashMap<String,String> getListTable() {
    return listTable;
}

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I converted as per you pasted. Even the Books/Tutorial i followed said the same to use # and not t mention set or get in the property method. But strangely this way it is not generating the table. [link](http://stackoverflow.com/questions/4551132/how-to-access-map-in-jsf) this maybe the answer to that. Since im using HashMap thats why. I will try the `` – Hani Q Nov 22 '12 at 13:36
  • Apparently you're not using JSF 2.x with JSTL 1.2, but an older version. I recommend to upgrade. The `#{}` works only in JSTL 1.2, not in 1.1 or older. See also the link about EL differences in the above answer and our JSTL wiki page: http://stackoverflow.com/tags/jstl/info – BalusC Nov 22 '12 at 13:46
  • I downloaded the Latest NetBeans with GlassFish three days ago. I created a tutorial example app which displayed time the #{} was working there and like you mentioned i didnt have to specify get. But i created this new project and the #{} isnt working now. I even tried by calling a test method that just returns a string value. I also tried displaying a returned `String[]` in `` still couldnt get them to work :(. The JSTL is 1.2 confirmed by viewing the MANIFEST of my GlassFishServer for JSTL version . Implementation-Version: 1.2.1 and Specification-Version: 1.2 – Hani Q Nov 22 '12 at 15:14
  • funny observation `public String getRandomStuff () { return "Bad Times"; }` and xhtml `#{txeConfBean.randomStuff}` doesnt work but `#{txeConfBean.getRandomStuff()}` works and displays "bad times" on web page.So this confirms im using JSTL 1.2 but something is broken – Hani Q Nov 22 '12 at 15:19