WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ACT ComboBox の日本語対応

by WebSurfer 2012年3月18日 16:50

AJAX Control Toolkit (ACT) の ComboBox は日本語に対応していませんが、それを無理やり(?)、ブラウザが IE のみの場合に限り、日本語対応させてみました。

日本語対応させた AJAX Control Toolkit の ComboBox

ヒントは MDSN の Visual Studio 共通フォーラム にあります。

ComboBox は、テキストボックス(html コードで言うと <input type="text" ... />)の onkeypress イベントで、入力された文字列をリスト(html で言うと ul, li 要素を使った一覧)の中の文字列と比較していますが、IME が ON の時は onkeypress イベントが発生しないのがうまくいかない原因のようです。

その Workaround は、IE のみの場合ですが、以下の通りです。

  1. IME モードが ON のときは onkeypress イベントが発生しないので、代わりに onkeyup イベントを利用する。そのため _onTextBoxKeyUp イベントハンドラを作成し、テキストボックスの onkeyup イベントにアタッチする。
  2. _onTextBoxKeyDown イベントハンドラで、Keycode を取得しておく(IME モード ON の時は 229 になる)。
  3. _onTextBoxKeyUp イベントハンドラで、上記 ② で取得した Keycode が 229 で、かつ KeyCode が 13(ENTER) のとき(文字変 換を確定)に、_onTextBoxKeyPress イベントハンドラを実行する。

AJAX Control Toolkit のソースコードは CodePlex のサイトから入手できます。今回の場合は、JavaScript のコード ComboBox.pre.js を入手して、関係する部分を書き換えて差し替えてやります。

具体的には以下の通りです。実際に動かして試せるよう 実験室 にアップしましたので、興味のある方は試してみてください。

