How to get filtered data from table to List

Version 2

    From original thread:

    Hi All,

     

    I have a problem. I have a rich:extendedDataTable and i need to send the filtered datas to one List (this List will be used in a Report). Can help me please? I have no idea to do this. Thanks.

     

    The problem exist only if you not implementing the model but just passing the list. When it became wrapped in our models and sorted/filtered - there is no way to get actual sublist except getting the wrapped model and walking by it.

     

    Proposals:

     

    Currently I'm writing such simple sample and here is my code:

    NOTE: written under RF 4 and for DataTable so changes could be needed for 3.3 and EDT

     

        <h:form id="form">

     

            <r:messages />
            <rich:dataTable value="#{carsBean.allInventoryItems}" var="car"
                id="table" rows="30">
                <f:facet name="noData">
                    Nothing found
                </f:facet>
                <rich:column filterValue="#{carsFilteringBean.vendorFilter}"
                    filterExpression="#{fn:containsIgnoreCase(car.vendor, carsFilteringBean.vendorFilter)}">
                    <f:facet name="header">
                        <h:panelGroup>
                            <h:outputText value="Vendor " />
                            <h:selectOneMenu value="#{carsFilteringBean.vendorFilter}">
                                <f:selectItems value="#{carsBean.vendorOptions}" />
                                <a4j:ajax render="table" execute="@this" event="change" />
                            </h:selectOneMenu>
                        </h:panelGroup>
                    </f:facet>
                    <h:outputText value="#{car.vendor}" />
                </rich:column>
                <rich:column>
                    <f:facet name="header">
                        <h:outputText value="Model" />
                    </f:facet>
                    <h:outputText value="#{car.model}" />
                </rich:column>
                <rich:column>
                    <f:facet name="header">
                        <h:outputText value="Price" />
                    </f:facet>
                    <h:outputText value="#{car.price}" />
                </rich:column>
                <rich:column filter="#{carsFilteringBean.mileageFilterImpl}">
                    <f:facet name="header">
                        <h:panelGroup>
                            <h:outputText value="Mileage &lt; " />
                            <h:inputText value="#{carsFilteringBean.mileageFilter}">
                                <f:convertNumber groupingUsed="true" />
                                <f:validateLongRange maximum="500000" />
                                <a4j:ajax event="blur" render="form:table" execute="@this" />
                            </h:inputText>
                        </h:panelGroup>
                    </f:facet>
                    <h:outputText value="#{car.mileage}" />
                </rich:column>
                <rich:column filterValue="#{carsFilteringBean.vinFilter}"
                    filterExpression="#{fn:containsIgnoreCase(car.vin,carsFilteringBean.vinFilter)}">
                    <f:facet name="header">
                        <h:panelGroup>
                            <h:outputText value="VIN " />
                            <h:inputText value="#{carsFilteringBean.vinFilter}">
                                <a4j:ajax event="blur" render="table" execute="@this" />
                            </h:inputText>
                        </h:panelGroup>
                    </f:facet>
                    <h:outputText value="#{car.vin}" />
                </rich:column>
            </rich:dataTable>
            <a4j:commandButton action="#{carsBean.fetchFilteredData}"
                render="outt">
                <a4j:param value="#{rich:clientId('table')}" name="currentTableId"/>
            </a4j:commandButton>
            <rich:dataTable value="#{carsBean.selectedItems}" var="car" id="outt">
                <rich:column>
                    #{car.mileage}
                </rich:column>       
            </rich:dataTable>
        </h:form>

     

     

    and bean


     

        public void fetchFilteredData(){

     

            FacesContext fc = FacesContext.getCurrentInstance();
            String tableId = fc.getExternalContext().getRequestParameterMap().get("currentTableId");
            UIDataTable table = (UIDataTable)fc.getViewRoot().findComponent(tableId);
            if (selectedItems == null){
                selectedItems = new ArrayList<InventoryItem>();
            }else{
                selectedItems.clear();
            }
            table.walk(fc, new DataVisitor() {
            
                public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {
                    selectedItems.add(allInventoryItems.get((Integer)rowKey));
                    return DataVisitResult.CONTINUE;
                }
            }, null);
        }

        public void fetchFilteredData(){

            FacesContext fc = FacesContext.getCurrentInstance();

            String tableId = fc.getExternalContext().getRequestParameterMap().get("currentTableId");

            UIDataTable table = (UIDataTable)fc.getViewRoot().findComponent(tableId);

            if (selectedItems == null){

                selectedItems = new ArrayList<InventoryItem>();

            }else{

                selectedItems.clear();

            }

            table.walk(fc, new DataVisitor() {

     

                public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {

                    selectedItems.add(allInventoryItems.get((Integer)rowKey));

                    return DataVisitResult.CONTINUE;

                }

            }, null);

        }

     

    But I would not recommend that way. It's much more simpler to wrap the list top the model like done at 3.3.x demo:

     

    package org.richfaces.demo.extendedDataTable;

     

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

     

    import org.richfaces.demo.capitals.Capital;

    import org.richfaces.model.DataProvider;

    import org.richfaces.model.ExtendedTableDataModel;

    import org.richfaces.model.selection.Selection;

    import org.richfaces.model.selection.SimpleSelection;

     

    public class ExtendedTableBean {

        private String sortMode = "single";

        private String selectionMode = "multi";

        private Object tableState;

        private Selection selection;

        private List<Capital> capitals = new ArrayList<Capital>();

        private ExtendedTableDataModel<Capital> dataModel;

        private List<Capital> selectedCapitals = new ArrayList<Capital>();

     

        public String getSortMode() {

            return sortMode;

        }

     

        public void setSortMode(String sortMode) {

            this.sortMode = sortMode;

        }

     

        public String getSelectionMode() {

            return selectionMode;

        }

     

        public void setSelectionMode(String selectionMode) {

            this.selectionMode = selectionMode;

        }

     

        public void takeSelection() {

            selectedCapitals.clear();

            Iterator<Object> iterator = getSelection().getKeys();

            while (iterator.hasNext()) {

                Object key = iterator.next();

                selectedCapitals.add(getCapitalsDataModel().getObjectByKey(key));

            }

        }

     

        public ExtendedTableDataModel<Capital> getCapitalsDataModel() {

            if (dataModel == null) {

                dataModel = new ExtendedTableDataModel<Capital>(new DataProvider<Capital>() {

     

                    private static final long serialVersionUID = 5054087821033164847L;

     

                    public Capital getItemByKey(Object key) {

                        for (Capital c : capitals) {

                            if (key.equals(getKey(c))) {

                                return c;

                            }

                        }

                        return null;

                    }

     

                    public List<Capital> getItemsByRange(int firstRow, int endRow) {

                        return capitals.subList(firstRow, endRow);

                    }

     

                    public Object getKey(Capital item) {

                        return item.getName();

                    }

     

                    public int getRowCount() {

                        return capitals.size();

                    }

     

                });

            }

            return dataModel;

        }

     

        public void setCapitals(List<Capital> capitals) {

            this.capitals = capitals;

        }

     

        public Object getTableState() {

            return tableState;

        }

     

        public void setTableState(Object tableState) {

            this.tableState = tableState;

        }

     

        public Selection getSelection() {

            if (selection==null){

                selection = new SimpleSelection();

                ((SimpleSelection)selection).addKey(capitals.get(0).getName());

            }

            return selection;

        }

     

        public void setSelection(Selection selection) {

            this.selection = selection;

        }

     

        public List<Capital> getSelectedCapitals() {

            return selectedCapitals;

        }

     

        public void setSelectedCapitals(List<Capital> selectedCapitals) {

            this.selectedCapitals = selectedCapitals;

        }

     

    }

     

     

    then you will not need to seek for component but could just get that dataModel and call walk directly on it.

     

    This document was generated from the following discussion: How to send filtered datas from extendDataTable to List