Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2011-2023 PrimeFaces Extensions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.primefaces.extensions.component.sheet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.FacesEvent;
import org.primefaces.PrimeFaces;
import org.primefaces.extensions.event.SheetEvent;
import org.primefaces.extensions.model.sheet.SheetRowColIndex;
import org.primefaces.extensions.model.sheet.SheetUpdate;
import org.primefaces.extensions.util.ExtLangUtils;
import org.primefaces.extensions.util.JavascriptVarBuilder;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;
import org.primefaces.util.ComponentUtils;
import org.primefaces.util.Constants;
import org.primefaces.util.LangUtils;
/**
* Spreadsheet component wrappering the Handsontable jQuery UI component.
*
* @author Mark Lassiter / Melloware
* @since 6.2
*/
@ResourceDependency(library = "primefaces", name = "components.css")
@ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
@ResourceDependency(library = "primefaces", name = "core.js")
@ResourceDependency(library = "primefaces", name = "components.js")
@ResourceDependency(library = "primefaces-extensions", name = "primefaces-extensions.js")
@ResourceDependency(library = "primefaces-extensions", target = "head", name = "sheet/sheet.css")
@ResourceDependency(library = "primefaces-extensions", name = "sheet/sheet.js")
public class Sheet extends SheetBase {
public static final String EVENT_CELL_SELECT = "cellSelect";
public static final String EVENT_CHANGE = "change";
public static final String EVENT_SORT = "sort";
public static final String EVENT_FILTER = "filter";
public static final String EVENT_COLUMN_SELECT = "columnSelect";
public static final String EVENT_ROW_SELECT = "rowSelect";
public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.Sheet";
private static final Collection EVENT_NAMES = Collections.unmodifiableCollection(Arrays.asList(EVENT_CHANGE,
EVENT_CELL_SELECT, EVENT_SORT, EVENT_FILTER, EVENT_COLUMN_SELECT, EVENT_ROW_SELECT));
/**
* The list of UI Columns
*/
private List columns;
/**
* List of invalid updates
*/
private List invalidUpdates;
/**
* Map of submitted values by row index and column index
*/
private final Map submittedValues = new ConcurrentHashMap<>();
/**
* Map of local values by row index and column index
*/
private final Map localValues = new ConcurrentHashMap<>();
/**
* The selection data
*/
private String selection;
/**
* The id of the focused filter input if any
*/
private String focusId;
/**
* Transient list of sheet updates that can be accessed after a successful model update.
*/
private final List updates = new ArrayList<>();
/**
* Maps a visible, rendered column index to the actual column based on whether or not the column is rendered. Updated on encode, and used on decode. Saved
* in the component state.
*/
private Map columnMapping;
/**
* Map by row keys for values found in list
*/
private Map rowMap;
/**
* Map by row keys for row number
*/
private Map rowNumbers;
@Override
public String getFamily() {
return SheetBase.COMPONENT_FAMILY;
}
/**
* {@inheritDoc}
*/
@Override
public Collection getEventNames() {
return EVENT_NAMES;
}
@Override
public String getDefaultEventName() {
return EVENT_CHANGE;
}
/**
* {@inheritDoc}
*/
@Override
public void queueEvent(final FacesEvent event) {
final FacesContext fc = FacesContext.getCurrentInstance();
if (isSelfRequest(fc) && event instanceof AjaxBehaviorEvent) {
final AjaxBehaviorEvent behaviorEvent = (AjaxBehaviorEvent) event;
final SheetEvent sheetEvent = new SheetEvent(this, behaviorEvent.getBehavior());
sheetEvent.setPhaseId(event.getPhaseId());
super.queueEvent(sheetEvent);
return;
}
super.queueEvent(event);
}
private boolean isSelfRequest(final FacesContext context) {
return getClientId(context).equals(context.getExternalContext().getRequestParameterMap()
.get(Constants.RequestParams.PARTIAL_SOURCE_PARAM));
}
/**
* The list of child columns.
*/
public List getColumns() {
if (columns == null) {
columns = new ArrayList<>();
getColumns(this);
}
return columns;
}
/**
* The list of rendered child columns.
*/
public List getRenderedColumns() {
final List allColumns = getColumns();
final List renderedCols = new ArrayList<>(allColumns.size());
for (final SheetColumn column : allColumns) {
if (column.isRendered()) {
renderedCols.add(column);
}
}
return renderedCols;
}
/**
* Grabs the UIColumn children for the parent specified.
*/
private List getColumns(final UIComponent parent) {
for (final UIComponent child : parent.getChildren()) {
if (child instanceof SheetColumn) {
columns.add((SheetColumn) child);
}
}
return columns;
}
/**
* Updates the list of child columns.
*/
public void setColumns(final List columns) {
this.columns = columns;
}
/**
* The list of invalid updates
*/
public List getInvalidUpdates() {
if (invalidUpdates == null) {
invalidUpdates = new ArrayList<>();
}
return invalidUpdates;
}
/**
* Resets the submitted values
*/
public void resetSubmitted() {
submittedValues.clear();
updates.clear();
}
/**
* Resets the sorting to the originally specified values (if any)
*/
public void resetSort() {
// Set to null to restore initial sort order specified by sortBy
getStateHelper().put(PropertyKeys.currentSortBy.name(), null);
final String origSortOrder = (String) getStateHelper().get(PropertyKeys.origSortOrder);
if (origSortOrder != null) {
setSortOrder(origSortOrder);
}
}
/**
* Resets invalid updates
*/
public void resetInvalidUpdates() {
getInvalidUpdates().clear();
}
/**
* Resets all filters, sorting and submitted values.
*/
public void reset() {
resetSubmitted();
resetSort();
resetInvalidUpdates();
localValues.clear();
for (final SheetColumn c : getColumns()) {
c.setFilterValue(null);
}
}
/**
* Updates a submitted value.
*/
public void setSubmittedValue(final String rowKey, final int col, final String value) {
submittedValues.put(new SheetRowColIndex(rowKey, col), value);
}
/**
* Retrieves the submitted value for the row and col.
*/
public String getSubmittedValue(final String rowKey, final int col) {
return submittedValues.get(new SheetRowColIndex(rowKey, col));
}
/**
* Updates a local value.
*/
public void setLocalValue(final String rowKey, final int col, final Object value) {
final SheetRowColIndex key = new SheetRowColIndex(rowKey, col);
if (value != null) {
localValues.put(key, value);
}
else {
localValues.put(key, ToBeRemoved.class);
}
}
/**
* Retrieves the submitted value for the rowKey and col.
*/
public Object getLocalValue(final String rowKey, final int col) {
return localValues.get(new SheetRowColIndex(rowKey, col));
}
/**
* Updates the row var for iterations over the list. The var value will be updated to the value for the specified rowKey.
*
* @param context the FacesContext against which to the row var is set. Passed for performance
* @param rowKey the rowKey string
*/
public void setRowVar(final FacesContext context, final String rowKey) {
if (context == null) {
return;
}
if (rowKey == null) {
context.getExternalContext().getRequestMap().remove(getVar());
}
else {
final Object value = getRowMap().get(rowKey);
context.getExternalContext().getRequestMap().put(getVar(), value);
}
}
protected Map getRowMap() {
if (rowMap == null || rowMap.isEmpty()) {
remapRows();
}
return rowMap;
}
/**
* Gets the object value of the row and col specified. If a local value exists, that is returned, otherwise the actual value is return.
*/
public Object getValueForCell(final FacesContext context, final String rowKey, final int col) {
// if we have a local value, use it
// note: can't check for null, as null may be the submitted value
final SheetRowColIndex index = new SheetRowColIndex(rowKey, col);
if (localValues.containsKey(index)) {
return localValues.get(index);
}
setRowVar(context, rowKey);
final SheetColumn column = getColumns().get(col);
final ValueExpression ve = column.getValueExpression("value");
if (ve != null) {
return ve.getValue(context.getELContext());
}
else {
return column.getValue();
}
}
/**
* Gets the render string for the value the given cell. Applys the available converters to convert the value.
*/
public String getRenderValueForCell(final FacesContext context, final String rowKey, final int col) {
// if we have a submitted value still, use it
// note: can't check for null, as null may be the submitted value
final SheetRowColIndex index = new SheetRowColIndex(rowKey, col);
if (submittedValues.containsKey(index)) {
return submittedValues.get(index);
}
final Object value = getValueForCell(context, rowKey, col);
if (value == null) {
return null;
}
final SheetColumn column = getColumns().get(col);
final Converter