<%@ Page Language="C#" %>
<%@ Import Namespace="AjaxControlToolkit" %>
<%@ Import Namespace="System.Data" %>
<%@ Register
    Assembly="AjaxControlToolkit"
    Namespace="AjaxControlToolkit"
    TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  private static string[] japaneseWordListText;
  public string[] GetJapaneseWordListText()
  {
    if (null == japaneseWordListText)
    {
      string[] tempWordListText = new string[] {
        "あいうえお",
        "かきくけこ",
        "さしすせそ",
        "たちつてと",
        "なにぬねの",
        "はひふへほ",
        "まみむめも",
        "abcdef",
        "日本語",
        "東京都",
        "神奈川県"
      };            
      japaneseWordListText = tempWordListText;
    }
    return japaneseWordListText;
  }

  private static string[] wordListText;
  public string[] GetWordListText()
  {
    if (null == wordListText)
    {
      string[] tempWordListText = new string[] {
        "Alfa",
        "Alpha",
        "Bravo",
        "Charlie",
        "Delta",
        "Echo",
        "Foxtrot",
        "Golf",
        "Hotel",
        "India",
        "Juliett",
        "Juliet",
        "Kilo",
        "Lima",
        "Mike",
        "November",
        "Oscar",
        "Papa",
        "Quebec",
        "Romeo",
        "Sierra",
        "Tango",
        "Uniform",
        "Victor",
        "Whiskey",
        "X-ray",
        "Xray",
        "Yankee",
        "Zulu",
        "Zero",
        "Nadazero",
        "One",
        "Unaone",
        "Two",
        "Bissotwo",
        "Three",
        "Terrathree",
        "Four",
        "Kartefour",
        "Five",
        "Pantafive",
        "Six",
        "Soxisix",
        "Seven",
        "Setteseven",
        "Eight",
        "Oktoeight",
        "Nine",
        "Novenine"
      };
      Array.Sort(tempWordListText);
      wordListText = tempWordListText;
    }
    return wordListText;
  }
    
  protected void Page_Load(object sender, EventArgs e)
  {
    if (!Page.IsPostBack)
    {
      ComboBox1.DataSource = GetWordListText();
      ComboBox1.DataBind();

      ComboBox3.DataSource = GetJapaneseWordListText();
      ComboBox3.DataBind();
    }
  }

  protected void Button1_Click(object sender, EventArgs e)
  {
    Label1.Text = ComboBox1.SelectedItem.Text;
  }

  protected void Button3_Click(object sender, EventArgs e)
  {
    Label3.Text = ComboBox3.SelectedItem.Text;
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title>AJAX Control Toolkit ComboBox の日本語対応</title>
</head>
<body>
  <form id="form1" runat="server">
  <ajaxToolkit:ToolkitScriptManager 
    ID="ToolkitScriptManager1" 
    runat="server">
  </ajaxToolkit:ToolkitScriptManager>

  <div>
    <ajaxToolkit:ComboBox ID="ComboBox1" 
      runat="server"
      AutoCompleteMode="SuggestAppend">
    </ajaxToolkit:ComboBox>
    <asp:Button ID="Button1" 
      runat="server" 
      Text="Button" 
      OnClick="Button1_Click" />
    <asp:Label ID="Label1" runat="server">
    </asp:Label>        
  </div>

  <div>
    <ajaxToolkit:ComboBox ID="ComboBox3" 
      runat="server"
      AutoCompleteMode="SuggestAppend">
    </ajaxToolkit:ComboBox>
    <asp:Button ID="Button3" 
      runat="server" 
      Text="Button" 
      OnClick="Button3_Click" />
    <asp:Label ID="Label3" runat="server">
    </asp:Label>        
  </div>
  </form>

  <script type="text/javascript">
  //<![CDATA[

  Sys.Extended.UI.ComboBox.prototype.createDelegates = function () {
    // ①
    // IME モードが ON のときは onkeypress イベントが発生
    // しない為、代わりに onkeyup イベントを利用。
    this._textBoxKeyUpHandler = 
      Function.createDelegate(this, this._onTextBoxKeyUp);

    // ここから下はオリジナルのコードそのまま。
    this._listMouseOverHandler = 
      Function.createDelegate(this, this._onListMouseOver);
    this._listMouseOutHandler = 
      Function.createDelegate(this, this._onListMouseOut);
    this._listMouseDownHandler = 
      Function.createDelegate(this, this._onListMouseDown);
    this._listClickHandler = 
      Function.createDelegate(this, this._onListClick);
    this._listDragHandler = 
      Function.createDelegate(this, this._onListDrag);
    this._listSelectStartHandler = 
      Function.createDelegate(this, this._onListSelectStart);
    this._listMouseWheelHandler = 
      Function.createDelegate(this, this._onListMouseWheel);
    this._textBoxClickHandler = 
      Function.createDelegate(this, this._onTextBoxClick);
    this._textBoxFocusHandler = 
      Function.createDelegate(this, this._onTextBoxFocus);
    this._textBoxBlurHandler = 
      Function.createDelegate(this, this._onTextBoxBlur);
    this._textBoxKeyPressHandler = 
      Function.createDelegate(this, this._onTextBoxKeyPress);
    this._textBoxKeyDownHandler = 
      Function.createDelegate(this, this._onTextBoxKeyDown);
    this._buttonClickHandler = 
      Function.createDelegate(this, this._onButtonClick);
    this._buttonBlurHandler = 
      Function.createDelegate(this, this._onButtonBlur);
    this._buttonKeyDownHandler = 
      Function.createDelegate(this, this._onButtonKeyDown);

    this._buttonKeyPressHandler = 
      Function.createDelegate(this, this._onButtonKeyPress);
    this._documentClickHandler = 
      Function.createDelegate(this, this._onDocumentClick);
    this._documentMouseWheelHandler = 
      Function.createDelegate(this, this._onDocumentMouseWheel);
    this._popupShowingHandler = 
      Function.createDelegate(this, this._popupShowing);
    this._popupShownHandler = 
      Function.createDelegate(this, this._popupShown);
    this._popupHidingHandler = 
      Function.createDelegate(this, this._popupHiding);
  };

  Sys.Extended.UI.ComboBox.prototype.clearDelegates = function () {
    // ①
    // IME モードが ON のときは onkeypress イベントが発生
    // しない為、代わりに onkeyup イベントを利用。
    this._textBoxKeyUpHandler = null;

    // ここから下はオリジナルのコードそのまま。
    this._listMouseOverHandler = null;
    this._listMouseOutHandler = null;
    this._listMouseDownHandler = null;
    this._listClickHandler = null;
    this._listDragHandler = null;
    this._listSelectStartHandler = null;
    this._listMouseWheelHandler = null;
    this._textBoxClickHandler = null;
    this._textBoxFocusHandler = null;
    this._textBoxBlurHandler = null;
    this._textBoxKeyPressHandler = null;
    this._textBoxKeyDownHandler = null;
    this._buttonClickHandler = null;
    this._buttonBlurHandler = null;
    this._buttonKeyDownHandler = null;
    this._buttonKeyPressHandler = null;
    this._documentClickHandler = null;
    this._documentMouseWheelHandler = null;
    this._popupShowingHandler = null;
    this._popupShownHandler = null;
    this._popupHidingHandler = null;
  };

  Sys.Extended.UI.ComboBox.prototype.addHandlers = function () {

    var optionListControl = this.get_optionListControl();

    $addHandlers(
      optionListControl,
      {
        'mouseover': this._listMouseOverHandler,
        'mouseout': this._listMouseOutHandler,
        'mousedown': this._listMouseDownHandler,
        'click': this._listClickHandler,
        'drag': this._listDragHandler,
        'selectstart': this._listSelectStartHandler
      },
      this);

    $addHandlers(
      this.get_textBoxControl(),
      {
        // ①
        // IME モードが ON のときは onkeypress イベントが発生
        // しない為、代わりに onkeyup イベントを利用。
        // これ以外はオリジナルのコードそのまま。
        "keyup": this._textBoxKeyUpHandler,

        "click": this._textBoxClickHandler,
        "focus": this._textBoxFocusHandler,
        "blur": this._textBoxBlurHandler,
        "keypress": this._textBoxKeyPressHandler
      }, 
      this);

    if (Sys.Browser.agent == Sys.Browser.InternetExplorer ||
      Sys.Browser.agent === Sys.Browser.Safari ||
      Sys.Browser.agent === Sys.Browser.WebKit) {
      $addHandler(
        this.get_textBoxControl(),
        "keydown", 
        this._textBoxKeyDownHandler);
    }

    $addHandlers(
      this.get_buttonControl(),
      {
        'click': this._buttonClickHandler,
        'blur': this._buttonBlurHandler,
        'keydown': this._buttonKeyDownHandler,
        'keypress': this._buttonKeyPressHandler
      }, 
      this);

    $addHandler(
      document,
      'click', 
      this._documentClickHandler);

    if (typeof (optionListControl.onmousewheel) === 'undefined') {
      $addHandler(
        optionListControl,
        'DOMMouseScroll', 
        this._listMouseWheelHandler);
      $addHandler(
        document,
        'DOMMouseScroll', 
        this._documentMouseWheelHandler);
    }
    else {
      $addHandler(
        optionListControl,
        'mousewheel', 
        this._listMouseWheelHandler);
      $addHandler(
        document,
        'mousewheel', 
        this._documentMouseWheelHandler);
    }
  };

  var keycodeOnTextBoxKeyDown = "";

  Sys.Extended.UI.ComboBox.prototype._onTextBoxKeyDown = function (e) {

    // ②
    // _onTextBoxKeyDown 時に Keycode を取得
    // (IME モード ON の時は 229)
    keycodeOnTextBoxKeyDown = this._getKeyboardCode(e);

    // ここから下はオリジナルのコードそのまま。
    var enterResult = this._handleEnterKey(e);
    if (enterResult != null) {
      return enterResult;
    }

    this._handleArrowKey(e);

    var erasureKeyResult = this._handleErasureKeys(e);
    if (erasureKeyResult != null) {
      return erasureKeyResult;
    }

    return true;

  };

  // ①
  // IME モードが ON のときは onkeypress イベントが発生
  // しない為、代わりに onkeyup イベントを利用。
  Sys.Extended.UI.ComboBox.prototype._onTextBoxKeyUp = function (e) {

    // ③
    // onkeyup時に②で取得した Keycode が 229 で
    // かつ KeyCode が 13(ENTER)のときに(文字変
    // 換を確定)、_onTextBoxKeyPress を Call する。
    if (keycodeOnTextBoxKeyDown == 229 && e.keyCode == 13) {
      this._onTextBoxKeyPress(e);
    }
  };

  //]]>  
  </script>
</body>
</html>

Tags: , ,

AJAX

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2018年11月  >>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar