All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.richfaces.component.AbstractExtendedDataTable Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.richfaces.component;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;

import org.richfaces.cdk.annotations.Attribute;
import org.richfaces.cdk.annotations.EventName;
import org.richfaces.cdk.annotations.JsfComponent;
import org.richfaces.cdk.annotations.JsfRenderer;
import org.richfaces.cdk.annotations.Tag;
import org.richfaces.cdk.annotations.TagType;
import org.richfaces.context.ExtendedVisitContext;
import org.richfaces.context.ExtendedVisitContextMode;
import org.richfaces.log.Logger;
import org.richfaces.log.RichfacesLogger;
import org.richfaces.model.SelectionMode;

/**
 * 

The <rich:extendedDataTable> component builds on the functionality of the <rich:dataTable> component, * adding features such as scrolling for the table body (both horizontal and vertical), Ajax loading for vertical * scrolling, frozen columns, row selection, and rearranging of columns. It also supports all the basic table features * such as sorting, filtering, and paging using the <rich:dataScroller> component.

* * @author Konstantin Mishin */ @JsfComponent(type = AbstractExtendedDataTable.COMPONENT_TYPE, family = AbstractExtendedDataTable.COMPONENT_FAMILY, generate = "org.richfaces.component.UIExtendedDataTable", renderer = @JsfRenderer(type = "org.richfaces.ExtendedDataTableRenderer"), tag = @Tag(name = "extendedDataTable", handler = "org.richfaces.taglib.ExtendedDataTableHandler", type = TagType.Facelets), attributes = { "style-prop.xml", "styleClass-prop.xml", "iteration-props.xml", "rows-prop.xml", "sequence-props.xml", "events-row-props.xml" }) public abstract class AbstractExtendedDataTable extends UIDataTableBase implements MetaComponentResolver, MetaComponentEncoder { public static final String COMPONENT_TYPE = "org.richfaces.ExtendedDataTable"; public static final String COMPONENT_FAMILY = UIDataTableBase.COMPONENT_FAMILY; public static final String SCROLL = "scroll"; public static final String SUBMITTED_CLIENT_FIRST = "submittedClientFirst"; public static final String OLD_CLIENT_FIRST = "oldClientFirst"; private static final Logger RENDERKIT_LOG = RichfacesLogger.RENDERKIT.getLogger(); protected enum PropertyKeys { clientFirst, clientRows } /** * Determines how many columns should not be vertically scrollable (should be "frozen"). */ @Attribute public abstract int getFrozenColumns(); @Attribute public abstract String getStyleClass(); /** * Defines selection mode for the table: none, single (only one row can be selected), multiple (Ctrl/Shift keys are used for * multi-selection), multipleKeyboardFree (clicks are used for multi-selection) */ @Attribute public abstract SelectionMode getSelectionMode(); /** * The client-side script method to be called after the EDT has been initialized, either after a page load, and an ajax update. */ @Attribute(events = @EventName(value = "ready")) public abstract String getOnready(); /** * The client-side script method to be called after the selection is changed. */ @Attribute(events = @EventName(value = "selectionchange", defaultEvent = true)) public abstract String getOnselectionchange(); /** * Determines the order in which the columns should be rendered, left to right. * The Strings are the ids of the columns. */ @Attribute public abstract String[] getColumnsOrder(); /** * ValueBinding pointing at a property of a String to hold table state */ @Attribute public abstract String getTableState(); /** * The client-side script method to be called before the selection is changed. */ @Attribute(events = @EventName("beforeselectionchange")) public abstract String getOnbeforeselectionchange(); public String resolveClientId(FacesContext facesContext, UIComponent contextComponent, String metaComponentId) { if (SCROLL.equals(metaComponentId)) { Object oldRowKey = getRowKey(); try { setRowKey(facesContext, null); return getClientId(facesContext) + MetaComponentResolver.META_COMPONENT_SEPARATOR_CHAR + metaComponentId; } finally { try { setRowKey(facesContext, oldRowKey); } catch (Exception e) { RENDERKIT_LOG.error(e.getMessage(), e); } } } return super.resolveClientId(facesContext, contextComponent, metaComponentId); } public void encodeMetaComponent(FacesContext context, String metaComponentId) throws IOException { if (SCROLL.equals(metaComponentId)) { Map attributes = getAttributes(); Integer submittedClientFirst = (Integer) attributes.remove(SUBMITTED_CLIENT_FIRST); if (submittedClientFirst != null) { attributes.put(OLD_CLIENT_FIRST, getClientFirst()); setClientFirst(submittedClientFirst); } } super.encodeMetaComponent(context, metaComponentId); } protected boolean visitDataChildren(VisitContext visitContext, final VisitCallback callback, boolean visitRows) { if (visitContext instanceof ExtendedVisitContext && visitRows) { ExtendedVisitContext extendedVisitContext = (ExtendedVisitContext) visitContext; if (extendedVisitContext.getVisitMode() == ExtendedVisitContextMode.RENDER) { // TODO nick - call preEncodeBegin(...) and emit PreRenderEvent setRowKey(visitContext.getFacesContext(), null); VisitResult result; result = extendedVisitContext.invokeMetaComponentVisitCallback(this, callback, SCROLL); if (result == VisitResult.ACCEPT) { // TODO nick - visit scroll? } else if (result == VisitResult.COMPLETE) { return true; } } } return super.visitDataChildren(visitContext, callback, visitRows); } protected int getActualFirst() { return getFirst() + getClientFirst(); } protected int getActualRows() { int rows = getClientRows(); if (rows > 0) { int r = getRows(); if (r > 0 && r < rows) { rows = r; } } else { rows = getRows(); } return rows; } public int getClientFirst() { return (Integer) getStateHelper().eval(PropertyKeys.clientFirst, 0); } public void setClientFirst(int clientFirst) { getStateHelper().put(PropertyKeys.clientFirst, clientFirst); updateState(); } public void setFirst(int first) { super.setFirst(first); setClientFirst(0); } /** * Use to switch Extended Data Table to AJAX lazy-loading mode. Specify number of rows rows to be loaded with one request. * If this attribute is set to "0", all rows are loaded. (Default value: 0) */ @Attribute(generate = false, defaultValue = "0") public int getClientRows() { return (Integer) getStateHelper().eval(PropertyKeys.clientRows, 0); } public void setClientRows(int clientRows) { getStateHelper().put(PropertyKeys.clientRows, clientRows); updateState(); } public void setValueBinding(String name, javax.faces.el.ValueBinding binding) { super.setValueBinding(name, binding); // TODO nick - clientFirst? if ("clientRows".equals(name)) { updateState(); } } public void setValueExpression(String name, ValueExpression binding) { super.setValueExpression(name, binding); // TODO nick - clientFirst? if ("clientRows".equals(name)) { updateState(); } } /** * The collection of keys for currently selected table rows (generated from data model by rowKeyConverter). */ @Attribute public abstract Collection getSelection(); }