0

I use a JSF 2.2, a Primefaces 6.0 and a CDI. I've got a datatable which has implemented lazy loading (the datatable downloads the data from the database). Each column has got a filter field.

One of the column has to have readonly filter field (I save a value for this filter in some variable before displaying the datatable). So, as I wrote, this filter field should be readonly (non-editable) and the filter should take the value from this field into filtering. How can I achieve this feature?

I tried to add the inputtext component and set the readonly attribute:

<p:dataTable id="dataTableOfDataStore" var="obj" widgetVar="dataTableOfDataStoreVar" 
            value="#{formVisualizationController.dataTableLazy}"             
            lazy="true"
            filteredValue="#{formVisualizationController.filteredDataTable}" 
            filterDelay="2000"

            <!-- other attributes -->                       
            >

    <!-- other columns -->

    <p:column headerText="Source IP" sortBy="#{obj.sip}"
            filterBy="#{obj.sip}" filterMatchMode="contains">
        <f:facet name="filter">
            <p:inputText readonly="true" onchange="PF('dataTableOfDataStoreVar').filter()"
             value="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}"
            style="width: 100%; background-color: #0088cc; color: #ffffff;"/>
        </f:facet>          
        <h:outputText value="#{obj.sip}" />     
    </p:column> 

    <!-- other columns -->

</p:dataTable>

Unfortunately it doesn't work. When I delete the readonly attribute, it works, but then the filter field is editable as well.

Of course, I can achieve this by manually pass on this value to the database query and then delete the filter from the column and keep the inputtext component with the value (and with readonly attribute), but maybe you know some different way to achieve this.

Robert
  • 762
  • 2
  • 10
  • 23

3 Answers3

1

This answer explains why readonly fields are not included in a request. Therefore Primefaces does not use it to filter.

In my opinion you will have to override/check it anyways on serverside if you want to ensure that it has not been tampered with. Therefore setting it programatically seems to be the best solution.

You can do this either in your query or by adding the filter value programatically. For example you could override the load method to use the value from your bean if it is mandatory.

dataTableLazy = new LazyDataModel<?>(){
    public List<Site> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        //set your filter here
        super.load(first, pageSize, sortField, sortorder, filters);
    }
}
Community
  • 1
  • 1
Abaddon666
  • 1,533
  • 15
  • 31
  • Thanks for your feedback. I've modified my `load` method and I've put my value (for `Source IP` column) into the `filters` parameter of the `load` method. It seems that is the best idea. Thanks! I've also added answer which includes steps which I did. – Robert Jul 12 '16 at 14:59
1

The implementation of the selected answer

  1. Modification of the JSF view. I've kept the inputtext component (with readonly attribute) which includes my constant value and I've deleted the filter feature (on the client side) for this column. The filter attributes have to stay in the <p:column> component, otherwise you won't see the inputtext component in the header row of the column.

    <p:column headerText="Source IP" sortBy="#{obj.sip}"
            filterBy="#{obj.sip}" filterMatchMode="contains">
        <f:facet name="filter">
            <p:inputText readonly="true" value="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}"
            style="width: 100%; background-color: #0088cc; color: #ffffff;"/>
        </f:facet>          
        <h:outputText value="#{obj.sip}" />     
    </p:column>
    
  2. In load method I've put my value into the filters parameter which stores all the required values for the filtering.

    dataTableLazy=new LazyDataModel<Data>() {
    
        @Override
        public List<Data> load(int first, int pageSize, List<SortMeta> multiSortMeta,
                Map<String, Object> filters) {  
    
            //here I put my value
            filters.put("sip", selectedSourceIP.getIp());
    
            List<Data> result=dataService.getLazyDataStoreTable(idSeletedUserTable, first, pageSize, multiSortMeta, filters);
    
            //other code
    
            return result;
        }
    };
    
Robert
  • 762
  • 2
  • 10
  • 23
-1

My idea is to use a select one button to simulate a readonly filter field, as the following:

    <p:column headerText="Source IP" sortBy="#{obj.sip}"
              filterBy="#{obj.sip}" filterMatchMode="contains">
        <f:facet name="filter">
            <p:selectOneButton onchange="PF('dataTableOfDataStoreVar').filter()">
                <f:selectItem itemLabel="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}" 
                              itemValue="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}" />
            </p:selectOneButton>
        </f:facet>          
        <h:outputText value="#{obj.sip}" />     
    </p:column> 
Fseee
  • 2,476
  • 9
  • 40
  • 63
  • 1
    Is Primefaces/JSF automatically validating, that value returned in the http request is actually a valid list item? And if not what happens? – Abaddon666 Jul 12 '16 at 13:30
  • Thanks for your feedback. Your solution works but not like I expect. In your solution the filter isn't work automatically, so first I've to active the button by clicking on it. I excepted the soultion which works like this: When the `datatable` is displayed, the filter has to work automatically because it has got the value in the filter field. But thanks for your idea. – Robert Jul 12 '16 at 14:58