Конфликт идентификатора поля внутри формы JSF с dataGrid - PullRequest
2 голосов
/ 06 августа 2011

Я реализую типичную корзину для покупок, основанную на компоненте dataGrid PrimeFaces. Ниже приведен пример кода.

Все в порядке, но поле inputText приводит к тому, что свойство bean-компонента устанавливается столько раз, сколько элементов на странице. Итак, если я добавлю 1 в первый элемент таблицы данных, он будет установлен, но после этого он будет установлен на 0 N раз, перезаписывая его.

Полагаю, это потому, что каждый inputText имеет одинаковый идентификатор. Я пытался заключить input + commandLink в их собственную форму, но это не работает. Я уверен, что это частый случай, и должно быть элегантное решение.

<h:form id="itemsForm" prependId="false">
    <p:dataGrid id="itemList" value="#{itemsBean.items}" var="item" type="unordered" paginator="true" rows="12" columns="1">                    
        <p:column>
            <p:inputText value="#{cartBean.quantity}"/>
            <p:commandLink actionListener="#{cartBean.add}" update=":cartPanel" value="Add to cart">
                <f:setPropertyActionListener target="#{cartBean.itemToCart}" value="#{item}"/>
            </p:commandLink>
        </p:column>             
    </p:dataGrid>
</h:form>

1 Ответ

1 голос
/ 06 августа 2011

Вы можете использовать AJAX здесь, чтобы сделать partial submit* данных вашей формы.Я приведу пример, используя встроенную поддержку JSF 2.0 AJAX и стандарт dataTable, но идея аналогична для JSF 1.x (например, a4j) и dataGrid:

Facelet:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"   
>   
    <h:head/>

    <h:body>

        <h:form id="form">

            <h:dataTable id="table" value="#{singleListSelectBean.items}" var="item">
                <h:column>                    
                    #{item}            
                    <h:inputText id="input" value="#{singleListSelectBean.value}" />
                    <f:ajax execute="input">
                        <h:commandButton value="Select" action="#{singleListSelectBean.select(item)}"  />
                    </f:ajax>
                </h:column>
            </h:dataTable>

        </h:form>

    </h:body>
</html>

Bean:

@ManagedBean
@ViewScoped
public class SingleListSelectBean {

    private List<String> items = Arrays.asList("a", "b", "c");
    private String value;

    public void select(String item) {
        System.out.format("Selecting item %s with value %s.", item, value);
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public List<String> getItems() {
        return items;
    }

}

В данном случае тег <f:ajax> применяет возможности Ajax ккомандная кнопка.Через атрибут execute вы сообщаете ему, что должен обрабатываться только ввод компонента с идентификатором input.

В контексте рендеринга каждой кнопки команды идентификатор input преобразуется в другой фактический client ID для каждого ряда.Например, form:table:0:input для первого ряда, form:table:1:input для второго ряда и так далее.Посредством этого выполняется частичная передача, и привязка единственного значения вашего компонента поддержки получает значение для строки, по которой щелкнул пользователь.

Обратите внимание, что в данном примере таблица не перерисовывается изначение будет «прилипать» к каждому входному текстовому компоненту.Это может создать иллюзию того, что ваш компонент поддержки связан с несколькими значениями, но это не случай.

(*) Хотя концептуально мы говорим о partial submitконкретная реализация JSF (например, Mojarra) все еще может разместить всю форму и отфильтровать ее на стороне сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...