2

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.

Diego Nieto
  • 581
  • 2
  • 10
  • 23
  • I don't see anything about `onRowSelect` You should look over the `primfaces` showcase for lazy loading carefully. – K.Nicholas Jan 29 '16 at 18:17
  • Thats the matter I created the lazy loading as is in the primefaces show case: http://primefaces.org/showcase/ui/data/datatable/lazy.xhtml, but can't find where is the error. – Diego Nieto Jan 29 '16 at 18:57
  • Like I said, I don't see anything in your code about `onRowSelect`. If row select is not working, perhaps you need an `onRowSelect`. Looking into that is my best suggestion. – K.Nicholas Jan 29 '16 at 19:17
  • I just added the method in the post at the controller, forgot about it when I created the question. – Diego Nieto Jan 29 '16 at 19:19
  • Well, if it still doesn't work, there is not much I can do. I can't compile your code because it is incomplete. I have confidence that if I test the showcase code it will work fine, so there is no way I can debug your code. Firstly, because your example is incomplete, and secondly and mostly, because that's not what this forum is for. – K.Nicholas Jan 29 '16 at 19:26
  • Well I'm not sure about it but at first I deployed the project on JBoss 7.1 and it worked ok, now I changed to tomcat 7, and isn't working, but not sure that could be a possible cause. – Diego Nieto Jan 29 '16 at 19:34
  • I suppose you should debug it and make sure the the `onRowSelect` is being called. – K.Nicholas Jan 29 '16 at 19:36
  • Finally I solved this problem, The problem was a logic error in the LazyDataModel specifically in the "getRowData(String rowKey)" method. If someone read this and need some help I will be happy of helping you. – Diego Nieto Feb 05 '16 at 04:51
  • Why are you using lazy data model, when you call `eventServiceImpl.getAll();` ? – Betlista Dec 17 '18 at 11:28

1 Answers1

4

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;
        }
    }
}
Diego Nieto
  • 581
  • 2
  • 10
  • 23