Ajaxでキーワード登録の使い勝手の向上を目指す。
id=keyword_nameのダブりに気付くまでに、ずいぶん遠回りをしてしまった...。しかし、試行錯誤の中でいろいろなことを試すことが出来たので、今まで知らなかったことも新たに発見することができた。新たな知識を活用して、もう少しキーワード追加の処理方法やインターフェースを改善してみることにする。
テキストフィールドに登録済のキーワードを入力した時の動作
現状では、同じキーワードが登録済の場合は、モデルkeyword.rbのバリデーションによって、エラーになる。でも、ユーザーの立場で考えれば、エラーにしないで登録済のキーワードを選択して、ソフトウェアブックへの登録処理を進めて欲しいと思うはず。テキストフィールドで新規追加しか処理していないから問題なのだ。条件によっては、プルダウンリストのようにキーワードを選択する処理も追加してみる。
app/controllers/softwares_controller.rb 修正1
protected def create_keyword if params[:keyword] @keyword = Keyword.find(:first, :conditions => ["name = ?", params[:keyword][:name]]) if @keyword == nil......同じキーワードが存在しない時だけ新規追加する @new_keyword = true @keyword = Keyword.new(params[:keyword]) @keyword.save end params[:software][:keyword_id] = @keyword.id end end
上記では、「rails」と「Rails」が違うキーワードとして判断されて新規追加されてしまう。大文字と小文字が違っていても、スペルが同じなら、新規追加ではなく選択するようにしたい。
app/controllers/softwares_controller.rb 修正2
protected
def create_keyword
if params[:keyword]
@keyword = Keyword.find(:first, :conditions => ["name LIKE ?", params[:keyword][:name]])
...(以下省略)...
「=」を「LIKE」に置き換えるだけで大文字と小文字の区別はなくなった。ちなみに、以下のような書き方があるようだ。
["name = ?", params[:keyword][:name] | 大文字と小文字の区別あり、完全一致 |
["name LIKE ?", params[:keyword][:name] | 大文字と小文字の区別なし、完全一致 |
["name LIKE ?", params[:keyword][:name] + '%'] | 大文字と小文字の区別なし、前方一致 |
-
-
- %の置き場所によって、後方一致や部分一致にも出来る。SQLについてもっと勉強すればさらに理解が深まるはずなのだが...。
-
まだ問題がある。入力検証エラーが発生しても、キーワードだけ新規追加されてしまう可能性がある。フォームの作成や確認のボタンを押して、エラーが無い時だけ追加するようにしないと、ユーザーが混乱する。そこで以下のようにした。
app/controllers/softwares_controller.rb 修正3
protected def create_keyword if params[:keyword] @keyword = Keyword.find(:first, :conditions => ["name LIKE ?", params[:keyword][:name]]) if @keyword == nil......同じキーワードが存在しない時だけ新規追加する。 form = Software.new(params[:software]) form.keyword_id = 1......仮にkeyword_idを設定する。 @new_keyword = true @keyword = Keyword.new(params[:keyword]) @keyword.save if form.valid?......エラーが無ければキーワードを新規追加する。 end params[:software][:keyword_id] = @keyword.id end end
さらに修正。テキストフィールドにキーワードが未入力の時、エラー表示するため。softwaresテーブルとkeywordsテーブル、両方のエラーを調和させることは結構難しい...。(もっと分かり易い書き方ってあるのだろうか...。)
app/controllers/softwares_controller.rb 修正4
protected def create_keyword if params[:keyword] @keyword = Keyword.find(:first, :conditions => ["name LIKE ?", params[:keyword][:name]]) if @keyword == nil......同じキーワードが存在しない時だけ新規追加する。 form = Software.new(params[:software]) form.keyword_id = 1......仮にkeyword_idを設定する。 @new_keyword = true @keyword = Keyword.new(params[:keyword]) @keyword.save if form.valid? || !@keyword.valid?......1) ソフトウェアにエラーが無ければキーワードを新規追加する。またはキーワードにエラーがあればその表示のために保存処理を行う。 end params[:software][:keyword_id] = @keyword.id || @keyword.name......2) end end
- キーワードにエラーがあれば、エラー表示のために保存処理をする。
- keyword.idが存在しなければ、一時的に@keyword.nameを代入して、エラー表示を正常に行う。
プルダウンリストの初期表示。
現状では、ソフトウェアの新規追加をする時、プルダウンリストの初期表示はキーワードの一つ目の値になっている。これだとユーザーが選択するのを忘れても、初期表示のキーワードのまま登録されてしまう。初期表示はキーワードと関係ない値にして、操作しないまま登録した時はエラーになるようにしたい。
views/models/softwares/_edit2_new_keyword.rhtmlの修正
<% if @new_keyword %>
<%= text_field :keyword, :name, :size => 60 %>
<% else %>
<%= collection_select :software, :keyword_id, Keyword.find_all, :id, :name, :prompt => '選択してください。' %>
<% end %>
オプションを一つ追加するだけでOK。ちなみに:include_blank => trueを設定すれば、空白行が追加される。
ビジュアルエフェクトを使ってみる。
特に必要性はないが、いろいろ調べているうちにこんな演出も出来ることを知った。手軽なので、忘れないように使ってみた。これもオプション設定を追加するだけでOK。
views/models/softwares/_edit2.rhtmlの修正
<% unless @controller.class.hidden_field?(@action_name, 'keyword_id') %> <tr> <td class="<%= localized_label_class_on(@software, 'keyword_id') %>"> <%= human_attribute_name(@software, 'keyword_id') %> <sub> <%= link_to_remote '選択', :update => 'select_or_typing', :url => {:action => 'list_keyword'}, :complete => visual_effect(:highlight, 'select_or_typing', :duration => 1) %> | <%= link_to_remote '新規', :update => 'select_or_typing', :url => {:action => 'new_keyword'}, :complete => visual_effect(:highlight, 'select_or_typing', :duration => 1) %> </sub>
これで、プルダウンリストとテキストフィールドを切り替えた時に一瞬セルがフラッシュするようになる。ビジュアルエフェクトって楽しい!手軽に使えるところもいい!
:complete => | link_to_remoteの部分更新が完了した時に行う処理 | |
visual_effect( | ビジュアルエフェクトを呼び出し | |
:highlight, | ハイライト処理を指定 | |
'select_or_typing', | ハイライト処理の場所を指定 | |
:duration => 1) | ハイライト処理の時間を1秒に指定(指定しないとデフォルト時間になる) |
-
-
- :highlightの他に、左右に揺れる:shakeなんてのもある。その他にもいろいろなエフェクトがあるようだ。詳しくはRDocのマニュアル参照。
-
スタイルシートの調整
エラー表示についても今までSafariで確認していたので気付かなかったが、Firefoxで確認すると、見栄えが悪い。
Firefox:
エラーが発生しても、フォームの周りがほとんど赤くならない。スタイルシートを調整してみた。
public/stylesheets/scaffold.cssの修正
...(途中省略)... form td.labelWithErrors{ /*......form の追加*/ background-color: pink; vertical-align: top; } ...(途中省略)... .fieldWithErrors { padding: 2px; background-color: red; display: table; outline-style: solid; /*......追加*/ outline-width: 2px; /*......追加*/ outline-color: red; /*......追加*/ } ...(途中省略)...
- エラーの時、フィールド名のセルが、ピンク色になる。
- Firefoxは、フォーム部品の余白がほとんど無いので、強制的に赤枠で囲う。
これで、以下のように表示されるようになる。
Firefox:
Safari:
これでキーワードの追加処理については、ほぼ満足。