Author: konstantin.mishin
Date: 2010-03-31 07:56:19 -0400 (Wed, 31 Mar 2010)
New Revision: 16691
Modified:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIExtendedDataTable.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java
Log:
RF-8484
Modified:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIExtendedDataTable.java
===================================================================
---
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIExtendedDataTable.java 2010-03-31
11:55:08 UTC (rev 16690)
+++
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIExtendedDataTable.java 2010-03-31
11:56:19 UTC (rev 16691)
@@ -24,12 +24,16 @@
import java.io.IOException;
import java.util.Collection;
+import java.util.Map;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
+import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.ajax4jsf.model.DataComponentState;
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.RepeatState;
import org.richfaces.renderkit.PartialEncodingRenderer;
@@ -42,6 +46,7 @@
public static final String SCROLL = "scroll";
public static final String SUBMITTED_CLIENT_FIRST =
"submittedClientFirst";
+ public static final String OLD_CLIENT_FIRST = "oldClientFirst";
protected enum PropertyKeys {
clientFirst, clientRows
@@ -52,8 +57,10 @@
Collection<String> subComponentIdentifiers)
throws IOException {
if (subComponentIdentifiers.contains(SCROLL)) {
- Integer submittedClientFirst = (Integer)
getAttributes().remove(SUBMITTED_CLIENT_FIRST);
+ Map<String, Object> attributes = getAttributes();
+ Integer submittedClientFirst = (Integer)
attributes.remove(SUBMITTED_CLIENT_FIRST);
if (submittedClientFirst != null) {
+ attributes.put(OLD_CLIENT_FIRST, getClientFirst());
setClientFirst(submittedClientFirst);
}
}
@@ -61,6 +68,16 @@
((PartialEncodingRenderer) renderer).encodePartially(this, context, callback,
subComponentIdentifiers);
}
+ public void partiallyWalk(FacesContext faces, DataVisitor visitor, Range range,
Object argument) {
+ Object key = getRowKey();
+ captureOrigValue(faces);
+
+ getExtendedDataModel().walk(faces, visitor, range, argument);
+
+ setRowKey(faces, key);
+ restoreOrigValue(faces);
+ }
+
@Override
protected DataComponentState createComponentState() {
return new RepeatState() {
@@ -71,14 +88,7 @@
@Override
public int getRows() {
- int rows = UIExtendedDataTable.this.getClientRows();
- if (rows > 0) {
- rows = Math.min(rows, UIExtendedDataTable.this.getRows());
- } else {
- rows = UIExtendedDataTable.this.getRows();
- }
-
- return rows;
+ return UIExtendedDataTable.this.getRealClientRows();
}
};
}
@@ -97,6 +107,16 @@
setClientFirst(0);
}
+ public int getRealClientRows() {
+ int rows = getClientRows();
+ if (rows > 0) {
+ rows = Math.min(rows, getRows());
+ } else {
+ rows = getRows();
+ }
+ return rows;
+ }
+
public int getClientRows() {
return (Integer) getStateHelper().eval(PropertyKeys.clientRows, 0);
}
Modified:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java
===================================================================
---
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java 2010-03-31
11:55:08 UTC (rev 16690)
+++
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java 2010-03-31
11:56:19 UTC (rev 16691)
@@ -28,8 +28,10 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -44,27 +46,57 @@
import org.ajax4jsf.javascript.JSFunction;
import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.model.DataVisitResult;
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.SequenceRange;
import org.ajax4jsf.renderkit.AjaxEventOptions;
import org.ajax4jsf.renderkit.RendererUtils.HTML;
import org.richfaces.component.UIExtendedDataTable;
import org.richfaces.component.util.HtmlUtil;
-@ResourceDependencies({ @ResourceDependency(library = "javax.faces", name =
"jsf.js"),
+@ResourceDependencies({ @ResourceDependency(library = "javax.faces", name =
"jsf-uncompressed.js"),
@ResourceDependency(name = "jquery.js"), @ResourceDependency(name =
"jquery.position.js"),
@ResourceDependency(name = "richfaces.js"), @ResourceDependency(name =
"extendedDataTable.js"),
@ResourceDependency(name = "extendedDataTable.css") })
public class ExtendedDataTableRenderer extends AbstractRowsRenderer implements
PartialEncodingRenderer {
- private class RendererState extends RowHolderBase {
+ private static enum PartName {
+ frozen, normal
+ }
+
+ private class Part {
+ private PartName name;
+ private List<UIComponent> columns;
+
+ public Part(PartName name, List<UIComponent> columns) {
+ this.name = name;
+ this.columns = columns;
+ }
+
+ public PartName getName() {
+ return name;
+ }
+ public List<UIComponent> getColumns() {
+ return columns;
+ }
+
+ }
+
+ private class RendererState extends RowHolderBase{
+
private UIExtendedDataTable table;
- private List<UIComponent> frozenColumns;
- private List<UIComponent> columns;
- private boolean frozen;
-
+ private List<Part> parts;
+ private Part current;
+ private Iterator<Part> partIterator;
+
+
+
public RendererState(FacesContext context, UIExtendedDataTable table) {
super(context);
this.table = table;
+ List<UIComponent> frozenColumns;
+ List<UIComponent> columns;
columns = new ArrayList<UIComponent>();
Iterator<UIComponent> iterator = table.columns();
Map<String, UIComponent> columnsMap = new LinkedHashMap<String,
UIComponent>();
@@ -88,27 +120,36 @@
int count = Math.min(((Integer)
table.getAttributes().get("frozenColumns")).intValue(), columns.size());
frozenColumns = columns.subList(0, count);
columns = columns.subList(count, columns.size());
+ parts = new ArrayList<Part>(PartName.values().length);
+ if (frozenColumns.size() > 0) {
+ parts.add(new Part(PartName.frozen, frozenColumns));
+ }
+ if (columns.size() > 0) {
+ parts.add(new Part(PartName.normal, columns));
+ }
}
public UIExtendedDataTable getRow() {
return table;
}
- public List<UIComponent> getFrozenColumns() {
- return frozenColumns;
+ public void startIterate() {
+ partIterator = parts.iterator();
}
- public List<UIComponent> getColumns() {
- return columns;
+ public Part nextPart() {
+ current = partIterator.next();
+ return current;
}
- public void setFrozen(boolean frozen) {
- this.frozen = frozen;
+ public Part getPart() {
+ return current;
}
+
+ public boolean hasNextPart() {
+ return partIterator.hasNext();
+ }
- public boolean isFrozen() {
- return frozen;
- }
}
@Override
@@ -121,31 +162,89 @@
Collection<String> subComponentIdentifiers) throws IOException {
if (subComponentIdentifiers.size() == 1 &&
subComponentIdentifiers.contains(UIExtendedDataTable.SCROLL)) {
FacesContext context = visitContext.getFacesContext();
- PartialResponseWriter writer =
context.getPartialViewContext().getPartialResponseWriter();
+ final PartialResponseWriter writer =
context.getPartialViewContext().getPartialResponseWriter();
UIExtendedDataTable table = (UIExtendedDataTable) component;
- Object key = table.getRowKey();
- table.captureOrigValue(context);
- table.setRowKey(context, null);
- RendererState state = createRowHolder(context, table);
- state.setFrozen(true);
- // TODO 1. Encode fixed children 2. Load necessary rows only
- for (int i = 0; i < 2; i++) { // TODO 1. Replace 2 with constant 2. Empty
frozen part shouldn't be rendered
- if (i == 0) {
- writer.startUpdate(table.getClientId(context) + ":ftb");
- } else {
- writer.startUpdate(table.getClientId(context) + ":ntb");
+ int clientFirst = table.getClientFirst();
+ Integer oldClientFirst = (Integer)
table.getAttributes().remove(UIExtendedDataTable.OLD_CLIENT_FIRST);
+ if (oldClientFirst == null) {
+ oldClientFirst = clientFirst;
+ }
+ int clientRows = table.getRealClientRows();
+ int difference = clientFirst - oldClientFirst;
+ SequenceRange addRange = null;
+ SequenceRange removeRange = null;
+ if (Math.abs(difference) >= clientRows) {
+ difference = 0;
+ addRange = new SequenceRange(clientFirst, clientRows);
+ removeRange = new SequenceRange(oldClientFirst, clientRows);
+ } else if (difference < 0) {
+ clientFirst += table.getFirst();
+ addRange = new SequenceRange(clientFirst, -difference);
+ removeRange = new SequenceRange(clientFirst + clientRows, -difference);
+ } else if (difference > 0) {
+ oldClientFirst += table.getFirst();
+ removeRange = new SequenceRange(oldClientFirst, difference);
+ int last = oldClientFirst + clientRows;
+ addRange = new SequenceRange(last, difference);
+ }
+ if (addRange != null) {
+ Object key = table.getRowKey();
+ table.captureOrigValue(context);
+ table.setRowKey(context, null);
+ final RendererState state = createRowHolder(context, table);
+ // TODO 1. Encode fixed children
+ for (state.startIterate(); state.hasNextPart();) {
+ char partNameFirstChar =
state.nextPart().getName().toString().charAt(0);
+ final List<String> ids = new LinkedList<String>();
+ table.partiallyWalk(context, new DataVisitor() {
+ @Override
+ public DataVisitResult process(FacesContext context, Object
rowKey, Object argument) {
+ UIExtendedDataTable dataTable = state.getRow();
+ dataTable.setRowKey(context, rowKey);
+ ids.add(dataTable.getClientId(context) + ":"
+ + state.getPart().getName().toString().charAt(0));
+ return DataVisitResult.CONTINUE;
+ }
+ }, removeRange, null);
+ table.partiallyWalk(context, new DataVisitor() {
+ @Override
+ public DataVisitResult process(FacesContext context, Object
rowKey, Object argument) {
+ UIExtendedDataTable dataTable = state.getRow();
+ dataTable.setRowKey(context, rowKey);
+ HashMap<String, String> attributes = new
HashMap<String, String>(1);
+ String id = dataTable.getClientId(context) + ":"
+ + state.getPart().getName().toString().charAt(0);
+ attributes.put("id", id);
+ try {
+ writer.updateAttributes(ids.remove(0), attributes);
+ writer.startUpdate(id);
+ encodeRow(state);
+ writer.endUpdate();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return DataVisitResult.CONTINUE;
+ }
+ }, addRange, null);
+ writer.startEval();
+ if (difference < 0) {
+ difference += clientRows;
+ }
+ writer.write("var richTBody =
document.getElementById('" + component.getClientId(context) + ":tb"
+ + partNameFirstChar + "');");
+ writer.write("var richRows = richTBody.rows;");
+ writer.write("for (var i = 0; i < " + difference
+ + "; i++ )
richTBody.appendChild(richTBody.removeChild(richRows[0]));");
+ writer.endEval();
}
- encodeTBody(state, i);
- writer.endUpdate();
- state.setFrozen(false);
+ writer.startEval();
+ writer.write("jQuery('#" +
component.getClientId(context).replace(":", "\\\\:")
+ + "').triggerHandler('rich:onscrollcomplete', "
+ table.getClientFirst() + ");");
+ writer.endEval();
+ table.setRowKey(context, key);
+ table.restoreOrigValue(context);
}
- writer.startEval();
- writer.write("jQuery('#" +
component.getClientId(context).replace(":", "\\\\:")
- + "').triggerHandler('rich:onscrollcomplete', " +
table.getClientFirst() + ");");
- writer.endEval();
- table.setRowKey(context, key);
- table.restoreOrigValue(context);
-
} else {
throw new IllegalArgumentException("Incorect subComponentIdentifiers:
" + subComponentIdentifiers);
}
@@ -303,15 +402,17 @@
writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
writer.startElement(HTML.TBOBY_ELEMENT, table);
writer.startElement(HTML.TR_ELEMENT, table);
- Iterator<UIComponent> columns = state.getFrozenColumns().iterator();
- for (int i = 0; i < 2; i++) { // TODO Replace 2 with constant
+ for (state.startIterate(); state.hasNextPart();) {
+ Part part = state.nextPart();
+ PartName partName = part.getName();
+ Iterator<UIComponent> columns = part.getColumns().iterator();
if (columns.hasNext()) {
writer.startElement(HTML.TD_ELEM, table);
- if (i == 0 && "footer".equals(name)) {
+ if (PartName.frozen.equals(partName) &&
"footer".equals(name)) {
writer.writeAttribute(HTML.CLASS_ATTRIBUTE,
"rich-extable-footer-align", null);
}
writer.startElement(HTML.DIV_ELEM, table);
- if (i == 0) {
+ if (PartName.frozen.equals(partName)) {
if ("header".equals(name)) {
writer
.writeAttribute(HTML.ID_ATTRIBUTE,
table.getClientId(context) + ":frozenHeader", null);
@@ -335,7 +436,6 @@
writer.endElement(HTML.DIV_ELEM);
writer.endElement(HTML.TD_ELEM);
}
- columns = state.getColumns().iterator();
}
writer.endElement(HTML.TR_ELEMENT);
writer.endElement(HTML.TBOBY_ELEMENT);
@@ -371,22 +471,25 @@
writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
writer.startElement(HTML.TBOBY_ELEMENT, table);
writer.startElement(HTML.TR_ELEMENT, table);
- state.setFrozen(true);
- for (int i = 0; i < 2; i++) { // TODO 1. Replace 2 with constant 2. Empty
frozen part shouldn't be rendered
+ for (state.startIterate(); state.hasNextPart();) {
writer.startElement(HTML.TD_ELEM, table);
writer.startElement(HTML.DIV_ELEM, table);
- if (i == 1) {
+ PartName partName = state.nextPart().getName();
+ if (PartName.normal.equals(partName)) {
writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) +
":body", null);
writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-part
rich-extable-part-width", null);
}
writer.startElement(HTML.TABLE_ELEMENT, table);
writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
- encodeTBody(state, i);
+ writer.startElement(HTML.TBOBY_ELEMENT, table);
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) +
":tb"
+ + partName.toString().charAt(0), null);
+ table.walk(context, this, state); // TODO encodeRows(context, table);
+ writer.endElement(HTML.TBOBY_ELEMENT);
writer.endElement(HTML.TABLE_ELEMENT);
writer.endElement(HTML.DIV_ELEM);
writer.endElement(HTML.TD_ELEM);
- state.setFrozen(false);
}
writer.endElement(HTML.TR_ELEMENT);
writer.endElement(HTML.TBOBY_ELEMENT);
@@ -396,20 +499,6 @@
writer.endElement(HTML.DIV_ELEM);
}
- private void encodeTBody(RendererState state, int i) throws IOException {
- FacesContext context = state.getContext();
- ResponseWriter writer = context.getResponseWriter();
- UIExtendedDataTable table = state.getRow();
- writer.startElement(HTML.TBOBY_ELEMENT, table);
- if (i == 0) {
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) +
":ftb", null);
- } else {
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) +
":ntb", null);
- }
- table.walk(context, this, state); // TODO encodeRows(context, table);
- writer.endElement(HTML.TBOBY_ELEMENT);
- }
-
private void encodeHeaderOrFooterCell(FacesContext context, ResponseWriter writer,
UIComponent column,
String facetName) throws IOException {
if (column.isRendered()) {
@@ -450,11 +539,10 @@
UIExtendedDataTable table = state.getRow();
writer.startElement(HTML.TR_ELEMENT, table);
Iterator<UIComponent> columns = null;
- if (state.isFrozen()) {
- columns = state.getFrozenColumns().iterator();
- } else {
- columns = state.getColumns().iterator();
- }
+ Part part = state.getPart();
+ writer.writeAttribute(HTML.ID_ATTRIBUTE,
+ table.getClientId(context) + ":" +
part.getName().toString().charAt(0), null);
+ columns = part.getColumns().iterator();
while (columns.hasNext()) {
UIComponent column = (UIComponent) columns.next();
if (column.isRendered()) {
@@ -517,7 +605,8 @@
if (clientFirst != null && clientFirst.length() > 0) {
int value = Integer.parseInt(clientFirst);
component.getAttributes().put(UIExtendedDataTable.SUBMITTED_CLIENT_FIRST,
value);
-
context.getPartialViewContext().getRenderIds().add(component.getClientId(context) +
"@" + UIExtendedDataTable.SCROLL);
+ context.getPartialViewContext().getRenderIds().add(
+ component.getClientId(context) + "@" +
UIExtendedDataTable.SCROLL);
}
}