5

I want to add Primefaces components dynamically. I'm using solution similar to this one, which was discussed there earlier:

<h:form>
    <h:panelGrid columns="2">
        <p:dataGrid id="categoriesGrid" value="#{bean.categories}"
            var="categoryBean" rowIndexVar="rowIndex">
            <p:column>
                <p:selectOneMenu id="categorySelect" effect="drop"
                    value="#{categoryBean.selectedCategory}" >
                    <f:selectItems value="#{categoryBean.availableCategories}"
                        var="category" itemLabel="#{category.name}"
                        itemValue="#{category}" />
                </p:selectOneMenu>
            </p:column>
        </p:dataGrid>
        <p:commandButton actionListener="#{bean.addNewCategory}"
            value="Add category" update="categoriesGrid"/>
    </h:panelGrid>
</h:form>

But there is problem with it. There is example of respond I get after "Add category" button was clicked:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<error>
    <error-name>
        class javax.faces.component.UpdateModelException
    </error-name>
    <error-message>
        <![CDATA[/createTutorial.xhtml @85,65 value=
            "#{categoryBean.selectedCategory}":java.util.NoSuchElementException]]>
    </error-message>
</error>
</partial-response>

Thanks in advance

Betlista
  • 10,327
  • 13
  • 69
  • 110
nikagra
  • 835
  • 2
  • 9
  • 23
  • As I found [there](http://code.google.com/p/primefaces/issues/detail?id=1568), `p:column` must be added, but the problem with ajax still exist – nikagra Nov 22 '11 at 09:42
  • Please post your solution as an answer (which you can accept later yourself). – oers Nov 22 '11 at 11:25
  • Do not put "Solved" in title. Post an **answer** and mark it accepted. This is a Q&A site, not a discussion forum or something. – BalusC Nov 22 '11 at 12:50

1 Answers1

2

The problem was with my bean. In order to get selected item, I had to implement custom implementation of javax.faces.Converter interface. In my opinion it's quite much work to do for such simple problem (this converter must be able to have access to data source and so on). So I've made a little trick:

public class CategoryBean{

    private list<Category> availableCategories;
    private Category selectedCategory;

    public Long getCSelectedCategory(){
        // Get selected category by it's id and set selectedCategory
    }

    public void setSelectedCategory(Long selectedCategory){
        return selectedCategory.getId();
    }

    // The remaining setters and getters
}

And the corresponding piece of page code now looks like:

<p:column>
    <p:selectOneMenu id="categorySelect" effect="drop"
        value="#{categoryBean.selectedCategory}" >
        <f:selectItems value="#{categoryBean.availableCategories}"
            var="category" itemLabel="#{category.name}"
            itemValue="#{category.id}" />
    </p:selectOneMenu>
</p:column>

Please, pay your attention to the itemValue attribute and access methods that are shown.The bug I had was wrong getter return type.

Concluding, the only problem with adding new Primefaces components dynamically in my case was returning selected value. You may implement converter or use similar trick.

Is such trick a good solution in your opinion?

Betlista
  • 10,327
  • 13
  • 69
  • 110
nikagra
  • 835
  • 2
  • 9
  • 23
  • If this is your final code then it does not look good and your trick is not a good trick. Because, if you take a look at this `value="#{categoryBean.selectedCategory}"` and this `itemValue="#{category.id}"`, it looks confusing. I think it's a good practice to use a converter in such a case. – Bhesh Gurung Nov 23 '11 at 14:44