cancel
Showing results for 
Search instead for 
Did you mean: 

Add Filter in a Table.

Former Member
0 Kudos

Hi All,

I am new to webDynpro so dont know whether I am going right with the approach or not, please guide me. I have created a table and getting the data directly in the view Context. My hierarchy is like:

Context

-- <b>FilterValues</b> (Node)

-Filter_A (Attribute)

-Filter_B

-Filter_C

-Filter_D

|-- <b>FromBackEnd</b>(Node)

|-Col_A (Attribute)

|-Col_B

|-Col_C

|-Col_D

I am getting the data displayed in the table correctly. Now I want to add filter to this table, So I added new node FilterValues in which I have added the attributes for filtering the columns.

Now I have created one action, say <i>Filter</i> and mapped the Table <b>onFilter</b> value with this action <i>Filter</i>, Also I have mapped the values of the <b>FilterValue</b> of the table column with the Values like (FilterValues.Filter_A,FilterValues.Filter_B etc.. )

I have reffered to the weblog:

<a href="/people/subramanian.venkateswaran2/blog/2005/05/10/filtering-table-values-using-webdynpro Table Values using WebDynpro</a>

Here, Subramanian has written a code for:

<b>//Step 1 -> Creating a link to the values present in custom controller

IUserlistNode myValues =

wdThis.wdGetCC_TableController().wdGetContext().nodeUserlist();</b>

but I am not using the custom Controller here. So where will I get the value of this <b>myValues</b> object.

Please help me with this, I am stuck with this problem since quite a long.

Regards

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi,

In the weblog i guess he has created a Custom Controller or might be using Component Controller. If u also have created it and not getting it in the view then, go to Propertied tab of the view and add the Controllers. U will find an 'add' button.

Regards,

Piyush.

Answers (1)

Answers (1)

Former Member
0 Kudos

SDN Help,

Welcome to SDN forums (nice nick, btw

In your case code should be:


IPrivate<NameOfView>.IFilterValuesNode myFilter =
wdContext.nodeFilterValues();

IPrivate<NameOfView>.IFromBackEndNode myValues =
wdContext.nodeFromBackEnd();

VS

pravesh_verma
Active Contributor
0 Kudos

Hi,

First of thanks for the reply.

@Piyush, I am not using any custom controller, and dont want to use it either. I am getting the data diecrly in the view Controller. I know this is not the recommended way to work, but this is a prototype which I am making. So can work around with it.

@ Valery, Thanks for the reply. Now I could atleast get the values again in the table. Previously I could not get that when I have added this filter.

<b>But</b> Guys, still my filter is not working. As I click the filter it gives me the error: <b>java.lang.IndexOutOfBoundsException</b> .. What may be the reason??

Regards

Sorry, I have to use my TEAM-ID, but by mistake I have used my personal-ID.

Former Member
0 Kudos

Pravesh,

Make sure FilterValues node has cardinality 1..1, and selection 1..1.

VS

Former Member
0 Kudos

Hi Valery,

Ok now there is no error but Filtering is not working.

I am attaching the code with the post:

public void onActionFilter(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )
  {
    //@@begin onActionFilter(ServerEvent)
  	
  	IPrivateServiceFacadeView.IFilterValuesNode myFilter = wdContext
				.nodeFilterValues();
		IPrivateServiceFacadeView.IFromBONode myValues = wdContext.nodeFromBO();

		int sizeElement = myFilter.size();

		String filterCountryID = wdContext.currentFilterValuesElement()
				.getFilter_CountryID();//has to be changed if the elements are
									   // mapped directly under the main context
		int size = wdContext.nodeFromBO().size();

		for (int i = sizeElement - 1; i >= 0; i--) {
			IPrivateServiceFacadeView.IFromBOElement myElements = wdContext
					.nodeFromBO().getFromBOElementAt(i);
			wdContext.nodeFromBO().removeElement(myElements);
		}

		for (int i = size - 1; i >= 0; i--) {
			String value = (String) myValues.getElementAt(i).getAttributeValue(
					"CountryID");
			if (value.matches(filterCountryID)) {
				IPrivateServiceFacadeView.IFromBOElement newElement = wdContext
						.createFromBOElement();
				newElement.setCountryID((String) myValues.getElementAt(i)
						.getAttributeValue("CountryID"));
				wdContext.nodeFromBO().addElement(newElement);
			}
		}

  	
    //@@end
  }

Please have a look and tell me where may be the problem is.

Regards

Former Member
0 Kudos

1. Create yet another value node in context -- FromBOFiltered. Attributes, cardinality, selection and other settings are same as for FromBO node.

2. Re-bind table and cell editors to node FromBOFiltered

3. Create supply function for node FromBOFiltered:


final IPrivateServiceFacadeView.IFromBONode myValues = wdContext.nodeFromBO(); 
final String filterCountryID = wdContext.currentFilterValuesElement().getFilter_CountryID();
if ( filterCountryID == null || filterCountryID.length() == 0 )
{
  /* NO FILTER -- copy all elements and exit */
  WDCopyService.copyElements( myValues, node );
  return;
}
	
int size = myValues.size();  	  	 		
for (int i = 0; i < size; i++)  	
{  	     
  final IPrivateServiceFacadeView.IFromBOElement el 
    = myValues.getFromBOElementAt(i);
		  
  final String value = el.getCountryID();  	
  /* SKIP UNMATCHED*/
  if ( !value.matches(filterCountryID) ) continue;

  final IPrivateServiceFacadeView.IFromBOFilteredElement newEl
    = node.createFromBOFilteredElement();  	
		   			
  WDCopyService.copyCorresponding( el, newEl );
  node.addElement( newEl );
}  	

4. Your action handler will contain single line:

wdContext.nodeFromBOFiltered().invalidate();

VS

Former Member
0 Kudos

Hi Valery,

Thanks I got to know a new thing. "<b>Suppy Function</b>" :).

