Java
AribaWeb

AribaWebのAWTDataTableのソート機能のカスタマイズ

More than 1 year has passed since last update.

AWTDataTableはカラムヘッダーをクリックすることでそのカラムの値を使ってテーブルに表示されるデータをソートする仕組みがありますが、ソートはAWTSortOrderingというオブジェクトが行っています。

ソートされる値は文字列として扱われているので、

  • C
  • A
  • B

  • A
  • B
  • C

または

  • C
  • B
  • A

と正しくソートされますが、

  • 2
  • 100
  • 45

  • 100
  • 2
  • 45

または

  • 45
  • 2
  • 100

とソートされてしまい、数量や金額といった数値が正しくソートされません。

また製品番号や伝票番号などでよく使われる

  • No2
  • No10
  • No9

のような場合も正しくソートされません。

これを解決するには、

  • Compareインターフェースを実装したFormatterを追加する
  • カラムにそのFormatterをバインディングする

ということを行います。

以下に実装例を示します。

MyFormatter.java

まずFormatterです。AWFormatterのサブクラスでCompareインターフェースを実装します。
package app.util;

import java.text.ParseException;

import ariba.ui.aribaweb.util.AWFormatter;
import ariba.util.core.Compare;

public class MyFormatter extends AWFormatter implements Compare {

    @Override
    public Object parseObject(String stringToParse) throws ParseException {
        return stringToParse;
    }

    @Override
    public String format(Object objectToFormat) {
        return (String)objectToFormat;
    }

    /**
     * ソート対象の値から数値部分だけを抜き出して数値として比較する
     */
    @Override
    public int compare(Object o1, Object o2) {
        String s1, s2;
        s1 = o1 == null ? null : (String)o1;
        s2 = o2 == null ? null : (String)o2;
        if(s1 != null && s2 != null) {
            int l1 = Integer.parseInt(s1.replaceAll("[^0-9]", ""));
            int l2 = Integer.parseInt(s2.replaceAll("[^0-9]", ""));
            return l1 - l2;
        } else {
            if(s1 == null && s2 == null) {
                return Compare.EqualTo;
            } else if(s1 == null) {
                return Compare.LessThan;
            } else {
                return Compare.GreaterThan;
            }
        } 
    }

}

Application.java

アプリケーション起動時に作成したFormatterをシステムに登録する。例ではMyFormatterを"myformatter"という名前で登録しています。この名前はテンプレートファイル(AWL)ののバインディングを行うときに参照される名前です。

...
...

@Override
public void init() {
    super.init();

    installFormatters();

}
...
...

private void installFormatters() {
    AWVFormatterFactory.registerProvider(new FormatterProvider() { 
        @Override
        public void populateFormatters(Map<String, Object> formatters, Locale locale, TimeZone timeZone) {
        Map<String, AWFormatter> map = MapUtil.map();
        map.put("myformatter", new MyFormatter());
        for(Map.Entry<String, AWFormatter> entry : map.entrySet()) {
            formatters.put(entry.getKey(), entry.getValue());
        }

    }}); 
}

テンプレートファイル(AWL)を修正する

<t:DataTable ....>
...
...
    <t:Column key="orderNo" label="Order #" formatter="$formatters.myformatter" />
...
...

</t:DataTable>