Skip to content

Instantly share code, notes, and snippets.

@kazz12211
Last active August 26, 2017 05:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazz12211/c2fc555ac49296bca7c9635c0d30f74f to your computer and use it in GitHub Desktop.
Save kazz12211/c2fc555ac49296bca7c9635c0d30f74f to your computer and use it in GitHub Desktop.
AribaWebのAWTDataTableでソート方法を変更する

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)の<t:DataTable><t:Column>のバインディングを行うときに参照される名前です。

...
...

@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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment