powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Java [игнор отключен] [закрыт для гостей] / JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
11 сообщений из 11, страница 1 из 1
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39845913
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день

Столкнулся с проблемой, при реализации на Primefaces с версиями <jsf.version>2.2.8</jsf.version> <primefaces.version>3.0</primefaces.version> динамического добавления и удаления компонентов inputTextarea с редактированием внутри них значений

В итоге удалось реализовать более менее работающий макет, но столкнулся с трудностью- при редактировании значения - если тут же не убирая фокус добавить новый элемент - подтягивается предыдущее нередактированное значения. Приложил скрин с описанием проблемы

Создал репо, в котором текущий код можно легко запустить используя mvn clean install run:jetty
https://github.com/aradess/jsf-jetty-dyn

Собственно вопрос, - каким должен быть код, чтобы редактирования и последующая вставка нового значения проходила корректно?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

<h:head>
    <title>PrimeFaces Hello World Example</title>
</h:head>

<h:body>
    <h:form>
        <p:panel id="main">
            <h:panelGrid columns="2">
                <h:outputText value="Add value"
                              style="vertical-align: top; width: 200px;"/>
                <p:selectOneMenu
                        widgetVar="type" id="type"
                        style="width: 350px"
                        value="#{helloWorld.selectedType}">
                    <f:selectItem itemValue="#{null}" itemLabel=""/>
                    <f:selectItems value="#{helloWorld.availableFields}" var="def" itemLabel="#{def}" itemValue="#{def}"/>
                    <p:ajax event="change"
                            update="main"
                            listener="#{helloWorld.change(helloWorld.selectedType)}"/>/>
                </p:selectOneMenu>
            </h:panelGrid>
            <h:panelGroup id="panelRepeatWrapper">
                <c:forEach id="panelRepeat" items="#{helloWorld.selectedFields}" var="field">
                    <h:panelGrid columns="3">
                        <h:outputText value="#{field}"
                                      style="vertical-align: top; width: 200px;"/>
                        <h:inputTextarea value="#{helloWorld.values[field]}"
                                         style="width: 550px; height: 50px;"/>
                        <p:commandButton value="x" action="#{helloWorld.onDelete(field)}" update="main">
                        </p:commandButton>
                    </h:panelGrid>
                </c:forEach>
            </h:panelGroup>
        </p:panel>
    </h:form>
</h:body>
</html>



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
package groupid;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@ManagedBean
@SessionScoped
public class HelloWorld {
    private final static List<String> ENTITIES = Arrays.asList(new String[]{"1", "2", "3", "4", "5"});

    @PostConstruct
    public void init() {
        selectedFields = ENTITIES.stream().filter(s -> !"5".equals(s)).collect(Collectors.toSet());
        availableFields = ENTITIES.stream().filter(s -> "5".equals(s)).collect(Collectors.toSet());
        values.put("1", "1");
        values.put("2", "2");
        values.put("3", "3");
        values.put("4", "4");
    }

    private String selectedType = "";
    private Set<String> availableFields;
    private Set<String> selectedFields;
    private Map<String, String> values = new HashMap<String, String>();

    public Set<String> getAvailableFields() {
        return availableFields;
    }

    public void setAvailableFields(Set<String> availableFields) {
        this.availableFields = availableFields;
    }

    public Set<String> getSelectedFields() {
        return selectedFields;
    }

    public void setSelectedFields(Set<String> selectedFields) {
        this.selectedFields = selectedFields;
    }

    public Map<String, String> getValues() {
        return values;
    }

    public void setValues(Map<String, String> values) {
        this.values = values;
    }

    public void change(String type) {
        Optional<String> f = availableFields.stream().filter(s -> s.equals(type)).findFirst();
        selectedFields.add(f.get());
        availableFields.remove(f.get());
        values.put(f.get(), null);
    }

    public void onDelete(String type) {
        Optional<String> f = selectedFields.stream().filter(s -> s.equals(type)).findFirst();
        selectedFields.remove(f.get());
        availableFields.add(f.get());
        values.put(f.get(), null);
    }

    public String getSelectedType() {
        return selectedType;
    }

    public void setSelectedType(String selectedType) {
        this.selectedType = selectedType;
    }
}
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39845914
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробуй ui:repeat из facelets вместо c:forEach из jstl. Но я сильно не вчитывался, просто знаю что c:orEach хреновенько работает с динамически добавляемыми элементами
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39845918
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JSTL по моему вообще не работает и вмести с JSF их лучше не использовать
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39845978
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никпопробуй ui:repeat из facelets вместо c:forEach из jstl. Но я сильно не вчитывался, просто знаю что c:orEach хреновенько работает с динамически добавляемыми элементами

