简体   繁体   中英

Row selection not working in primefaces (5.3) data table when the lazy loading is implemented, but it works without lazy loading

This is my data table:

<h:form id="eventListForm">
                <p:contextMenu id="eventDataTableContextMenu" for="datalist">  
                <p:menuitem value="#{myBundle.Create}" onclick="document.getElementById('eventListForm:createButton').click();" icon="ui-icon-plus"/>
                <p:menuitem value="#{myBundle.View}" onclick="document.getElementById('eventListForm:viewButton').click();" icon="ui-icon-search"/>
                <p:menuitem value="#{myBundle.Edit}" onclick="document.getElementById('eventListForm:editButton').click();" icon="ui-icon-pencil"/>
                <p:menuitem value="#{myBundle.Delete}" onclick="document.getElementById('eventListForm:deleteButton').click();" icon="ui-icon-trash"/>
            </p:contextMenu>
            <p:dataTable id="datalist"
                         value="#{eventController.lazyModel}"
                         var="item"
                         rowKey="#{item.eventId}"
                         paginator="true"
                         paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
                         rows="10"
                         rowsPerPageTemplate="10,20,30,40,50"
                         selectionMode="single"
                         selection="#{eventController.selected}"
                         lazy="true">

                <p:ajax event="rowSelect" update="@form:createButton,@form:viewButton,@form:editButton,@form:deleteButton,@form:eventDataTableContextMenu"/>
                <p:ajax event="rowUnselect" update="@form:createButton,@form:viewButton,@form:editButton,@form:deleteButton,@form:eventDataTableContextMenu"/>
                <p:ajax event="contextMenu" update="@form:createButton @form:viewButton @form:editButton @form:deleteButton"/>
                <p:ajax event="rowDblselect" onsuccess="document.getElementById('eventListForm:viewButton').click();"/>

This is the controller:

 public class EventController {

        IEventService eventService;
        List<EventDTO> items;
        private EventDTO selected;
        private Integer priorityIdSelected;

        private LazyDataModel<EventDTO> lazyModel;

        public void init() {
            //items = eventService.getAll();
            lazyModel = new EventLazyLoader(eventService);
        }


public void onRowSelect(SelectEvent event) {
    FacesMessage msg = new FacesMessage("Event Selected", ((EventDTO) event.getObject()).getEventId().toString());
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

This is the lazy loader implementation:

public class EventLazyLoader extends LazyDataModel<EventDTO> {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private List<EventDTO> datasource;

    public EventLazyLoader(IEventService eventServiceImpl) {
        this.datasource = eventServiceImpl.getAll();
    }

    @Override
    public EventDTO getRowData(String rowKey) {
        for(EventDTO event : datasource) {
            if(event.getEventId().equals(rowKey))
                return event;
        }
        return null;
    }

    @Override
    public Object getRowKey(EventDTO event) {
        return event.getEventId();
    }

    @Override
    public List<EventDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
        List<EventDTO> data = new ArrayList<EventDTO>();
          //filter
        for(EventDTO event : datasource) {
            boolean match = true;
            if (filters != null) {
                for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                    try {
                        String filterProperty = it.next();
                        Object filterValue = filters.get(filterProperty);
                        String fieldValue = String.valueOf(event.getClass().getField(filterProperty).get(event));
                        if(filterValue == null || fieldValue.startsWith(filterValue.toString())) {
                            match = true;
                        } else {
                            match = false;
                            break;
                        }
                    } catch(Exception ex) {
                        match = false;
                    }
                }
            }
            if(match) {
                data.add(event);
            }
        }

        //sort
        if(sortField != null) {
            Collections.sort(data, new EventLazySorter(sortField, sortOrder));
        }

        //rowCount
        int dataSize = data.size();
        this.setRowCount(dataSize);

        //paginate
        if(dataSize > pageSize) {
            try {
                return data.subList(first, first + pageSize);
            }
            catch(IndexOutOfBoundsException e) {
                return data.subList(first, first + (dataSize % pageSize));
            }
        }
        else {
            return data;
        }
    }
}

The controller also have a the items List (java.util.List ) if I use this list as a data for the data list the row selection works without any problem, it seems that the problem is the lazy loading, but I don't have any idea why this is happening.

By the way thanks a lot for all the hints and help that someone can give me.

Finally I solved this problem, The problem was a logic error in the LazyDataModel implementation specifically in the "getRowData(String rowKey)" method. In the comment "Error here" the problem was that in the primefaces showcase, the example uses the equals() method to compare, my problem was that I tried to compare for equality one Integer (the id of my dto) with the string value obtained from the row selection, so I parse that string and finally compare the integer values (a silly mistake if you think about it)

public class EventLazyLoader extends LazyDataModel<EventDTO> {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final Logger logger = Logger.getLogger(EventLazyLoader.class);

    private List<EventDTO> datasource;

    public EventLazyLoader(IEventService eventServiceImpl) {
        this.datasource = eventServiceImpl.getAll();
    }

    @Override
    public EventDTO getRowData(String rowKey) {
        int intRowKey = Integer.parseInt(rowKey);
        for(EventDTO event : datasource) {
            if(event.getEventId() == intRowKey) {//Error here
                return event;
            }
        }
        return null;
    }

    @Override
    public Object getRowKey(EventDTO event) {
        return event.getEventId();
    }

    @Override
    public List<EventDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
        List<EventDTO> data = new ArrayList<EventDTO>();
          //filter
        for(EventDTO event : datasource) {
            boolean match = true;
            if (filters != null) {
                for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                    try {
                        String filterProperty = it.next();
                        Object filterValue = filters.get(filterProperty);
                        String fieldValue = String.valueOf(event.getClass().getField(filterProperty).get(event));
                        if(filterValue == null || fieldValue.startsWith(filterValue.toString())) {
                            match = true;
                        } else {
                            match = false;
                            break;
                        }
                    } catch(Exception ex) {
                        match = false;
                    }
                }
            }
            if(match) {
                data.add(event);
            }
        }

        //sort
        if(sortField != null) {
            Collections.sort(data, new EventLazySorter(sortField, sortOrder));
        }

        //rowCount
        int dataSize = data.size();
        this.setRowCount(dataSize);

        //paginate
        if(dataSize > pageSize) {
            try {
                return data.subList(first, first + pageSize);
            }
            catch(IndexOutOfBoundsException e) {
                return data.subList(first, first + (dataSize % pageSize));
            }
        }
        else {
            return data;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM