1 2 Previous Next 21 Replies Latest reply: May 19, 2011 3:47 AM by Aymen HAJ RSS

How to send filtered datas from extendDataTable to List

Carlos Leite Newbie

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.

  • 1. Re: How to send filtered datas from extendDataTable to List
    Carlos Leite Newbie

    somebody? I really need this.

  • 2. Re: How to send filtered datas from extendDataTable to List
    Ilya Shaikovsky Master

    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

     

        <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.

  • 4. Re: How to send filtered datas from extendDataTable to List
    Carlos Leite Newbie

    Thanks Ilya, my extendedDataTable was populated with a list. Now, i implements your code, with dataModel, but i can't to get the filtered data from extendedDataTable. Im using implicit filter. Look my code and help me please:

     

    my bean:

     

        private List<Historico> historicos = new ArrayList<Historico>();
        private ExtendedTableDataModel<Historico> dataModel;

     

     

     

        public ExtendedTableDataModel<Historico> getHistoricoDataModel() {
            if (dataModel == null) {
                dataModel = new ExtendedTableDataModel<Historico>(new DataProvider<Historico>() {

     


                    public Historico getItemByKey(Object key) {
                        for (Historico c : getTodoHistorico()) {
                            if (key.equals(getKey(c))) {
                                return c;
                            }
                        }
                        return null;
                    }

     

                    public List<Historico> getItemsByRange(int firstRow, int endRow) {
                        return getTodoHistorico().subList(firstRow, endRow);
                    }

     

                    public Object getKey(Historico item) {
                        return item.getId();

     

                    }

     

                    public int getRowCount() {
                        return getTodoHistorico().size();

     

                    }

     

    my page:

     

    <rich:extendedDataTable
                                style="text-align:center;margin 0 auto;"
                                onRowMouseOut="this.style.backgroundColor='#FFFFFF'"
                                onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
                                id="tabelaHistorico"
                                value="#{MBHistorico.historicoDataModel}"
                                rows="60"
                                width="400"
                                var="item">
                                <f:facet name="header">
                                    <rich:datascroller align="left" for="tabelaHistorico" maxPages="100" id="sc1" />
                                </f:facet>
                                <rich:column sortable="true" sortBy="#{item.numeroMaquina}" width="70px"
                                             filterBy="#{item.numeroMaquina}" filterEvent="onkeyup"
                                             label="Nº Máq.">
                                    <f:facet name="header">
                                        <h:outputText value="NºMáq."/>
                                    </f:facet>
                                    <h:outputText value="#{item.numeroMaquina}"/>
                                </rich:column>
    ..
    ..
    more columns and the end.

  • 5. Re: How to send filtered datas from extendDataTable to List
    Carlos Leite Newbie

    How i can to get the filtered data and add in a list?

  • 6. Re: How to send filtered datas from extendDataTable to List
    Carlos Leite Newbie

    and more...  I tried the metod getItemsByRange, but he return all data of the table and ignore the filter.

  • 7. Re: How to send filtered datas from extendDataTable to List
    Almar Newbie

    Hi Guys,

     

    I found an alternative solution (using RichFaces 3.3.3).

     

    I’m sorry to say that I couldn’t get Ilya’s solution (creating my own ExtendedTableDataModel) to work. Whatever I tried, I always got the unfiltered/unsorted data. After a while I found the following solution.

     

    Add an UIDataTable to your managed bean and ‘bind’  the dataTable to it (hint use binding parameter of dataTable). Now you can get your filtered/sorted data with the following code:

     

     

    public List<MyDataObj> getFilteredData() throws IOException {
         final List<MyDataObj> filteredData = new ArrayList<MyDataObj>();
    
         getUiDataTable().walk(FacesContext.getCurrentInstance(), new DataVisitor() {     
              public void process(FacesContext context, Object rowKey, Object argument) {
                   UIDataTable table = (UIDataTable) argument;
                   table.setRowIndex((Integer)rowKey);
                   MyDataObj obj = (MyDataObj) table.getRowData();     
                   filteredData.add(obj);
              }
         }, getUiDataTable());
    
         return filteredData;
    }
    

     

     

    ~ Almar

  • 8. Re: How to send filtered datas from extendDataTable to List
    Almar Newbie

    Oke, so the above solution doesnot work if you also use a datascroller with your table. When using the above solution in combination with a datascroller you’ll only get the data that is displayed.

     

     

    I looked at the suggestion of Ilya again and found out what went wrong (RichFaces 3.3.3). You need a reference to the ModifiableModel instead of the ExtendedTableDataModel.

     

     

    Creating data model:

     

    public ModifiableModel getDataModel() {
         if (this.DataModel == null) {
              ExtendedTableDataModel<MyDataObj> model = new ExtendedTableDataModel<MyDataObj>(new DataProvider<MyDataObj>() {
                   private static final long serialVersionUID = 5054087821033164847L;
    
                   public MyDataObj getItemByKey(Object key) {
                        for (MyDataObj c : MyManagedBean.this.data) {
                             if (key.equals(getKey(c))) {
                                  return c;
                             }
                        }
                        return null;
                   }
    
                   public List<MyDataObj> getItemsByRange(int firstRow, int endRow) {
                        return MyManagedBean.this.data.subList(firstRow, endRow);
                   }
    
                   public Object getKey(MyDataObj item) {
                        return item.getId();
                   }
    
                   public int getRowCount() {
                        return MyManagedBean.this.data.size();
                   }
              });
    
              this.dataModel = new ModifiableModel(model, "row");
         }
    
         return this.dataModel;
    }
    
    

     

    Retrieving filtered data:

     

    public List<MyDataObj> getFilteredData() throws IOException {
              final List<MyDataObj> filteredData = new ArrayList<MyDataObj>();
              final ModifiableModel model = getDataModel();
    
              getDataModel().walk(FacesContext.getCurrentInstance(), new DataVisitor() {
                        public void process(FacesContext context, Object rowKey, Object argument) {
                                  model.setRowIndex((Integer)rowKey);
                                  filteredData.add((MyDataObj) model.getRowData());
                        }
              }, new SequenceRange(0, -1), null); 
    
              return filteredData;
    }
    
    

     

    ~ Almar

  • 9. Re: How to send filtered datas from extendDataTable to List
    Carlos Leite Newbie

    Almar, thanks for response. My project was waiting for this and i think finally will continues. I'll test this solution in weekend, and after i post the result in this thread.

  • 10. Re: How to send filtered datas from extendDataTable to List
    liumin hu Master

    hi,

     

    i have a solution similaire. But i have one question : in your code

     

       this.dataModel = new ModifiableModel(model, "row");

    Do you need var attribute of your datatable be the same?

     

    liu

  • 11. Re: How to send filtered datas from extendDataTable to List
    Almar Newbie

    Hi Liumin hu,

     

    Yes, the var attribute of the datatable should have the same value as profided in the ModifiableModel constructor. If they are not the same, filtering and sorting on the table won't work anymore.

     

    Moreover, I discovered my solution by looking at UIDataTable.java. If you provide a datamodel that doesnot implement Modifiable, the dataModel is wrapped in a ModifiableModel as follows:

     

    ModifiableModel modifiableModel = new ModifiableModel(dataModel, getVar());

     

     

    So, normally the var property of the ModifiableModel will always be the same as that of the datatable.

     

    ~ Almar

  • 12. How to send filtered datas from extendDataTable to List
    Aymen HAJ Newbie

    Hi Almar,

     

    I didn't understand how to use your soltuion(if I have to bind my extendedDataTable to the datatmodel or something else).

     

    I tried it but every time I got an empty filtered list.

     

    Could you please explain me more . For information, I'm using richfaces 3.3.2.

     

    Thanks,

     

    Aymen

  • 13. How to send filtered datas from extendDataTable to List
    Almar Newbie

    Hi Aymen,

     

    Make sure you use the getDataModel() method as the value of your rich:dataTable. Also make sure that your var attribute is "row".

     

    <rich:dataTable value="#{managedBean.getDataModel()}" var="row" ....

     

    ~ Almar

  • 14. How to send filtered datas from extendDataTable to List
    Aymen HAJ Newbie

    Hi,

     

    Using #{managedBean.getDataModel()} as a value for rich:extendedDataTable didn't work, so I used <rich:extendedDataTable value="#{managedBean.dataModel}" instead, but the problem is that shown data is incorrect, it looks like the same row is repeated all over the table.

     

    Regards,

     

    Aymen.

1 2 Previous Next