пробовал ui:repeat - работоспособного варианта не получилось, то есть с c:forEach удалось продвинуться дальше, но попробую
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39845982
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vas0,

совет по использованию JSTL был найден на stackoverflow, в то же время там была найден пост о различиях https://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense

Проблема в том, что я практически не работал ранее с JSF и не хотелось бы собирать все его грабли
Потому и прошу совета
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39846406
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал ui:repeat
https://github.com/aradess/jsf-jetty-dyn/blob/feature/repeat/src/main/webapp/helloworld.xhtml
https://github.com/aradess/jsf-jetty-dyn/blob/feature/repeat/src/main/java/groupid/HelloWorld.java

Как бы работает, но это не то что нужно. Это все реализовано через события вида onclick=submit() - но это приводит к ререндерингу всей формы. А реальный кейс, в котором используется данная функциональность - сложнее, и ререндеринг в нем лишний.

Попробую уточнить загвоздку, которую нужно решить, которая есть в следующем коде:

Нужно чтобы при выборе значения в selectOneMenu и соответственно запуска в ajax listener="#{helloWorld.change(helloWorld.selectedType)}"/> , чтобы перед запуском этого listener значения которые введены в h:inputTextarea были синхронизированы с helloWorld.values[field]

Потому что сейчас наблюдается ситуация:
1) Ввели значение в Поле 3 (и это никак не отобразилось на значениях в helloWorld.values)
2) Выбрали добавление элемента из выпадающего списка
3) Обновили элемент c id="main" значениями которые в helloWorld.values (а они устаревшие)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

<h:head>
    <title>PrimeFaces Hello World Example</title>
</h:head>

<h:body>
    <h:form>
        <p:panel id="main">
            <h:panelGrid columns="2">
                <h:outputText value="Add value"
                              style="vertical-align: top; width: 200px;"/>
                <p:selectOneMenu
                        widgetVar="type" id="type"
                        style="width: 350px"
                        value="#{helloWorld.selectedType}">
                    <f:selectItem itemValue="#{null}" itemLabel=""/>
                    <f:selectItems value="#{helloWorld.availableFields}" var="def" itemLabel="#{def}" itemValue="#{def}"/>
                    <p:ajax event="change"
                            update="main"
                            listener="#{helloWorld.change(helloWorld.selectedType)}"/>/>
                </p:selectOneMenu>
            </h:panelGrid>
            <h:panelGroup id="panelRepeatWrapper">
                <c:forEach id="panelRepeat" items="#{helloWorld.selectedFields}" var="field">
                    <h:panelGrid columns="3">
                        <h:outputText value="#{field}"
                                      style="vertical-align: top; width: 200px;"/>
                        <h:inputTextarea value="#{helloWorld.values[field]}"
                                         style="width: 550px; height: 50px;"/>
                        <p:commandButton value="x" action="#{helloWorld.onDelete(field)}" update="main">
                        </p:commandButton>
                    </h:panelGrid>
                </c:forEach>
            </h:panelGroup>
        </p:panel>
    </h:form>
</h:body>
</html>
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39846596
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AghialНужно чтобы при выборе значения в selectOneMenu и соответственно запуска в ajax listener="#{helloWorld.change(helloWorld.selectedType)}"/> , чтобы перед запуском этого listener значения которые введены в h:inputTextarea были синхронизированы с helloWorld.values[field]


Давно не трогал JSF, но вдруг угадаю.
Добавить у p:ajax атрибут process="main" не пробовали? Вроде по умолчанию процессится только компонент, в котором расположен этот p:ajax.
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39852397
olegeos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что такая старая версия primefaces?
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39852423
olegeos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
 
            <p:panel id="main2">
                <h:panelGrid  columns="2">
                    <h:outputText value="Add value"
                                  style="vertical-align: top; width: 200px;"/>
                    <p:selectOneMenu 
                        widgetVar="type" id="type2"
                        style="width: 350px"
                        value="#{helloWorld.selectedType}">
                        <f:selectItem  itemLabel=""/>
                        <f:selectItems value="#{helloWorld.availableFields}" var="def" itemLabel="#{def}" itemValue="#{def}"/>
                        <p:ajax event="change"
                                update="main2"
                             listener="#{helloWorld.change2()}"/>/>
                    </p:selectOneMenu>
                </h:panelGrid>
                <p:panel id="panelRepeatWrapper2">

                    <ui:repeat id="panelRepeat1" value="#{helloWorld.listTextArea}" var="field" >
                        <h:panelGrid columns="4">
                            <h:outputText value="#{field.nomerRow}"
                                          style="vertical-align: top; width: 200px;"/>
                            <h:inputTextarea value="#{field.area}"
                                             style="width: 550px; height: 50px;"/>
                            <p:commandButton id="button1" value="x" actionListener="#{helloWorld.onDelete2(field)}"  update="form1:panelRepeatWrapper2"  />
                            <p:message  for="button1" showDetail="true" showSummary="true"/>
                        </h:panelGrid>

                    </ui:repeat>

                </p:panel>
            </p:panel>



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
public class HelloWorld {