Anyways Still there is one issue in this. I could get the Filtering done properly but, the behaviour of the table has changed. It is not showing any element at the first action. Only when I pass some filtering criteria it shows some elements.

I want that initially it show all the elements by defualt. I tried binding the elements I got from the FromBO node, but I guess its the property of the supply function that we cannot call bind if the node is having the <i>Supply function relationship or Supply role.</i> This is what it is showing me in the error.

Secondly, If I am searching something like [Ch*], for country name China, the filter is not working. it is not showing any data, the table is empty at that time. Is this a invalid string for the search?? Kindly resolve this as well.

Regards

Former Member
0 Kudos

<i>I want that initially it show all the elements by defualt. I tried binding the elements I got from the FromBO node, but I guess its the property of the supply function that we cannot call bind if the node is having the Supply function relationship or Supply role. This is what it is showing me in the error.</i>

Could you debug your code?

Is supply function invoked when application is starting?

Is FromBO node populated at this time?

Don't call bind on node FromBOFiltered. Just make sure that node FromBO is populated in wdDoInit and everything should work (ok, if you are not assigning something as filter from code).

<i>Secondly, If I am searching something like [Ch*], for country name China, the filter is not working. it is not showing any data, the table is empty at that time. Is this a invalid string for the search?? Kindly resolve this as well.</i>

Because you are using Regular Expressions (RE) for matching via call

value.matches(filter).

But what user enters is not RE, if you enter Ch.* (note the dot character) everything will work.

So you may either ommit wildcards and use

value.indexOf(filter) >= 0

Or convert user input into RE (Pattern is java.util.Pattern):


//@begin other
/**/
final private static Pattern MATCH_ALL 
  = Pattern.compile(".*");

private Pattern compile(final String mask)
{
  if ( skipFilter(mask) ) return MATCH_ALL;
  else
  try 
  { 
    return Pattern.compile
    ( 
      mask.replaceAll("(\*|\?)", "\.
//@begin other
/**/
final private static Pattern MATCH_ALL 
  = Pattern.compile(".*");

private Pattern compile(final String mask)
{
  if ( skipFilter(mask) ) return MATCH_ALL;
  else
  try 
  { 
    return Pattern.compile
    ( 
      mask.replaceAll("(\\*|\\?)", "\\.$1"), 
      Pattern.CASE_INSENSITIVE 
    );
  }
  catch (final PatternSyntaxException ex)
  {
    wdComponentAPI.getMessageManager()
      .reportException( "Invalid filter: " + mask, false);
    return MATCH_ALL;
  }
}
		
private static boolean skipFilter(final String mask)
{
  return ( StringUtil.isEmpty(mask) || "*".equals(mask) ); 
}

//@end"), 
      Pattern.CASE_INSENSITIVE 
    );
  }
  catch (final PatternSyntaxException ex)
  {
    wdComponentAPI.getMessageManager()
      .reportException( "Invalid filter: " + mask, false);
    return MATCH_ALL;
  }
}
		
private static boolean skipFilter(final String mask)
{
  return ( StringUtil.isEmpty(mask) || "*".equals(mask) ); 
}

//@end

And in supply function use:

--before loop


final Pattern pattern = compile(filterCountryID);

--inside loop


if ( !pattern.matcher(value).matches() ) continue;

Valery Silaev

EPAM Systems

http://www.NetWeaverTeam.com

Former Member
0 Kudos

Hi:

try:

/people/peter.vignet/blog/2007/01/03/generic-web-dynpro-java-table-filter

regards