Author: pyaschenko
Date: 2011-04-27 13:06:51 -0400 (Wed, 27 Apr 2011)
New Revision: 22447
Modified:
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/component/UIDataAdaptor.java
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/RenderKitUtils.java
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/AbstractTableBaseRenderer.java
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
Log:
https://issues.jboss.org/browse/RF-10824 - behaviors for row* events are fixed.
Modified:
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/component/UIDataAdaptor.java
===================================================================
---
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/component/UIDataAdaptor.java 2011-04-27
14:27:41 UTC (rev 22446)
+++
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/component/UIDataAdaptor.java 2011-04-27
17:06:51 UTC (rev 22447)
@@ -22,56 +22,29 @@
package org.richfaces.component;
-import static
org.richfaces.component.util.Strings.NamingContainerDataHolder.SEPARATOR_CHAR_JOINER;
+import org.ajax4jsf.component.IterationStateHolder;
+import org.ajax4jsf.model.*;
+import org.richfaces.cdk.annotations.Attribute;
+import org.richfaces.context.ExtendedVisitContext;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
-import java.text.MessageFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
-import javax.faces.component.ContextCallback;
-import javax.faces.component.EditableValueHolder;
-import javax.faces.component.NamingContainer;
-import javax.faces.component.PartialStateHolder;
-import javax.faces.component.StateHelper;
-import javax.faces.component.StateHolder;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIComponentBase;
-import javax.faces.component.UIForm;
-import javax.faces.component.UINamingContainer;
-import javax.faces.component.UIViewRoot;
-import javax.faces.component.UniqueIdVendor;
+import javax.faces.component.*;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.ComponentSystemEvent;
-import javax.faces.event.ComponentSystemEventListener;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.ListenerFor;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PostValidateEvent;
-import javax.faces.event.PreRenderComponentEvent;
-import javax.faces.event.PreValidateEvent;
+import javax.faces.event.*;
+import java.text.MessageFormat;
+import java.util.*;
-import org.ajax4jsf.component.IterationStateHolder;
-import org.ajax4jsf.model.DataComponentState;
-import org.ajax4jsf.model.DataVisitResult;
-import org.ajax4jsf.model.DataVisitor;
-import org.ajax4jsf.model.ExtendedDataModel;
-import org.ajax4jsf.model.Range;
-import org.richfaces.cdk.annotations.Attribute;
-import org.richfaces.context.ExtendedVisitContext;
-import org.richfaces.log.Logger;
-import org.richfaces.log.RichfacesLogger;
+import static
org.richfaces.component.util.Strings.NamingContainerDataHolder.SEPARATOR_CHAR_JOINER;
/**
* Base class for iterable components, like dataTable, Tomahawk dataList, Facelets
repeat, tree etc., with support for
@@ -81,7 +54,7 @@
*/
@ListenerFor(systemEventClass = PreRenderComponentEvent.class)
public abstract class UIDataAdaptor extends UIComponentBase implements NamingContainer,
- UniqueIdVendor, IterationStateHolder, ComponentSystemEventListener {
+ UniqueIdVendor, IterationStateHolder, ComponentSystemEventListener {
/**
* <p>The standard component family for this component.</p>
@@ -135,7 +108,7 @@
//TODO nick - PSH support?
private DataComponentState componentState = null;
private ExtendedDataModel<?> extendedDataModel = null;
-
+
private Object rowKey = null;
private String containerClientId;
@@ -146,7 +119,6 @@
/**
* @author Nick Belaevski
- *
*/
private final class DataVisitorForVisitTree implements DataVisitor {
/**
@@ -184,12 +156,12 @@
return DataVisitResult.STOP;
}
-
+
if (result == VisitResult.ACCEPT) {
result = visitDataChildrenMetaComponents((ExtendedVisitContext)
visitContext, callback);
if (VisitResult.COMPLETE.equals(result)) {
visitResult = true;
-
+
return DataVisitResult.STOP;
}
}
@@ -265,23 +237,23 @@
* row number in sequence data, but, for example - path to current node in
* tree.
*
- * @param faces -
+ * @param facesContext -
* current FacesContext
- * @param key new key value.
+ * @param rowKey new key value.
*/
public void setRowKey(FacesContext facesContext, Object rowKey) {
this.saveChildState(facesContext);
-
+
this.rowKey = rowKey;
-
+
getExtendedDataModel().setRowKey(rowKey);
-
+
this.containerClientId = null;
boolean rowSelected = (rowKey != null) && isRowAvailable();
setupVariable(facesContext, rowSelected);
-
+
this.restoreChildState(facesContext);
}
@@ -289,7 +261,7 @@
* Save values of {@link EditableValueHolder} fields before change current
* row.
*
- * @param faces
+ * @param facesContext
*/
protected void saveChildState(FacesContext facesContext) {
Iterator<UIComponent> itr = dataChildren();
@@ -299,10 +271,18 @@
}
}
+ protected Iterator<UIComponent> allFixedChildren() {
+ if (getFacetCount() > 0) {
+ List<UIComponent> children = new ArrayList<UIComponent>();
+
+ return getFacets().values().iterator();
+ } else {
+ return Collections.<UIComponent>emptyList().iterator();
+ }
+ }
+
/**
* @param facesContext
- * @param next
- * @param childState
*/
protected void saveChildState(FacesContext facesContext, UIComponent component) {
@@ -378,8 +358,6 @@
* row.
*
* @param facesContext
- * @param next
- * @param childState
*/
protected void restoreChildState(FacesContext facesContext, UIComponent component) {
String id = component.getId();
@@ -389,7 +367,7 @@
SavedState savedState = null;
@SuppressWarnings("unchecked")
Map<String, SavedState> savedStatesMap = (Map<String, SavedState>)
getStateHelper()
- .get(PropertyKeys.childState);
+ .get(PropertyKeys.childState);
if (savedStatesMap != null) {
savedState = savedStatesMap.get(component.getClientId(facesContext));
@@ -433,7 +411,7 @@
protected FacesEvent wrapEvent(FacesEvent event) {
return new RowKeyContextEventWrapper(this, event, getRowKey());
}
-
+
@Override
public void queueEvent(FacesEvent event) {
super.queueEvent(wrapEvent(event));
@@ -447,7 +425,7 @@
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (event instanceof RowKeyContextEventWrapper) {
RowKeyContextEventWrapper eventWrapper = (RowKeyContextEventWrapper) event;
-
+
eventWrapper.broadcast(getFacesContext());
} else {
super.broadcast(event);
@@ -520,9 +498,10 @@
/**
* Boolean attribute that defines whether this iteration component will reset saved
children's state
* before rendering. By default state is reset if there are no faces messages with
severity error or higher.
+ *
* @return
*/
-
+
@Attribute
public boolean isKeepSaved() {
Object value = getStateHelper().eval(PropertyKeys.keepSaved);
@@ -546,7 +525,6 @@
* Changed: does not check for row availability now
*
* @param faces current faces context
- * @param localModel
* @param rowSelected
*/
protected void setupVariable(FacesContext faces, boolean rowSelected) {
@@ -587,7 +565,7 @@
componentState = createComponentState();
if ((componentStateExpression != null)
- &&
!componentStateExpression.isReadOnly(getFacesContext().getELContext())) {
+ &&
!componentStateExpression.isReadOnly(getFacesContext().getELContext())) {
componentStateExpression.setValue(getFacesContext().getELContext(),
componentState);
}
}
@@ -611,7 +589,6 @@
/**
* @param var
* @param attrs
- * @param rowData
*/
private void removeVariable(String var, Map<String, Object> attrs) {
if (var != null) {
@@ -644,7 +621,7 @@
private String getRowKeyAsString(FacesContext facesContext, Object rowKey) {
assert rowKey != null;
-
+
Converter rowKeyConverter = getRowKeyConverter();
if (rowKeyConverter == null) {
// Create default converter for a row key.
@@ -656,18 +633,18 @@
setRowKeyConverter(rowKeyConverter);
}
}
-
+
if (rowKeyConverter != null) {
return rowKeyConverter.getAsString(facesContext, this, rowKey);
} else {
return rowKey.toString();
}
}
-
+
public String getContainerClientId() {
return getContainerClientId(getFacesContext());
}
-
+
@Override
public String getContainerClientId(FacesContext facesContext) {
if (facesContext == null) {
@@ -676,18 +653,18 @@
if (null == containerClientId) {
containerClientId = super.getContainerClientId(facesContext);
-
+
Object rowKey = getRowKey();
-
+
if (rowKey != null) {
String rowKeyString = getRowKeyAsString(facesContext, rowKey);
containerClientId = SEPARATOR_CHAR_JOINER.join(containerClientId,
rowKeyString);
- }
+ }
}
return containerClientId;
}
-
+
/**
* Save current state of data variable.
*
@@ -820,7 +797,7 @@
pushComponentToEL(faces, this);
preDecode(faces);
- this.iterate(faces, decodeVisitor);
+ processDecodesChildren(faces);
this.decode(faces);
popComponentFromEL(faces);
}
@@ -834,7 +811,7 @@
Application app = faces.getApplication();
app.publishEvent(faces, PreValidateEvent.class, this);
preValidate(faces);
- this.iterate(faces, validateVisitor);
+ processValidatesChildren(faces);
app.publishEvent(faces, PostValidateEvent.class, this);
popComponentFromEL(faces);
}
@@ -846,7 +823,7 @@
pushComponentToEL(faces, this);
preUpdate(faces);
- this.iterate(faces, updateVisitor);
+ processUpdatesChildren(faces);
doUpdate();
@@ -854,9 +831,21 @@
}
protected void doUpdate() {
-
+
}
-
+
+ protected void processDecodesChildren(FacesContext faces) {
+ this.iterate(faces, decodeVisitor);
+ }
+
+ protected void processValidatesChildren(FacesContext faces) {
+ this.iterate(faces, validateVisitor);
+ }
+
+ protected void processUpdatesChildren(FacesContext faces) {
+ this.iterate(faces, updateVisitor);
+ }
+
@Override
public void setId(String id) {
super.setId(id);
@@ -886,7 +875,7 @@
if (stateObject != null) {
DataAdaptorIterationState iterationState = (DataAdaptorIterationState)
stateObject;
iterationState.restoreComponentState(this);
-
+
this.componentState = iterationState.getComponentState();
this.extendedDataModel = iterationState.getDataModel();
} else {
@@ -1006,7 +995,7 @@
@Override
public void restoreState(FacesContext context, Object stateObject) {
if (stateObject == null) {
- return ;
+ return;
}
Object[] state = (Object[]) stateObject;
@@ -1039,7 +1028,7 @@
// if clientId.startsWith(baseId + separatorChar)
if (clientId.startsWith(baseId) && (clientId.length() >
baseId.length())
- && (clientId.charAt(baseId.length()) == separatorChar)) {
+ && (clientId.charAt(baseId.length()) == separatorChar)) {
return true;
}
@@ -1047,8 +1036,7 @@
}
@Override
- public boolean invokeOnComponent(FacesContext context, String clientId,
ContextCallback callback)
- throws FacesException {
+ public boolean invokeOnComponent(FacesContext context, String clientId,
ContextCallback callback) throws FacesException {
if ((null == context) || (null == clientId) || (null == callback)) {
throw new NullPointerException();
@@ -1138,6 +1126,91 @@
return found;
}
+ public boolean invokeOnRow(FacesContext context, String clientId, ContextCallback
callback) {
+ if ((null == context) || (null == clientId) || (null == callback)) {
+ throw new NullPointerException();
+ }
+
+ String baseId = getClientId(context);
+
+ if (!matchesBaseId(clientId, baseId,
UINamingContainer.getSeparatorChar(context))) {
+ return false;
+ }
+
+ String rowId = clientId.substring(baseId.length() + 1);
+ if (rowId.indexOf(UINamingContainer.getSeparatorChar(context)) >= 0) {
+ return false;
+ }
+
+
+ Object oldRowKey = getRowKey();
+
+ captureOrigValue(context);
+
+ try {
+
+ setRowKey(context, null);
+
+ Iterator<UIComponent> fixedChildrenItr = fixedChildren();
+
+ while (fixedChildrenItr.hasNext()) {
+ if (checkAllFixedChildren(fixedChildrenItr.next(), rowId)) {
+ return false;
+ }
+ }
+
+ Object newRowKey = null;
+
+ if (rowId != null) {
+ Converter keyConverter = getRowKeyConverter();
+
+ if (null != keyConverter) {
+ try {
+ newRowKey = keyConverter.getAsObject(context, this, rowId);
+ } catch (ConverterException e) {
+ LOG.warn(e);
+ }
+ }
+ }
+
+ setRowKey(context, newRowKey);
+ callback.invokeContextCallback(context, this);
+ } catch (Exception e) {
+ throw new FacesException(e);
+ } finally {
+ try {
+ setRowKey(context, oldRowKey);
+ restoreOrigValue(context);
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+
+ return true;
+
+ }
+
+ private boolean checkAllFixedChildren(UIComponent fixedChild, String id) {
+ if(fixedChild.getId().equals(id)) {
+ return true;
+ }
+
+ if (fixedChild instanceof NamingContainer) {
+ return false;
+ }
+
+ for (UIComponent uiComponent : fixedChild.getChildren()) {
+ if (checkAllFixedChildren(uiComponent, id)) {
+ return true;
+ }
+ }
+ for (UIComponent uiComponent : fixedChild.getFacets().values()) {
+ if (checkAllFixedChildren(uiComponent, id)) {
+ return true;
+ }
+ }
+ return false;
+ }
// Tests whether we need to visit our children as part of
// a tree visit
private boolean doVisitChildren(VisitContext context, boolean visitRows) {
@@ -1185,7 +1258,7 @@
protected VisitResult visitDataChildrenMetaComponents(ExtendedVisitContext
extendedVisitContext, VisitCallback callback) {
return VisitResult.ACCEPT;
}
-
+
protected boolean visitDataChildren(VisitContext visitContext, VisitCallback
callback, boolean visitRows) {
if (visitRows) {
@@ -1244,7 +1317,7 @@
if (visitRows) {
setRowKey(facesContext, null);
}
-
+
if (visitFixedChildren(visitContext, callback)) {
return true;
}
@@ -1258,7 +1331,7 @@
return false;
} else {
VisitContext directChildrenVisitContext =
-
extendedVisitContext.createNamingContainerVisitContext(this, directSubtreeIdsToVisit);
+
extendedVisitContext.createNamingContainerVisitContext(this, directSubtreeIdsToVisit);
if (visitRows) {
setRowKey(facesContext, null);
@@ -1296,7 +1369,7 @@
}
/**
- * @param facesContext
+ * @param context
* @return
*/
private boolean requiresRowIteration(FacesContext context) {
Modified:
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/RenderKitUtils.java
===================================================================
---
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/RenderKitUtils.java 2011-04-27
14:27:41 UTC (rev 22446)
+++
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/RenderKitUtils.java 2011-04-27
17:06:51 UTC (rev 22447)
@@ -21,17 +21,9 @@
*/
package org.richfaces.renderkit;
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.renderkit.ComponentAttribute.Kind;
import javax.faces.application.Application;
import javax.faces.application.Resource;
@@ -45,11 +37,10 @@
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.*;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.ScriptUtils;
-import org.richfaces.renderkit.ComponentAttribute.Kind;
-
/**
* @author Nick Belaevski
*
@@ -797,4 +788,8 @@
}
}
+ public static String getBehaviorSourceId(FacesContext facesContext) {
+ return
facesContext.getExternalContext().getRequestParameterMap().get(BEHAVIOR_SOURCE_ID);
+ }
+
}
Modified:
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java
===================================================================
---
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java 2011-04-27
14:27:41 UTC (rev 22446)
+++
branches/4.0.X/ui/common/ui/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java 2011-04-27
17:06:51 UTC (rev 22447)
@@ -21,12 +21,7 @@
package org.richfaces.renderkit.util;
-import java.util.Map;
-
-import javax.faces.component.UIComponent;
-import javax.faces.component.behavior.ClientBehaviorContext;
-import javax.faces.context.FacesContext;
-
+import com.google.common.base.Strings;
import org.ajax4jsf.component.AjaxClientBehavior;
import org.ajax4jsf.javascript.JSFunctionDefinition;
import org.ajax4jsf.javascript.JSReference;
@@ -35,7 +30,10 @@
import org.richfaces.renderkit.AjaxOptions;
import org.richfaces.renderkit.HtmlConstants;
-import com.google.common.base.Strings;
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.ClientBehaviorContext;
+import javax.faces.context.FacesContext;
+import java.util.Map;
/**
* @author shura
* <p/>
@@ -461,30 +459,31 @@
* Create call to Ajax Submit function with first two parameters
*
* @param facesContext
- * @param uiComponent
- * @param functionName
+ * @param component
* @return
*/
public static AjaxFunction buildAjaxFunction(FacesContext facesContext, UIComponent
component) {
return new AjaxFunction(component.getClientId(facesContext),
buildEventOptions(facesContext, component));
}
+
public static AjaxFunction buildAjaxFunction(ClientBehaviorContext behaviorContext,
AjaxClientBehavior behavior) {
Object source;
-
+
AjaxOptions options = buildAjaxOptions(behaviorContext, behavior);
if (behaviorContext.getSourceId() != null) {
source = behaviorContext.getSourceId();
} else {
source = JSReference.THIS;
-
+
FacesContext facesContext = behaviorContext.getFacesContext();
UIComponent component = behaviorContext.getComponent();
-
- options.set("sourceId", component.getClientId(facesContext));
+
+ options.setAjaxComponent(component.getClientId(facesContext));
+ options.set("sourceId", source);
}
-
+
return new AjaxFunction(source, options);
}
Modified:
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/AbstractTableBaseRenderer.java
===================================================================
---
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/AbstractTableBaseRenderer.java 2011-04-27
14:27:41 UTC (rev 22446)
+++
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/AbstractTableBaseRenderer.java 2011-04-27
17:06:51 UTC (rev 22447)
@@ -22,19 +22,18 @@
package org.richfaces.renderkit;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
+import org.richfaces.component.Row;
+import org.richfaces.component.UIDataTableBase;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
-import org.richfaces.component.Row;
-import org.richfaces.component.UIDataTableBase;
-
/**
* @author Anton Belevich
*
@@ -122,6 +121,7 @@
public void encodeFirstRowStart(ResponseWriter writer, FacesContext context, String
parentId, int currentRow, UIComponent component) throws IOException {
writer.startElement(HtmlConstants.TR_ELEMENT, component);
+ writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, parentId + ":" +
currentRow, null);
String styleClass = concatClasses(getRowClass(context, parentId),
getFirstRowClass(context, parentId), component.getAttributes().get(ROW_CLASS));
if (styleClass.length() > 0) {
writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, styleClass, null);
@@ -134,6 +134,8 @@
public void encodeRowStart(ResponseWriter writer, FacesContext context, String
parentId, int currentRow, UIComponent component) throws IOException {
writer.startElement(HtmlConstants.TR_ELEMENT, component);
+ writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, parentId + ":" +
currentRow, null);
+
String styleClass = concatClasses(getRowClass(context, parentId),
component.getAttributes().get(ROW_CLASS));
if (styleClass.length() > 0) {
writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, styleClass, null);
Modified:
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
===================================================================
---
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2011-04-27
14:27:41 UTC (rev 22446)
+++
branches/4.0.X/ui/iteration/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2011-04-27
17:06:51 UTC (rev 22447)
@@ -24,22 +24,23 @@
import org.ajax4jsf.javascript.JSFunction;
import org.richfaces.cdk.annotations.JsfRenderer;
-import org.richfaces.component.AbstractCollapsibleSubTable;
-import org.richfaces.component.AbstractDataTable;
-import org.richfaces.component.Row;
-import org.richfaces.component.UIDataTableBase;
+import org.richfaces.component.*;
import org.richfaces.component.util.HtmlUtil;
import org.richfaces.renderkit.util.AjaxRendererUtils;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
+import javax.faces.component.ContextCallback;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
/**
@@ -54,6 +55,9 @@
})
public class DataTableRenderer extends AbstractTableRenderer {
+ private static final String BEHAVIOR_EVENT_NAME =
"javax.faces.behavior.event";
+ private static final String ROW = "row";
+
private class DataTableHiddenEncodeStrategy implements EncodeStrategy {
public void begin(ResponseWriter writer, FacesContext context, UIComponent
component, Object[] params) throws IOException {
AbstractDataTable dataTable = (AbstractDataTable)component;
@@ -82,7 +86,48 @@
public void end(ResponseWriter writer, FacesContext context, UIComponent
component, Object [] params) throws IOException {
}
}
-
+
+ protected void doDecode(FacesContext context, final UIComponent component) {
+ super.doDecode(context, component);
+
+ if ((null == context) || (null == component)) {
+ throw new NullPointerException();
+ }
+
+ if (component instanceof ClientBehaviorHolder) {
+ final Map<String, List<ClientBehavior>> behaviors =
((ClientBehaviorHolder) component).getClientBehaviors();
+
+ if (behaviors == null || behaviors.isEmpty()) {
+ return;
+ }
+
+ Map<String, String> parametersMap =
context.getExternalContext().getRequestParameterMap();
+ final String behaviorEvent = parametersMap.get(BEHAVIOR_EVENT_NAME);
+
+ if (!behaviorEvent.startsWith(ROW)){
+ return;
+ }
+
+ String behaviorSourceId = RenderKitUtils.getBehaviorSourceId(context);
+
+ ((UIDataAdaptor) component).invokeOnRow(context, behaviorSourceId, new
ContextCallback() {
+
+ public void invokeContextCallback(FacesContext context, UIComponent
target) {
+ if (target.equals(component)) {
+ List<ClientBehavior> behaviorsForEvent =
behaviors.get(behaviorEvent);
+ if (behaviorsForEvent != null &&
!behaviorsForEvent.isEmpty()) {
+ for (ClientBehavior behavior : behaviorsForEvent) {
+ behavior.decode(context, component);
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+
+
public void encodeTableStructure(ResponseWriter writer, FacesContext context,
UIDataTableBase dataTable)
throws IOException {
if (dataTable instanceof AbstractDataTable) {