Проблема с фильтрацией Primefaces Datatable для раскрывающегося списка при вводе данных - PullRequest
0 голосов
/ 04 августа 2020

У меня есть раскрывающийся список (p: selectOneMenu) в качестве поля ввода в строке данных Primefaces 8.0, после того как я выберу значение в раскрывающемся списке, если я отсортирую его, выбранное значение может быть сохранено после ajax submit. Однако, если я ввожу фильтр, который фильтрует 0 строк, а затем очищаю фильтр, выбранное значение в раскрывающемся списке исчезает:

обновленная база на запросе Кукельтье на добавление входного текста:

  1. Выберите значение раскрывающегося списка

enter image description here

  1. введите фильтр, чтобы все строки были отфильтрованы

enter image description here

  1. очистить фильтр, выбранное значение исчезнет

enter image description here

My backing bean:

package sample;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class SampleBean implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 5307652891294044974L;

    private static final Map dropDown = new HashMap<>();
    
    static {
        dropDown.put("K1", "K1");
        dropDown.put("K2", "K2");
        dropDown.put("K3", "K3");
    }

    public Map getDropDown() {
        return dropDown;
    }

    private List tableObjects = Arrays.asList(new TableObject[] {new TableObject(), new TableObject()});
    
    public List getTableObjects() {
        return tableObjects;
    }

    public void setTableObjects(List tableObjects) {
        this.tableObjects = tableObjects;
    }

    public static class TableObject 
    {
        private String dd;
        private String inputText;

        public String getDd() {
            return dd;
        }

        public void setDd(String dd) {
            this.dd = dd;
        }

        public String getInputText() {
            return inputText;
        }

        public void setInputText(String inputText) {
            this.inputText = inputText;
        }
        
    }
}

My facelet:

 Привет, мир JSF 2.3   

Я sh мой тестовый проект на github, если вы хотите его протестировать

git clone https://github.com/saycchai/jsf-test.git
cd jsf-test
chmod +x *.sh
./buildAndRun.sh

для сервера payara: просмотрите: http://localhost: 8080 /index.xhtml

для другого сервера: http://localhost: 8080 / jsf-test / index.x html

1 Ответ

0 голосов
/ 06 августа 2020
• 1000 установите значение Dd на previousDd перед фазой APPLY_REQUEST_VALUES и установите значение резервной копии previousDd обратно на Dd перед фазой RENDER_RESPONSE, введите следующий код:

Backing Bean

package sample;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.Transient;

@Named
@SessionScoped
public class SampleBean implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 5307652891294044974L;

    private static final Map<String, String> dropDown = new HashMap<>();
    
    static {
        for(int i=1; i<10; i++) {
            dropDown.put("K"+i, "K"+i);
        }
    }

    public Map<String, String> getDropDown() {
        return dropDown;
    }

    private List<TableObject> tableObjects = Arrays.asList(new TableObject[] {new TableObject(), new TableObject(), new TableObject(), new TableObject()});
    
    public List<TableObject> getTableObjects() {
        return tableObjects;
    }

    public void setTableObjects(List<TableObject> tableObjects) {
        this.tableObjects = tableObjects;
    }

    public static class TableObject 
    {
        private String dd;
        private String inputText;

        public String getDd() {
            return dd;
        }

        public void setDd(String dd) {
            this.dd = dd;
        }

        public String getInputText() {
            return inputText;
        }

        public void setInputText(String inputText) {
            this.inputText = inputText;
        }
        
        @Transient
        private String previousDd;
        
        public String getPreviousDd() {
            return previousDd;
        }

        public void setPreviousDd(String previousDd) {
            this.previousDd = previousDd;
        }

    }
}

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"
    xmlns:p="http://primefaces.org/ui" 
>

<h:head>
    <title>Hello World JSF 2.3</title>
</h:head>