    private final static List<String> ENTITIES = Arrays.asList(new String[]{"1", "2", "3", "4", "5"});

    private final String[] array = new String[]{"1", "2", "3", "4", "5"};
    private List<TestList> listTextArea;

    @PostConstruct
    public void init() {
        selectedFields = ENTITIES.stream().filter(s -> !"5".equals(s)).collect(Collectors.toSet());
        availableFields = ENTITIES.stream().filter(s -> "5".equals(s)).collect(Collectors.toSet());
        values.put("1", "1");
        values.put("2", "2");
        values.put("3", "3");
        values.put("4", "4");
        //----------
        listTextArea = new ArrayList<>();

    }

    private String selectedType = "";
    private Set<String> availableFields;
    private Set<String> selectedFields;
    private Map<String, String> values = new HashMap<>();

    public Set<String> getAvailableFields() {
        return availableFields;
    }

    public void setAvailableFields(Set<String> availableFields) {
        this.availableFields = availableFields;
    }

    public Set<String> getSelectedFields() {
        return selectedFields;
    }

    public void setSelectedFields(Set<String> selectedFields) {
        this.selectedFields = selectedFields;
    }

    public Map<String, String> getValues() {
        return values;
    }

    public void setValues(Map<String, String> values) {
        this.values = values;
    }

    public void change(String type) {
        Optional<String> f = availableFields.stream().filter(s -> s.equals(type)).findFirst();
        selectedFields.add(f.get());
        availableFields.remove(f.get());
        values.put(f.get(), null);
    }

    public void onDelete(String type) {
        Optional<String> f = selectedFields.stream().filter(s -> s.equals(type)).findFirst();
        selectedFields.remove(f.get());
        availableFields.add(f.get());
        values.put(f.get(), null);
    }

    public void change2() {
        TestList ttt = new TestList();
        ttt.setNomerRow("1");
        ttt.setArea(selectedType);
        listTextArea.add(ttt);
    }

    public void onDelete2(TestList test) {
        if (!listTextArea.isEmpty()) {
            listTextArea.remove(test);
            System.out.println(listTextArea.size());
        }
    }

    public String getSelectedType() {
        return selectedType;
    }

    public void setSelectedType(String selectedType) {
        this.selectedType = selectedType;
    }

    public List<TestList> getListTextArea() {
        return listTextArea;
    }

    public void setListTextArea(List<TestList> listTextArea) {
        this.listTextArea = listTextArea;
    }


такой вариант
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39853611
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
olegeosА что такая старая версия primefaces?

Прощу прощения за столь поздний ответ.
Потому что это суровый legacy с кучей функциональности и без тестов. Поменять версию компонентов нереально
...
Рейтинг: 0 / 0
JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
    #39853616
Aghial
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
olegeosтакой вариант

К сожалению у меня не взлетел. Были ошибки компиляции, исправил их, выложил код
https://github.com/aradess/jsf-jetty-dyn/blob/feature/2/src/main/webapp/helloworld.xhtml
По-прежнему была трабла:
1) Ввели новое значение в Поле 3 (и это никак не отобразилось на значениях в helloWorld.values)
2) Выбрали добавление элемента из выпадающего списка
3) После автоматического обновления значение в Поле 3 - старое, до редактирования

Нашел, путем неоднократного гугления по разным запросам следующий пост
https://stackoverflow.com/a/30216301

Предлагается использовать ajax и перехватывать значения в bean непосредственно из AjaxBehaviorEvent, и синхронизировать значение мапы в bean со значением, которое на экране
Вроде бы заработало, буду смотреть дальше

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
    public void fieldValue(AjaxBehaviorEvent e) {
        if (e.getSource() instanceof UIInput) {
            UIInput input = (UIInput) e.getSource();
            Object value = input.getValue();
            String id = input.getId();
            values.put(id.substring(2), value.toString());
        }
    }


https://github.com/aradess/jsf-jetty-dyn/tree/feature/AjaxBehaviorEvent
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / JSF, PrimeFaces - динамическое добавление, редактирование и удаление элементов
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]