Ajax.Autocomplete : Enter ボタンを押すとformがsubmitされて残念だ、の場合。
Autocomplete は script.aculo.us の機能なのでRails 2.0でもHelperを使わずにJavaScriptで書けば普通に使えます。
で、せっかくだからtaggingのautocompleteを以下のように入れてみる。tagging は acts_as_taggable_steroid で。
# View <div> <label style="width: 100px;" for="entry[tag_list]"><%= _("Tags") %></label> <%= text_field 'entry', 'tag_list', :size => 40 %> (<%= _("Each tag is separated with comma(,)") %>) <div id="tag_choices" class="autocomplete"></div> </div> <script type="text/javascript"> new Ajax.Autocompleter("entry_tag_list", "tag_choices", <%= tags_blog_blogs_url.to_json %>, { method : "get", tokens : [","] }); </script> # Contoller # GET /components/blog/blogs/tags # Returns the tag list for auto compoleter def tags starts_with = params[:entry][:tag_list] rescue nil if starts_with @tags = Tag.find(:all, :conditions => ["name LIKE ?", "#{starts_with}%"]) else @tags = Tag.find(:all) end end # tag Renderer <ul> <% @tags.each do |tag| %> <li><%=h tag.name %></li> <% end %> </ul>
- RESTful なResourceにアクセスするので、method オプションに"get"を渡すのが必須。デフォルトだとPOSTなので。
- tokens 指定で、tokenを区切りにしてautocompleteをしてくれる。これ便利。
- AutoComplete に戻すHTML は ul/li でリストにする。
これはこれでいいんだけど、Autocompleteが働いたときに、候補を選んでEnterキーを押すと、確かにテキストフィールドに追加されるんだが、それと同時にsubmitが発生してしまう。これは、テキストフィールドのkeypressのデフォルトの挙動で、input type="submit"がある時などの挙動(このあたり正直ややこしい)。
うーん、気に入らんな、と思って、text_field メソッドを書き換えた。
module ActionView::Helpers::FormHelper alias :text_field_original :text_field def text_field(object_name, method, options = {}) override_default_keybehavior = options.delete(:override_default_keybehavior) unless override_default_keybehavior options[:onkeypress] = "#{options[:onkeypress]}; return event.keyCode != Event.KEY_RETURN;" end text_field_original(object_name, method, options) end end
これで、:override_keypress_default => true オプションが設定された場合にのみ、デフォルトの挙動が適用される。検索とか、inputが一つしかないような場合にはEnterでsubmitしてほしいので(というのをJavaScriptで自動適用できるようにするとそれはそれで便利だが後でやるflagで)。