on 12-07-2010 8:25 PM
I have searched blogs, tried different creative search terms in this forum, followed every link, even performed a general internet search and still my Web Dynpro Java table filter is not working.
I have tried Peter Vignet's solution, parsed out the text posted by at least two other contributors, and still no success.
I have confirmed my 'source' node and 'table' node are populated, and verified their cardinality as collection = 0..n and selection = 0..1
I have checked the cardinality on my 'filter' node and it is collection = 1..1 and selection = 0..1
My 'filter' node elements are of type string.
I have bound my table to my 'table' node, and bound each column to its corresponding filter element.
I have recreated my table using standard columns insteand of grouped columns.
And after all this and more, my table has a filter row but does not perform a filter action when I enter a criteria value.
Anything else I can check? Ideas? Hints?
My platform is NW7.0 EHP1 SR3
Hi,
Please post the code of invoking filter. What are the column data types?
Please ensure, you are copying the source node to duplicate node.
Regards
Saravanan K
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
First of all, thank you, Saravanan and Nizamudeen for taking an interest in my issue.
In answer to your questions:
Saravanan - Yes - I am copying the source node to duplicate node.
Nizamudeen - I was not receiving error until I discovered my table node Primary property binding was pointing to my original source model node (I am using WDCopy service to move values to my source node, then copying again to my data node.) Once I reconstructed my context nodes and attributes to ensure there was no binding to the model node, I began to see runtime errors:
500 Internal Server Error
SAP NetWeaver Application Server 7.00/Java AS 7.00
..
Failed to process request. Please contact your system administrator.
...
Root Cause
The initial exception that caused the request to fail, was:
...
java.lang.IllegalArgumentException:
at com.sap.tc.webdynpro.clientserver.data.DataContainer.createLocalPath(DataContainer.java:1359)
at com.sap.tc.webdynpro.clientserver.data.DataContainer.updateAttribute(DataContainer.java:454)
at com.sap.tc.webdynpro.clientserver.uielements.adaptbase.AbstractAdapter.updateAttribute(AbstractAdapter.java:671)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter$FilterField.onINPUTFIELDCHANGE(TableAdapter.java:4271)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter$FilterField.onINPUTFIELDKEYPRESS(TableAdapter.java:4509)
... 48 moreHere is my current version of TableFilter.java:
/** * Helper class that makes a Web Dynpro table UI element filterable (column-wise). */
public final class TableFilter {
/** * Creates a table filter for the given table using the given filter action.
This constructor must be called from wdDoModifyView(), but
* usually only when that hook is called for the first time. Store the newly
* created instance in a context attribute with Java native type
* com.sap.tc.webdynpro.tests.utils.TableFilter.
* The given filter action's event handler will be bound to the onAction
* event of filter columns and must at least call this table filter's
* filter(wdEvent) method. * * When a table is made filterable its onAction event (incl.
* parameter mapping) is changed. Furthermore if a header is present for that
* column then the header's imageSource property is also changed
* to indicate the currently filtered column.
* * @see filter()
* @see com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTable */
public TableFilter(IWDTable table, IWDAction filterAction) {
this.table = table;
// sanity checks
if (filterAction == null)
throw new IllegalArgumentException("Filter action must be given");
if (table == null)
throw new IllegalArgumentException("Table must be given");
if (table.bindingOfDataSource() == null)
throw new IllegalArgumentException(
"Data source of table with id '"
+ table.getId()
+ "' must be bound");
String dataSourcePrefix = table.bindingOfDataSource() + ".";
int index = 0;
//for (Iterator it = table.iterateColumns(); it.hasNext(); ++index)
for (Iterator it = table.iterateGroupedColumns();
it.hasNext();
++index) {
// for every column: try to make it bindable
IWDTableColumn column = (IWDTableColumn) it.next();
// attribute must be determined
String bindingOfPrimaryProperty =
bindingOfPrimaryProperty(column.getTableCellEditor());
if (bindingOfPrimaryProperty == null
|| !bindingOfPrimaryProperty.startsWith(dataSourcePrefix))
continue;
// no attribute found or outside of data source
String attributeName =
bindingOfPrimaryProperty.substring(dataSourcePrefix.length());
if (attributeName.indexOf('.') >= 0)
continue;
// attribute not immediately below data source
table.setOnFilter(filterAction);
}
}
/** * This method must be called from the event handler of this table filter's
* filter action. It performs the actual filter operation. */
public void filter(
IWDCustomEvent wdEvent,
IWDNode dataSource,
IWDNode originalSource,
IWDNode filterNode,
IWDMessageManager manager) {
// find the things we need
String refinedFilter = null;
String field = null;
String attributeName = null;
String bindingOfPrimaryProperty = null;
String dataSourcePrefix = table.bindingOfDataSource() + ".";
manager.reportSuccess("variable dataSourcePrefix = " + dataSourcePrefix);
//dataSourcePrefix = "Table.";
//manager.reportSuccess("Change dataSourcePrefix = 'table'");
IWDAbstractTableColumn[] columns = table.getGroupedColumns();
String path = null;
String attribute = null;
StringTokenizer tokenizer = null;
dataSource.invalidate();
WDCopyService.copyElements(originalSource, dataSource);
int totalElements = originalSource.size();
manager.reportSuccess("variable totalElements = " + totalElements);
for (int i = totalElements - 1; i >= 0; i--) {
IWDNodeElement element = dataSource.getElementAt(i);
for (int j = 0; j < columns.length; j++) {
IWDTableColumn colmn = (IWDTableColumn) columns[j];
bindingOfPrimaryProperty =
bindingOfPrimaryProperty(colmn.getTableCellEditor());
if (bindingOfPrimaryProperty != null
&& bindingOfPrimaryProperty.startsWith(dataSourcePrefix)) {
attributeName =
bindingOfPrimaryProperty.substring(
dataSourcePrefix.length());
}
//manager.reportSuccess("variable bindingOfPrimaryProperty = " + bindingOfPrimaryProperty);
//manager.reportSuccess("variable attributeName = " + attributeName);
try {
if (attributeName.indexOf('.') < 0)
field = element.getAttributeAsText(attributeName);
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//manager.reportSuccess("variable field = " + field);
if (colmn.bindingOfFilterValue() != null) {
path = colmn.bindingOfFilterValue();
manager.reportSuccess("variable path = " + path);
tokenizer = new StringTokenizer(path, ".");
while (tokenizer.hasMoreTokens()) {
attribute = tokenizer.nextToken();
}
refinedFilter =
refineFilterString(
filterNode.getCurrentElement().getAttributeAsText(
attribute));
if (!(field.matches(refinedFilter))) {
dataSource.removeElement(element);
}
}
}
}
// for(int j =0; j < columns.length; j++ )
// {
// IWDTableColumn colmn = (IWDTableColumn) columns[j];
//
// bindingOfPrimaryProperty = bindingOfPrimaryProperty(colmn.getTableCellEditor());
//
// if(bindingOfPrimaryProperty != null
// && bindingOfPrimaryProperty.startsWith(dataSourcePrefix)){
// attributeName = bindingOfPrimaryProperty.substring(dataSourcePrefix.length());
// }
//
// refinedFilter = refineFilterString(filterNode.getCurrentElement().getAttributeAsText(attributeName));
//
// if (refinedFilter.equals(".*"))
// colmn.getHeader().setImageSource(null);
// else
// if (colmn.getHeader() != null)
// colmn.getHeader().setImageSource("~sapicons/s_b_filt.GIF");
// else
// colmn.getHeader().setImageSource(null);
// }
}
/** * Returns the binding of the given table cell editor's property that is
* considered "primary" or null if no such binding exists or no
* such property can be determined. */
private static final String bindingOfPrimaryProperty(IWDTableCellEditor editor) {
return editor instanceof IWDViewElement
? bindingOfPrimaryProperty((IWDViewElement) editor)
: null;
}
/** * Returns the binding of the given view element's property that is
considered "primary" or null if no such binding exists or no
* such property can be determined. */
private static final String bindingOfPrimaryProperty(IWDViewElement element) {
if (element instanceof IWDAbstractDropDownByIndex)
return ((IWDAbstractDropDownByIndex) element).bindingOfTexts();
if (element instanceof IWDAbstractDropDownByKey)
return ((IWDAbstractDropDownByKey) element).bindingOfSelectedKey();
if (element instanceof IWDAbstractInputField)
return ((IWDAbstractInputField) element).bindingOfValue();
if (element instanceof IWDCaption)
return ((IWDCaption) element).bindingOfText();
// if (element instanceof IWDCheckBox)
// return ((IWDCheckBox) element).bindingOfChecked();
if (element instanceof IWDLink)
return ((IWDLink) element).bindingOfText();
if (element instanceof IWDProgressIndicator)
return ((IWDProgressIndicator) element).bindingOfPercentValue();
if (element instanceof IWDRadioButton)
return ((IWDRadioButton) element).bindingOfSelectedKey();
if (element instanceof IWDTextEdit)
return ((IWDTextEdit) element).bindingOfValue();
if (element instanceof IWDTextView)
return ((IWDTextView) element).bindingOfText();
//if (element instanceof IWDImage)
// return ((IWDImage)element).bindingOfAlt();
return null;
}
/** * Instance of a comparator according to the ordering imposed by the
implementation of Comparable. */
private static final Comparator DEFAULT = new Comparator() {
/** * Compares the given objects according to the ordering imposed by the first
ones compareTo(Object) function. Furthermore, null
is treated to be less than any object.
* @see java.lang.Comparable#compareTo(java.lang.Object)
@see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */
public int compare(Object o1, Object o2) {
if (o1 == null && o2 == null)
return 0;
if (o1 == null)
return -1;
if (o2 == null)
return +1;
return ((Comparable) o1).compareTo((Comparable) o2);
}
};
Hello jennifer,
Same Clarification.
Is the Filter node cardinality is 1....1?
is the filter node attributes are of type string?
Are you binding the data source in the table instead of original node?
The code which i am asking is the code which you have written in your View i.e., your code to enable the filter row and your code to pass values to the filter method?
Can you post that.
Regards
Nizamudeen SM
I'll try and give better answers this time:
Is the Filter node cardinality is 1....1? ---> Yes
is the filter node attributes are of type string? ---> Yes
Are you binding the data source in the table instead of original node? ---> Yes
The code which i am asking is the code which you have written in your View i.e., your code to enable the filter row and your code to pass values to the filter method?
//@@begin wdDoModifyView
if (firstTime) {
// define TableSorter variables
// identify table to be sorted
IWDTable table = (IWDTable) view.getElement("tbl_MyNotifs");
// create TableSorter instance for specified table
wdContext.currentContextElement().setTableSorter(
new TableSorter(table, wdThis.wdGetSortAction()
, null, null));
// This corresponds to Peter Vignet's TableFilter.java
wdContext.currentContextElement().setTableFilter(
new TableFilter(table, wdThis.wdGetFilterAction(),
wdContext.nodeSource(),null));
}
//@@end
//@@begin onActionfilter(ServerEvent)
wdContext.currentContextElement().getTableFilter().filter(
wdContext.nodeSource(),wdContext.nodeTable());
//@@end
Hello Jennifer,
Please check the code below.
ModifyView
{
wdContext.currentCommonElement().setTableName((IWDTable)view.getElement("ListTable"));
wdContext.currentCommonElement().setTableFilter(new TableFilter(wdContext.currentCommonElement().getTableName(),wdThis.wdGetFilterListAction()));
wdContext.currentCommonElement().getTableName().getOnFilter().setEnabled(false);
}
On click of Filter Button
//Enable filter
wdContext.currentCommonElement().getTableName().getOnFilter().setEnabled(true);
wdContext.nodeListFilter().invalidate(); //Invalidating Filter Node (1...1)
//On Action of Filter List - Pressing Enter in Filter Row
wdContext.currentCommonElement().getTableFilter().filter(wdEvent,wdContext.nodeListSrc(),wdContext.nodeList(),wdContext.nodeListFilter(),messageManager);
wdContext.nodeListSrc() - Source node bind to Table
wdContext.nodeList() - Orignial Node
wdContext.nodeListFilter () - Filter Node.
try and confirm us
Regards
Nizamudeen SM
Where do I place code for on click of filter button? The filter icon in the filter row appears to be created dynamically, and I don't see a similar method in the TableFilter.java class file? I am using NWDS 7.0 EHP1 SR3
Please disregard the quesion about where to place on click code for the filter icon - I understand that is the code executed by the onFilter action of the table element. Since I have named my action, 'filter' my method is onActionfilter.
With that in mind, should I have a distinct method to handle the on enter event of the filter row? I haven't found any material that suggests that yet. And are there any other table column parameters that need to be set? I am a bit confused by the 'isFiltered' property.
Edited by: Jennifer Mansker-Bickel on Dec 10, 2010 11:16 AM
It is clear that I have analyzed this issue as far as possible without use of debugger. My next step will be to try and get my local portal instance functional so I can deploy to it and debug.
Thank you so very much to every one who took the time to assist me. It is very much appreciated.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
its working for us in my project.
we had used the below readymade Filter javafile in our project check the below link in tablefilters headlin
[http://wiki.sdn.sap.com/wiki/display/WDJava/WelcometoWebDynproJava%21]
hope it willl help u
Regards,
Govindu
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Jennifer,
1. Can you post the code which you have written to EnableFilter, also for the filter event? So that we will have a fair idea.
2. Are you getting any error?
Three nodes are required,
1. Src Node which contains the actual data.
2. Table Node which is the copy of the Src Node and bind this node to the table.
3. Filter node with 1...1 Cardinality and all the attributes of type string.
Revert for any queries.
Regards
Nizamudeen SM
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Our Basis team will not allow debugging on our development server. If you have ideas about placement of print statements, I'd be glad to try them.
Any other suggestions?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for finding that odd. Maybe someone from our Basis team will read this thread and think maybe our standard operating procedure isn't quite so standard. We have other restrictions that would also make you scratch your head.
I usually run my own local portal instance for this very reason, but I have new equipment and haven't completely configured my local portal for deployment.
I suggest that you talk to your manager. If a developer is not allowed to use a debugger in a development system, something is wrong in your organization.
Regarding your issue: check the data binding of the filter fields. The stack trace indicates that after pressing ENTER inside some filter field the WD runtime cannot access the corresponding context data.
I continue to be baffled by this error:
The initial exception that caused the request to fail, was:
java.lang.IllegalArgumentException:
at com.sap.tc.webdynpro.clientserver.data.DataContainer.createLocalPath(DataContainer.java:1359)
at com.sap.tc.webdynpro.clientserver.data.DataContainer.updateAttribute(DataContainer.java:454)
at com.sap.tc.webdynpro.clientserver.uielements.adaptbase.AbstractAdapter.updateAttribute(AbstractAdapter.java:671)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter$FilterField.onINPUTFIELDCHANGE(TableAdapter.java:4271)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter$FilterField.onINPUTFIELDKEYPRESS(TableAdapter.java:4509)
... 48 more
My table columns all have their filterValues bound to the FilterTable node elements, I have even tried initializing the FilterTable node in wdDoInit.
I have reverted my TableFilter.java code to Peter Vignet's original but the result is the same.
What am I missing?
Use the debugger to check what is going on.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
90 | |
10 | |
10 | |
10 | |
7 | |
7 | |
6 | |
5 | |
4 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.