Skip to Content

Java Web Dynpro Table Filter

Introduction

Web Dynpro Table offers a Table Sorter java Class that can be directly used to sort any table with very few lines of coding. It is powerful tool , easy to implement and use. Web Dynpro Table offers also a filtering possibility through the filtering row that allows filter input. The Filtering row is the first row. Only the UI is provided, the filtering action is not. The logic of the filter process is not implemented in Web Dynpro. The application developer must implement the filtering action to be executed (see SAP UI Web Dynpro Table documentation). The Java Class described below intends to offer a filtering tool as easy to implement and to use as the Table Sorter Java Class.

Table Filter

The Java Web Dynpro TableFilter is a Java class. It filters the column of a table according the filter value located at the top of a column. It can be implemented in few steps. Figure 1:
image
Here is an example of filtering using the TableFilter java class Figure 2:
image
When the TableFilter’s filter action is triggered, the filter method passes two nodes. The first node contains all the data and the table’s node, the node that shows the data. The TableFilter populates the table node from the all data node according the filter values. Filtering is done for each filter value of each column , only the row matching all the filters are shown.

Filtering Capabilities:

The table filter has the following capabilities:
Strings : if the filter value is a “a” it returns any fields that as a “a” , what ever is the position of the a in the string and does not makes difference between upper case and lower case. It also accepts the # (exclude) or (=) include sign in first position.
Numeric values , dates, times: It filters for the exact value, a range(~) , include(=) , exclude(#) sign. The include or exclude sign should be in first position.
For range “~100”, gives the values up to 100 included;”1~100” gives all values between 1 and 100 , 1 and 100 included;” 100~” gives all the values about 100 , 100 included
Boolean values: Booleans can be filtered using include (=) or exclude (#).
Icons: Icons can be filtered according their legends. Legend is language dependant. Icon legends can be shown as a tool tip of the icon.

Quick Steps for Default Implementation:

First we will speak about the quick default implantation. Then we will see how we can improve the default implementation. The default implementation assumes that the table node is a value node and drop down and icons if any in the table are not filtered and no columns are updatable.

Step 1: Add TableFilter

Add the table filter to the package. Figure 3
image

Step 2: Create Nodes

The filter table needs 3 nodes (see Figure 4 below): One table node, on filter node, one all data node. All these nodes should be under the root node context. The All data node contains always all the data , it is called in the figure below “sourceNode” . The “FilterNode” contains the filter values. The attributes of the SourceNode & TableNode are identical. They have the same attribute names; and the attributes with the same name are of the same type. The Filter node is of cardinality 1,1 and contains the values of the filter , one attribute per column you want to filter. All the filter attributes are of type string. Figure 4:
image

Step 3: Associate Filter to Column

Each column that you want to filter must have a filter.Figure 5:
image

Step 4: Create Table Filter in Context View

In the view controller create a context attribute “TableFilter” . Its type is TableFilter. Figure 6:
image
The details steps to do it are :
The type is chosen by selecting the “…” button . Figure 7:
image
Then select button Java Native Type & Browse button: Figure 8:
image

Step 5: Create filter Action

Go to the Actions tab and create an action with the name filter.Figure 9:
image

Step 6: Code Filter Action

Go to the implementation tab and under the onActionFilter() put the following code:
public void onActionfilter(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) {
//@@begin onActionfilter(ServerEvent)
wdContext.currentContextElement().getTableFilter().filter(wdContext.nodeSource(), wdContext.nodeTable());
//@@end
}

Step 7: Code wdDoModifyView

Switch to the method wdDoModifyView and enter the following source code:
public static void wdDoModifyView(IPrivateTableFilterCV wdThis, IPrivateTableFilterCV.IContextNode wdContext, com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime) {
//@@begin wdDoModifyView
if (firstTime ) {
IWDTable table = (IWDTable) view.getElement("Table");
wdContext.currentContextElement().setTableFilter( new TableFilter(table, wdThis.wdGetFilterAction(), wdContext.nodeSource(),null));
}
//@@end
}

“Table” is the id of the UI table Figure 10:
image
At the first time wdDoModifyView initialize the table filter. The constructor of the table filter for each column finds the associated filter and the needed comparator to perform the column filtering.

Step 8: Add explanation:

Add an explanation of the filter’s capabilities above you table Figure 11:
image
The text could be like this: Character fields are filtered for any character in the field, include =, exclude #. Numeric , Date fields can be filtered for exact value, range ~ , exclude # ; Check boxes can be filtered for include = or exclude #; Icon by legend.

Improving the Default Implementation

The default implementation can be improved to filter icons, dropdown, and update the All data node , if the table has been updated or if the table had some rows that have been added or deleted.

Filtering Icons

A icon is filtered according its legend., you need in the all data node and the table node a attribute for the legend icons (legend icon are language dependent and will have to be translated) so in the TableFilter constructor the last parameter is a hashtable that indicates the mapping between the icon column ids and the icon legend attribute.
The constructor becomes:
if (firstTime ) {
// mapping of the icon column to the legend column{
Hashtable hash=new Hashtable(); hash.put("Icon","IconLegend");
// table constructor has the hash table as a parameter
IWDTable table = (IWDTable) view.getElement("Table");
wdContext.currentContextElement().setTableFilter( wdContext.currentContextElement().setTableFilter( new TableFilter(table, wdThis.wdGetFilterAction(), (IWDNode)wdContext.nodeSource(),hash));
}

The logic is explained by the figures 12 & 13. Figure 12:
image

Figure 13:
image

The result is Figure 14:
image

Warning : Never make a column legendIcon in the table. The reason is that at initialization of the TableFilter will automatically associate the legendIcon column with the legendIcon attribute. The icon mapping given by the hashtable will be disregarded. Figure 15:
image

Filtering Drop Down :

Since drop down shows text but the column value is a key, the filtering must be done the same way the icon filtering is done. This means that at the initialization, the hashtable indicates a mapping between the drop down column and the node attribute to filter. In our example the column shown is owner, but the filtering is done on the attribute ownertext.

Updating the “All Data Node” from the Table Node

Default implementation does not update the all data node. If the table is updatable, and some data are updated, or some rows are added or deleted, the TableFilter does not update the all data node, the “sourceNode” in our example.. The DC has to do the update if the default implementation is used as is, as explained by the Figure 16:
image

If the table has be updated or if some rows have been added or deleted. The All data node needs to be updated from the table node. TableFilter has currently two methods that are doing that. To update the “All Data Node” from the table node , each method has to know what attribute is the unique identifier of the element (this identifier cannot be the element index because it will not work in case of deleting and adding rows) . Figure 17 shows an attribute “Row Unique ID” that identify uniquely an element
image

The method to update is:

public void updateAllDataNodeElment( IWDNode sourceNode, IWDNode targetNode, String attributeRowId, boolean addRowOnFly);

String attributeRowId : is the attribute name that uniquely identify the rowed, this attribute is of type String.
Boolean addRowonFly : if a row has been added in the table not only the updated existing row will be updated in AllDataNode but if a row has been created, if the flag is set to true a new element is created in the AllDataNode.
The method to delete is:

public void deleteAllDataNodeElement(IWDNode sourceNode, IWDNode targetNode, String attributeRowId, ArrayList idsToDelete)
String attributeRowId : is the attribute name that uniquely identify the row, this attribute is of type String.
ArrayList idsToDelete: contains a list of the unique row identifier to delete.

Coming back to our example , the table has now three buttons “Update”,“Add “ & “Delete ” for adding or deleting a row.
First we update the first row , we change the integer column from 1000 to 1, By pressing the button update and directly invoking the method updateAllDataNodeElment , the all data node is updated and so the table can be filtered and this new value will be taken into account. Figure 18 :
image
If we have drop downs to update before invoking the updateAllDataNodeElment method, the table attribute “Ownertext” should be updated accordingly. Figure 19:
image

Continuing with our example , using the button “Add” adds a new row to the table, the “Add” button action invokes at the end the updateAllDataNodeElment with the boolean addRowOnFly= true that update the all data node .Figure 20 shows that a new row has been added at the end of the table:
image
Since the all data node has been updated, a new filtering takes into account the new row. Figure 21:
image

Inversely, by selecting motile rows and pressing the “Delete “ button the deleteAllDataNodeElement method is invoked and the row are deleted from the table node and the all data node. Figure 22:
image
So the next filtering will be accurate and take into account the fact that some rows have been deleted. Figure 23:
image

Tips & Trick:

If the data of the AllDataNode are not changed:
If you initiate the TableFilter with the AllDataNode fully populated , and the data are not changed , when using the filter action, you can pass a null instead of a the AllDataNode, the method will retrieve the data from the AllDataNode you pass at the initialization. Or the last time you passed it through the filter action.

TableFilter Class Code

To report this post you need to login first.

18 Comments

You must be Logged on to comment or reply to a post.

  1. Matthias Ostermaier
    Hi folks,

    this table filter will also work for NW04 when you comment out or remove all NW2004s-specific code lines.

    Concretely speaking, these are all lines where the flag “IsFiltered” is set on a table column and where a distiction between table classes is made. (IWDAbstractTableColumn, IWDTableColumn, IWDGroupedColumn). NW04 only knows the type IWDTableColumn.

    However I stumbled on a little “bug” (given that I didn’t misunderstand anything): In the blog, the constructor of TableFilter is called with a null-value for the argument “hashicons”.

    In my case, this leads to a NullPointerException in setFilterForColumns() where it says if (hashIcon.containsKey(columnId)). So maybe others might accomodate this line as well to avoid runtime errors.

    Best regards,
    Matthias Ostermaier

    (0) 
    1. Peter Vignet Post author
      Matthias:
      To fix the bug of
      if (hashIcon.comtainsKey(columnId). I see the one of the following ways:

      a) check if the hashIcon is not null before
      (small code change required)
      or b) give to the constuctor an empty hashtable ( no code change required)
      Thanks, Best regards

      (0) 
  2. Stefan Kuster
    Hi, this blog is great. Unfortunately I can’t get the TableFilter work.

    Is there somewhere a example project for NW 2004s with a working TableFilter?

    In wdDoModifyView I have the following code:
    if (firstTime)
    {
    IWDTable table = (IWDTable)view.getElement(“Table”);
    wdContext.currentContextElement().setTableFilter(new TableFilter(table, wdThis.wdGetFilterAction(), wdContext.nodeSearchResults(),null));
    }

    In the Action onActionFilter is this code:
    wdContext.currentContextElement().getTableFilter().filter(wdContext.nodeSearchResults(), wdContext.nodeSearchResultsFiltered());

    The Filer line is visible in the WebDynpro Table, but the filter doesn’t do anything. I always see the same data.

    Can anybody help me please?

    E-Mail please to: cirhmkp02@sneakemail.com

    Thanks,
    Stefan

    (0) 
  3. Reena Wadhwa
    Hi,
    Blog is really very helpful and owrking fine for me.
    But the filter given in this blog is case sensitive. can you help me in changing it to case insensitive filter

    Thanks

    (0) 
    1. Peter Vignet Post author
      Hi Reena

      The filtering is done by a simple java comparator.
      For me the  filter is not case sensitive , it filters the same way if you enter  upper or lower case .
      I use SAP NetWeaver Developer Studio
      Version: 7.0.10
      May be you use a different version  NetWeaver Developer Studio.

      Thanks, regards,
      Peter

      (0) 
  4. Apurva Maduskar
    Hi,

    Thank you.
    The blog is very helpful.

    I am facing one problem regarding date format.
    Filter for column with date field is working only if filter value is entered in the format MM/dd/yyyy. Its not working for any other format like dd.MM.yyyy. What can be done so as to convert entered date into required format?

    Regards,
    Apurva

    (0) 
    1. Peter Vignet Post author
      Hi Apurva:

      -All dates are of java.sql. type.
      -All dates are set to a SimpleDateFormat(“yyyy-MM-dd”); before being filtered
      -All dates filtered are filtered using a simple java comparator:(Object o1, Object o2)
      – Dates and times are automatically formatted according the setting parameters of the current locale session.
      Please verify that your dates are of type java.sql  and also verify your
      Version of SAP NetWeaver Developer Studio. I use version 7.0.10 .

      I heard that a German colleague has updated the code for the newer version of SAP NetWeaver Developer.

      Thanks
      Best regards
      Peter

      (0) 
  5. Ashok D
    Hi Peter,

    Thanks for this nice blog.

    I have a question .Character search results in all entries no matter what the position of character.If I want to search for records beginning with 123 but not ending with 123.?is their a expression.

    (0) 
    1. Peter Vignet Post author
      Hi Ashok
      As explained in the paragraph filtering capabilities, for a string, the filtering has included or exclude, it does not look for a position in the string.

      Filtering Capabilities:
      The table filter has the following capabilities:
      Strings : if the filter value is a “a” it returns any fields that as a “a” , what ever is the position of the a in the string and does not makes difference between upper case and lower case. It also accepts the # (exclude) or (=) include sign in first position.
      Numeric values , dates, times: It filters for the exact value, a range(~) , include(=) , exclude(#) sign. The include or exclude sign should be in first position.
      For range “~100”, gives the values up to 100 included;”1~100” gives all values between 1 and 100 , 1 and 100 included;” 100~” gives all the values about 100 , 100 included
      Boolean values: Booleans can be filtered using include (=) or exclude (#).
      Icons: Icons can be filtered according their legends. Legend is language dependant. Icon legends can be shown as a tool tip of the icon.

      Thanks, Regards,

      (0) 
  6. Marcelo Almeida
    I have a problem when I put some information that doesnt exist.
    Example: I have a columm that have numbers to 1 until 5. When I fill out with numbers between this range, the filter works. But if I put 6 I get this message error:

    java.lang.NullPointerException

    at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TextViewAdapter.getSelection(TextViewAdapter.java:1215)
        at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:424)
        at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:133)

    (0) 
  7. Mahaboob Hussain
    Hello,

    if i had a column with values (a, ht ,at,bt, t, tt, at, ta, tah, ttt).
    If I filter the column with letter ‘t’ .The filtering is working but the displayed result is not in a order.

    Resulted Filter order displayed: at, t, at, ta, tt tah, tt)
    which doesn’t give any order. it would be a good blog if the resulted filter values dispaly in a order.

    Order should be like
    1) all rows with first letter t
    2) all rows with second letter t
    3) all rows with third letter t
    4) so on till the last letter is t in the value

    good resulted order: t, ta, tah, tt, tt, at, at

    Thanks
    Maha
    mahaboob.ep@gmail.com

    (0) 
    1. Mahaboob Hussain

      values in Column: (a, ht ,tt, at, bt, t, tt, at, ta, tah, ttt)

      when filter a column with letter ‘t’

      currently Displayed order(using blog): at, t, ht, at, bt, tt, ta, tt tah, ttt)

      Best order to display:  t, ta, tah, tt, tt, ttt, at, at, bt, ht

      (0) 
  8. alok parija
    I am using the filter class, i am getting an error in the class where the Hashtable has been instanciated. Is there a missing bracket or something like this? please help.
    (0) 

Leave a Reply