<h:body>
    <h:form id="form">
        <p:dataTable id="itemTable" var="item" value="#{sampleBean.tableObjects}"
            widgetVar="itemTable"
            paginator="true"
        >

            <p:ajax event="sort" process="@this" update="@this"
                skipChildren="false" />
            <p:ajax event="page" process="@this" update="@this"
                skipChildren="false"
            />
            <p:ajax event="filter" process="@this" update="@this" global="false"
                skipChildren="false" 
                onstart="cfg.ext.params.push({name: 'tableFilterCount', value: PF('itemTable').paginator.cfg.rowCount});"
            />

            <p:column id="DropdownHeader" headerText="Dropdown" sortBy="#{item.dd}"
                filterBy="#{item.dd}" filterMatchMode="contains">
                <p:selectOneMenu id="Dropdown" value="#{item.dd}" required="false"
                    label="Dropdown" style="width: 90%">
                    
                    <f:selectItem itemValue="#{null}" itemLabel="" />
                    <f:selectItems value="#{sampleBean.dropDown.entrySet()}"
                        var="entry" itemValue="#{entry.value}" itemLabel="#{entry.key}" />
                </p:selectOneMenu>
            </p:column>
            <p:column id="InputTextHeader" headerText="Input Text"
                sortBy="#{item.inputText}" filterBy="#{item.inputText}"
                filterMatchMode="contains">
                <p:inputText id="InputText" value="#{item.inputText}" >
                    <p:ajax />
                </p:inputText>
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

Phase Listener

package sample;

import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

import org.primefaces.component.datatable.DataTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sample.SampleBean.TableObject;

public class SamplePhaseListener implements PhaseListener {

    /**
     * 
     */
    private static final long serialVersionUID = 5273254619684337785L;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public void afterPhase(PhaseEvent event) {
        
    }

    public void beforePhase(PhaseEvent event) {
        
        if(event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES) {
            
            prettyPrint("----------------start of Before "+event.getPhaseId().getName()+"------------------------------", 0);
            
            String tableFilterCount = event.getFacesContext().getExternalContext().getRequestParameterMap().get("tableFilterCount");
            
            if(tableFilterCount != null && "0".equals(tableFilterCount)) {
                //backup the previous value first
                DataTable table = (DataTable) event.getFacesContext().getViewRoot().findComponent("form:itemTable");
                for (int index = 0; index < table.getRowCount(); index++) {
                    table.setRowIndex(index);

                    Object rowData = table.getRowData();

                    if(rowData != null) {
                        TableObject tableObject = (TableObject) rowData;
                        logger.info(" before backup to previousDd, dd: {}, previousDd: {}", tableObject.getDd(), tableObject.getPreviousDd());

                        tableObject.setPreviousDd(tableObject.getDd());
                        
                        logger.info(" after backup to previousDd, dd: {}, previousDd: {}", tableObject.getDd(), tableObject.getPreviousDd());
                    }
                    
                }
            }
            
            prettyPrint("----------------end of Before "+event.getPhaseId().getName()+"------------------------------", 0);
        }
        
        
        if(event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
            
            prettyPrint("----------------start of Before " + event.getPhaseId().getName() + "------------------------------", 0);
            
            String tableFilterCount = event.getFacesContext().getExternalContext().getRequestParameterMap().get("tableFilterCount");
            
            if(tableFilterCount != null && "0".equals(tableFilterCount)) {
                //restore the Dd from previous value
                DataTable table = (DataTable) event.getFacesContext().getViewRoot().findComponent("form:itemTable");
                for (int index = 0; index < table.getRowCount(); index++) {
                    table.setRowIndex(index);

                    Object rowData = table.getRowData();

                    if(rowData != null) {
                        TableObject tableObject = (TableObject) rowData;
                        logger.info(" before restore from previousDd, dd: {}, previousDd: {}", tableObject.getDd(), tableObject.getPreviousDd());

                        tableObject.setDd(tableObject.getPreviousDd());

                        logger.info(" after restore from previousDd, dd: {}, previousDd: {}", tableObject.getDd(), tableObject.getPreviousDd());
                    }
                    
                }
            }
            
            
            prettyPrint("----------------end of Before "+event.getPhaseId().getName()+"------------------------------", 0);
        }
    }

    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }

    public static final String IDENT = "  ";

    private void prettyPrint(String str, int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++)
            sb.append(IDENT);

        sb.append(str + "\n");

        logger.trace(sb.toString());
    }
}

faces-config. xml


<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
    version="2.3">

    <lifecycle>
        <phase-listener>sample.SamplePhaseListener</phase-listener>
    </lifecycle>
    
</faces-config>

...