前回解説したときは英語を使用していたので気付かなかったのだが、日本語で使用するとプラグインそのままだと不便な箇所がいくつかあったのでそれの修正点もあわせて解説していく。ちなみに今回の環境はGoogle App Engine PythonをサーバとしフレームワークにはDjango-nonrelを使用している。
まずこちらのgithubからソースコードをダウンロードしよう。git cloneでダウンロードするとajax対応ではないソースコードが落ちてくるので画面右上のDownloadボタンから取得するように。ZIPファイルを解凍すると色々とファイルが入っているけれど、今回は下図のようなフォルダ構造にした。
実際のHtmlとプラグインを使用するJavascriptコードは下記のようになる。
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.12/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/multiselect/plugins/localisation/jquery.localisation-min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/multiselect/plugins/tmpl/jquery.tmpl.1.1.1.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/multiselect/plugins/blockUI/jquery.blockUI.js"></script>
<script src="{{ STATIC_URL }}js/multiselect/ui.multiselect.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$.localise('ui.multiselect', {language: 'ja', path: '{{ STATIC_URL }}js/multiselect/locale/'});
$("#groups").multiselect({
remoteUrl: "/community_web/group/search"
});
});
</script>
<select id="groups" class="multiselect" multiple="multiple" name="groups">
</select>
{{ STATIC_URL }}という記述はDjangoのテンプレート機能なので他のフレームワークを使用している場合は適切な形に修正して欲しい。前回解説したときと比べて変わったのはlocalizationプラグインを使用してローカライズを行っている箇所だ。下記にui.multiselect-ja.jsの内容を示す。
$.extend($.ui.multiselect.locale, {
addAll:'すべて追加',
removeAll:'すべて削除',
itemsCount:'#{count}個選択',
itemsTotal:'#{count}個',
busy:'処理中...',
errorDataFormat:"データ形式が予期しない形です。処理を続行できません",
errorInsertNode:"選択肢を追加するときに問題が発生しました:\n\n\t[#{key}] => #{value}\n\n処理は中止されました。",
errorReadonly:"選択肢 #{option}は読み取り専用です",
errorRequest:"データ取得中にエラーが発生しました。 (Type: #{status})"
});
これで上記の内容で日本語表示される。ついでui.multiselect.jsのほうに手を加える。
// _registerSearchEvents内の$.ajaxを下記のように修正する
$.ajax({
url: that.options.remoteUrl,
data: $.extend(params, {q:encodeURIComponent(value)}), // ここ重要
success: function(data) {
that.addOptions(data);
that._setBusy(false);
},
デフォルトではサーバに投げるクエリ文字列をescape()でエンコーディングしているけれど、escapeが出力するエンコーディングはW3C標準ではないので、Django側で受けたときに正しくデコードできない。そのためescapeに変わってencodeURIComponent()を使用する。
それに併せて使い勝手の上でmultiselectのそのままの仕様だと日本語入力しづらいことこの上ないので、下記のように入力にあわせた自動検索を無効化しておく。
switch (e.which) {
case 13: // enter
_searchNow(true);
return false;
//default: // これをコメントアウト
// timer = setTimeout(function() { _searchNow(); }, Math.max(that.options.searchDelay,1));
}
上記に併せてsearchDelayオプションも不要になったので気になる人は削除しておこう。これでクライアント側の準備は整ったのでサーバ側を見てみよう。リクエストハンドラーとして下記の一文をurlpatternsに追加しておく。
//...省略 (r'^community_web/group/search', 'community_web.views.group.search'), //...省略
実際のリクエストハンドラーは下記。
group.py
def search(request):
query = request.GET.get('q', None)
if query:
query = urllib2.unquote(query.encode('ascii')).decode('utf8')
list = ['%s=%s' % (group.id, group.title) for group in Group.objects.filter(title__startswith=query)]
results = '\n'.join(list)
else:
results = ''
return HttpResponse(results)
検索文字列を取得するところでごにゃごにゃとやっている解説は下記の通り。
まず、query.encode('ascii')でobjectから文字列に変換している。ついで、urllib2.unquote()でエスケープ文字を普通の文字に変換している。そして最後にUTF8でデコードして完了。
これで日本語でも複数選択のプラグインが正常に動作するはずだ。


0 件のコメント:
コメントを投稿