Skip to Content
avatar image
Former Member

Table Sorting

Hello i have SAP NWDS SP15.

I have added tablesorter.java class, do all by tutorial, but

when i test my application i can sort only boolead field (Strings are not sorted)

+ when i sort by boolean field, my table are not updated i need to do this manually (by clicking on the next - back elements)

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Jul 11, 2008 at 09:22 AM

    Hi,

    Did you Assign the actions to the "onAction" event of the two table columns.

    check the below link....

    Sorting Table Column

    regards,

    Pradeep

    Add comment
    10|10000 characters needed characters exceeded

  • avatar image
    Former Member
    Jul 11, 2008 at 09:33 AM

    Hello i have new question 😊

    in class tablesorter.java

    if i set table.iterateGroupedColumns(), i can sort all strings but i cant sort boolean

    if i set table.IterateColumns(), i can sort boolean, but i cannot sort Strings (this method is depreceated)

    Who can help?

    code:

    public TableSorter(IWDTable table, IWDAction sortAction, Comparator[] comparators) {

    this.table = table;

    // sanity checks

    if (sortAction == null)

    throw new IllegalArgumentException("Sort 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.iterateGroupedColumns(); it.hasNext(); ++index) { // for every column: try to make it bindable

    IWDTableColumn column = (IWDTableColumn) it.next();

    Comparator comparator = null;

    if (comparators != null && index < comparators.length)

    comparator = comparators[index];

    ReversableComparator reversable = null;

    if (comparator instanceof NodeElementByAttributeComparator) {

    // the easy one, attribute and ordering are given

    reversable = new ReversableComparator(comparator);

    } else { // 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 (TODO handle this)

    reversable = new ReversableComparator(new NodeElementByAttributeComparator(attributeName, comparator));

    }

    // set up internal data structures

    comparatorForColumn.put(column, reversable);

    // prepare table column

    column.setOnAction(sortAction);

    column.mappingOfOnAction().addSourceMapping("col", "col");

    if (column.getHeader() != null)

    column.getHeader().setImageSource(null);

    }

    }

    Add comment
    10|10000 characters needed characters exceeded

  • avatar image
    Former Member
    Jul 11, 2008 at 11:16 AM

    Solwed at my OWN

    Add comment
    10|10000 characters needed characters exceeded

    • No. I did not add columns manually. May be 1 or 2 later when requirement changed. How to find out whether the columns are grouped or manually added?

      My colleague did the sorting and the result is not as desired. I'm pasting the codes here.

      1. This is in the view where the table is present.

      public static void wdDoModifyView(IPrivateView_SearchMaterial wdThis, IPrivateView_SearchMaterial.IContextNode wdContext, com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)

      {

      //@@begin wdDoModifyView

      if (firstTime) {

      // view.nowCreateAllCustomExtensionFields();

      IWDTable materialTable = (IWDTable) view.getElement("Table");

      wdContext.currentContextElement().setVa_TableSorter_SearchMaterial( new TableSorter(materialTable, wdThis.wdGetSortMaterialsAction(), null));

      }

      2. This is what i see in the TableSorter.java

      public TableSorter(IWDTable table, IWDAction sortAction, Map comparators) {

      init(table, sortAction, comparators, null);

      }

      public TableSorter(IWDTable table, IWDAction sortAction, Map comparators, String[] sortableColumns) {

      init(table, sortAction, comparators, sortableColumns);

      }

      /**

      • Initialisation stuff

      */

      private void init(IWDTable table, IWDAction sortAction, Map comparators, String[] sortableColumns){

      this.table = table;

      if(sortableColumns == null){

      sortableCols = null;

      }else{

      sortableCols = new HashMap();

      for (int i = 0; i < sortableColumns.length; i++) {

      sortableCols.put(sortableColumns<i>, sortableColumns<i>);

      }

      }

      // sanity checks

      if (sortAction == null)

      throw new IllegalArgumentException("Sort 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");

      // make the columns sortable

      String dataSourcePrefix = table.bindingOfDataSource() + ".";

      //TODO: remove the following line since this method is not longer available in later releases

      setComparatorsForColumns(dataSourcePrefix, table.iterateColumns(), comparators);

      setComparatorsForColumns(dataSourcePrefix, table.iterateGroupedColumns(), comparators);

      //set up the table properties

      table.setOnSort(sortAction);

      table.mappingOfOnSort().addSourceMapping(IWDTable.IWDOnSort.COL, "selectedColumn");

      table.mappingOfOnSort().addSourceMapping(IWDTable.IWDOnSort.DIRECTION, "sortDirection");

      }

      /**

      • Try to make the given columns sortable (recusivly, if necessary)

      */

      private void setComparatorsForColumns(String dataSourcePrefix, Iterator columnIterator, Map comparators){

      int index = 0;

      for (Iterator it = columnIterator; it.hasNext(); ++index) { // for every column: try to make it bindable

      IWDAbstractTableColumn abstractColumn = (IWDAbstractTableColumn) it.next();

      if(abstractColumn instanceof IWDTableColumn){

      IWDTableColumn column = (IWDTableColumn)abstractColumn;

      if(sortableCols == null || sortableCols.containsKey(column.getId())){

      //try to make this column sortable

      Comparator comparator = null;

      if (comparators != null){

      comparator = (Comparator)comparators.get(column.getId());

      }

      NodeElementByAttributeComparator elementComparator = null;

      if (comparator instanceof NodeElementByAttributeComparator) {

      // the easy one, attribute and ordering are given

      elementComparator = (NodeElementByAttributeComparator)comparator;

      } else { // attribute must be determined

      String bindingOfPrimaryProperty = bindingOfPrimaryProperty(column.getTableCellEditor());

      if (bindingOfPrimaryProperty == null || !bindingOfPrimaryProperty.startsWith(dataSourcePrefix)){

      //no attribute found or outside of data source

      column.setSortState(WDTableColumnSortDirection.NOT_SORTABLE);

      continue;

      }

      String attributeName = bindingOfPrimaryProperty.substring(dataSourcePrefix.length());

      Collection subnodes = new ArrayList();

      if (attributeName.indexOf('.') >= 0){

      //attribute not immediately below data source

      String[] tokens = tokenize (attributeName, ".");

      for(int i=0; i<tokens.length-1; i++){

      subnodes.add(tokens<i>);

      }

      attributeName = tokens[tokens.length-1];

      }

      if(subnodes.size() == 0){

      elementComparator = new NodeElementByAttributeComparator(attributeName, comparator);

      }else{

      elementComparator = new NodeElementByAttributeComparator(attributeName, comparator, subnodes);

      }

      }

      // set up internal data structures

      comparatorForColumn.put(column, elementComparator);

      //set sort state

      column.setSortState(WDTableColumnSortDirection.NONE);

      }else{

      //column should not be sortable

      column.setSortState(WDTableColumnSortDirection.NOT_SORTABLE);

      }

      }else if (abstractColumn instanceof IWDTableColumnGroup){

      //it's just a column group -> try to bind the columns of the column group

      IWDTableColumnGroup columnGroup = (IWDTableColumnGroup)abstractColumn;

      setComparatorsForColumns(dataSourcePrefix, columnGroup.iterateColumns(), comparators);

      }

      }

      }

      /**

      • Tokenizes the input string according to the given delimiters. The delimiters will be left out.

      • Example: tokenize("Hello_World", "_") results ["Hello", "World"]

      */

      private String[] tokenize (String input, String delim){

      StringTokenizer tokenizer = new StringTokenizer(input, delim);

      String[] tokens = new String[tokenizer.countTokens()];

      int index = 0;

      while(tokenizer.hasMoreTokens()){

      tokens[index] = tokenizer.nextToken();

      index++;

      }

      return tokens;

      }

      /**

      • This method must be called from the event handler of this table sorter's

      • sort action. It performs the actual sort operation.

      */

      public void sort(IWDCustomEvent wdEvent, IWDNode dataSource) {

      // find the things we need

      String columnId = wdEvent.getString("selectedColumn");

      String direction = wdEvent.getString("sortDirection");

      IWDTableColumn column = (IWDTableColumn) table.getView().getElement(columnId);

      NodeElementByAttributeComparator elementComparator = (NodeElementByAttributeComparator) comparatorForColumn.get(column);

      if (elementComparator == null){

      //not a sortable column

      column.setSortState(WDTableColumnSortDirection.NOT_SORTABLE);

      return;

      }

      // sorting

      elementComparator.setSortDirection(WDTableColumnSortDirection.valueOf(direction));

      dataSource.sortElements(elementComparator);

      }

      /**

      • Returns the binding of the given table cell editor's property that is

      • considered "primary" or <code>null</code> 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 <code>null</code> 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();

      return null;

      }

      /**

      • Instance of a comparator according to the ordering imposed by the

      • implementation of <code>Comparable</code>.

      */

      private static final Comparator DEFAULT = new Comparator() {

      /**

      • Compares the given objects according to the ordering imposed by the first

      • ones <code>compareTo(Object)</code> function. Furthermore, <code>null</code>

      • 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;

      if (o1 instanceof Boolean && o2 instanceof Boolean)

      return o1.toString().compareTo(o2.toString()); // false < true

      if (o1 instanceof String && o2 instanceof String){

      //Use a Collator for sorting according to the given Locale

      Collator collate = Collator.getInstance(WDResourceHandler.getCurrentSessionLocale());

      return collate.compare(o1, o2);

      }

      return ((Comparable) o1).compareTo((Comparable) o2);

      }

      };

      /**

      • Map of table column to comparator (<code>ReversableComparator</code>)

      • used for sorting that column (sortable columns only).

      */

      private Map comparatorForColumn = new HashMap();

      /**

      • The table to be sorted.

      */

      private IWDTable table = null;

      /**

      • Column-IDs of the columns, which should be sortable

      */

      private Map sortableCols = null;

      /**

      • Generic comparator that compares node elements by a given attribute with

      • the help of a given comparator.

      */

      public final class NodeElementByAttributeComparator implements Comparator {

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute according to the natural ordering of that attribute's

      • type (which must implement <code>java.lang.Comparable</code>).

      */

      public NodeElementByAttributeComparator(String attributeName) {

      this(attributeName, null, false, new ArrayList());

      }

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute with the help of the given comparator. If no comparator

      • is given, the natural ordering of that attribute's type is used.

      */

      public NodeElementByAttributeComparator(String attributeName, Comparator comparator) {

      this(attributeName, comparator, false, new ArrayList());

      }

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute either as objects (i.e. "in internal format") or as text

      • (i.e. "in external format") as indicated. The ordering is the natural

      • ordering of that attribute's type (which must implement

      • <code>java.lang.Comparable</code>) in case objects are compared or the

      • natural ordering of <code>java.lang.String</code> in case texts are compared.

      */

      public NodeElementByAttributeComparator(String attributeName, boolean compareAsText) {

      this(attributeName, null, compareAsText, new ArrayList());

      }

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute according to the natural ordering of that attribute's

      • type (which must implement <code>java.lang.Comparable</code>). In addition it is possible

      • to define the path to a child node with the <code>java.util.Collection</code> subnodes.

      • (List of child node names in the correct order)

      */

      public NodeElementByAttributeComparator(String attributeName, Collection subnodes) {

      this(attributeName, null, false, subnodes);

      }

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute with the help of the given comparator. If no comparator

      • is given, the natural ordering of that attribute's type is used. In addition it is possible

      • to define the path to a child node with the <code>java.util.Collection</code> subnodes.

      • (List of child node names in the correct order)

      */

      public NodeElementByAttributeComparator(String attributeName, Comparator comparator, Collection subnodes) {

      this(attributeName, comparator, false, subnodes);

      }

      /**

      • Creates a new comparator for the given attribute name that compares values

      • of that attribute either as objects (i.e. "in internal format") or as text

      • (i.e. "in external format") as indicated. The ordering is the natural

      • ordering of that attribute's type (which must implement

      • <code>java.lang.Comparable</code>) in case objects are compared or the

      • natural ordering of <code>java.lang.String</code> in case texts are compared. In addition it is possible

      • to define the path to a child node with the <code>java.util.Collection</code> subnodes.

      • (List of child node names in the correct order)

      */

      public NodeElementByAttributeComparator(String attributeName, boolean compareAsText, Collection subnodes) {

      this(attributeName, null, compareAsText, subnodes);

      }

      /**

      • Internal constructor.

      */

      private NodeElementByAttributeComparator(

      String attributeName,

      Comparator comparator,

      boolean compareAsText,

      Collection subNodes) {

      if (attributeName == null)

      throw new IllegalArgumentException("Attribute name must not be null");

      if (comparator == null)

      comparator = DEFAULT;

      this.attributeName = attributeName;

      this.comparator = comparator;

      this.compareAsText = compareAsText;

      this.sortDirection = true;

      this.subNodes = subNodes;

      }

      /**

      • Sets the sort direction of this comparator to the given direction. The comparator sort in ascending order by default.

      • @see com.sap.tc.webdynpro.clientserver.uielib.standard.api.WDTableColumnSortDirection

      */

      public void setSortDirection(WDTableColumnSortDirection direction){

      if(direction.equals(WDTableColumnSortDirection.UP)){

      sortDirection = true;

      }else if(direction.equals(WDTableColumnSortDirection.DOWN)){

      sortDirection = false;

      }

      }

      /**

      • Compares the given objects which must be instances of <code>IWDNodeElement</code>

      • according to the values of the attribute given at construction time

      • with the help of the comparator given at construction time.

      • @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)

      • @see com.sap.tc.webdynpro.progmodel.api.IWDNodeElement

      */

      public int compare(Object o1, Object o2) {

      IWDNodeElement element1 = (IWDNodeElement) o1;

      IWDNodeElement element2 = (IWDNodeElement) o2;

      if(subNodes.size() > 0){

      element1 = getSubNodeElement(element1, 0);

      element2 = getSubNodeElement(element2, 0);

      }

      Object attributeValue1 = null;

      Object attributeValue2 = null;

      if(element1 != null){

      attributeValue1 =

      compareAsText

      ? element1.getAttributeAsText(attributeName)

      : element1.getAttributeValue(attributeName);

      }

      if(element2 != null){

      attributeValue2 =

      compareAsText

      ? element2.getAttributeAsText(attributeName)

      : element2.getAttributeValue(attributeName);

      }

      if(sortDirection){

      return comparator.compare(attributeValue1, attributeValue2);

      }else{

      return comparator.compare(attributeValue2, attributeValue1);

      }

      }

      /**

      • Determines recursivly the child node, which have an attribute with the given name.

      • The path to this child node must be specified in the subnodes property of this comparator.

      • Start this method with index = 0.

      */

      private IWDNodeElement getSubNodeElement(IWDNodeElement currentElement, int index){

      if(currentElement == null || index >= subNodes.size()){

      //end of recursion

      return currentElement;

      }else{

      return getSubNodeElement(currentElement.node().getChildNode((String)subNodes.toArray()[index], currentElement.index()).getCurrentElement(), index+1);

      //return getSubNodeElement(currentElement.node().getChildNode((String)subNodes.toArray()[index], currentElement.index()).getElementAt(0), index+1);

      }

      }

      /**

      • Name of the attribute used for comparisons.

      */

      private final String attributeName;

      /**

      • Comparator used for comparing the attribute's values.

      */

      private final Comparator comparator;

      /**

      • Indicates whether attribute values are compared as text (as opposed to

      • "as objects").

      */

      private final boolean compareAsText;

      /**

      • Sort direction (true = ascending order, false = descending order)

      */

      private boolean sortDirection;

      /**

      • List of child node names

      • (Description of the path from the given context node to the specified attribute)

      */

      private Collection subNodes;

      }

      }