p:dataTable selections are lost after paginating a LazyDataModel

后端 未结 5 1235
春和景丽
春和景丽 2021-01-04 00:31

My problem is that after I\'ve selected a few items on the 1st page, if I paginate to another page and come back, my initial selections are not shown. I\'ve tried to impleme

5条回答
  •  囚心锁ツ
    2021-01-04 01:21

    This is because when SelectionFeature is decoded a new list is created.

    And if table.getRowData(rowKeys[i]) (related to your LazyDataModel implementation) returns null your old selectıons in the previous page are gone.may try to solve it by changing your LazyDataModel implementation I didn't try these but take a look at this and this

    Had the same problem and I think this solution is easier if you have a lot of different tables implementing LazyDataModel.

    This is what I did: check if it is lazy first then add currently selected rows to the selectionList.

    For primefaces 4.0

    1)Override DataTableRenderer

    In faces-config.xml

    
       
           org.primefaces.component
           org.primefaces.component.DataTableRenderer
           com.package.LazyDataTableRenderer
       
    
    

    And

    public class LazyDataTableRenderer extends DataTableRenderer {
    static Map FEATURES;
    
        static {
            FEATURES = new HashMap();
            FEATURES.put(DataTableFeatureKey.DRAGGABLE_COLUMNS, new DraggableColumnsFeature());
            FEATURES.put(DataTableFeatureKey.FILTER, new FilterFeature());
            FEATURES.put(DataTableFeatureKey.PAGE, new PageFeature());
            FEATURES.put(DataTableFeatureKey.SORT, new SortFeature());
            FEATURES.put(DataTableFeatureKey.RESIZABLE_COLUMNS, new ResizableColumnsFeature());
            FEATURES.put(DataTableFeatureKey.SELECT, new LazySelectionFeature());
            FEATURES.put(DataTableFeatureKey.ROW_EDIT, new RowEditFeature());
            FEATURES.put(DataTableFeatureKey.CELL_EDIT, new CellEditFeature());
            FEATURES.put(DataTableFeatureKey.ROW_EXPAND, new RowExpandFeature());
            FEATURES.put(DataTableFeatureKey.SCROLL, new ScrollFeature());
        }
    
        @Override
        public void decode(FacesContext context, UIComponent component) {
            DataTable table = (DataTable) component;
    
            for(Iterator it = FEATURES.values().iterator(); it.hasNext();) {
                DataTableFeature feature = it.next();
    
                if(feature.shouldDecode(context, table)) {
                    feature.decode(context, table);
                }
            }
    
            decodeBehaviors(context, component);        
        }
    }
    

    2)Override SelectionFeature's decode

    Updated: edited to allow deselecting

    public class LazySelectionFeature extends org.primefaces.component.datatable.feature.SelectionFeature{
    
        @Override
        public void decode(FacesContext context, DataTable table) {
            String clientId = table.getClientId(context);
            Map params = context.getExternalContext().getRequestParameterMap();
    
            String selection = params.get(clientId + "_selection");
    
            if(table.isSingleSelectionMode())
                decodeSingleSelection(table, selection);
            else
                decodeMultipleSelection(context, table, selection);
        }
    
        void decodeSingleSelection(DataTable table, String selection) {
                if(ComponentUtils.isValueBlank(selection))
                    table.setSelection(null);
                else
                    table.setSelection(table.getRowData(selection));
            }
    
        void decodeMultipleSelection(FacesContext context, DataTable table, String selection) {
            Class clazz = table.getValueExpression("selection").getType(context.getELContext());
            boolean isArray = clazz.isArray();
    
            if(!isArray && !List.class.isAssignableFrom(clazz)) {
                throw new FacesException("Multiple selection reference must be an Array or a List for datatable " + table.getClientId());
            }
    
            if(ComponentUtils.isValueBlank(selection)) {
                if(isArray) {
                    table.setSelection(Array.newInstance(clazz.getComponentType(), 0));
                }
                else {
                    table.setSelection(new ArrayList());
                }
            }
            else {
                String[] rowKeys = selection.split(",");
                List selectionList = new ArrayList();
    
                boolean lazy=table.isLazy();
                if (lazy) {
    
                List currentRowKeys = new ArrayList(Arrays.asList(rowKeys));
                if (table.getSelection() != null) {
                    List alreadySelected = (List) table.getSelection();
    
                    for (Object object : alreadySelected) {//For deselecting
                        Object rowKeyFromModel = table.getRowKeyFromModel(object);
                        if (currentRowKeys.contains(rowKeyFromModel)) {
                            selectionList.add(object);
                            currentRowKeys.remove(rowKeyFromModel);
                        } 
                    }                    
                }
                for (String key : currentRowKeys) {//For selecting  
                    Object rowData = table.getRowData(key);
                    if (rowData != null && !selectionList.contains(rowData)) {
                           selectionList.add(rowData);
                    }
                }
    
            }else{
    
                    for(int i = 0; i < rowKeys.length; i++) {
                        Object rowData = table.getRowData(rowKeys[i]);
    
                        if(rowData != null)
                            selectionList.add(rowData);
                    }
    
                }
    
                if(isArray) {
                    Object selectionArray = Array.newInstance(clazz.getComponentType(), selectionList.size());
                    table.setSelection(selectionList.toArray((Object[]) selectionArray));
                }
                else {
                    table.setSelection(selectionList);
                }
            }
        }
    }
    
    
    

    Might not be the best solution but should work, let me know if there is a better way. Hope this helps someone.

    提交回复
    热议问题