ruby-etude:form-elements-helper
Ruby用 form要素出力ヘルパークラス
htmlのformの要素(inputタグとか)の出力ヘルパークラス。
エラー時などの入力内容を再表示する場合に対応している。入力された内容をCGIから取り出し、再表示している。
設計としてはクラスの継承を重ねて作った。本当ならmix-inを使ってみたかったけど、staticメソッド的にしたからできなかった。
ソースコード
require "cgi" module Form end # HTMLエスケープのショートカット def h(value) return CGI.escapeHTML(value.to_s) end # ヘルパーメソッドをラップするクラス class Form::Form def initialize @params = CGI.new.params @label_no = 0 end def text(name, attr = {}) return Form::Text.get_tag(name, attr, @params) end def hidden(name, value, attr = {}) return Form::Hidden.get_tag(name, value, attr) end def password(name, attr = {}) return Form::Password.get_tag(name, attr) end def file(name, attr = {}) return Form::File.get_tag(name, attr) end def submit(label, attr = {}) return Form::Submit.get_tag(label, attr) end def button(label, onclick, attr = {}) return Form::Button.get_tag(label, onclick, attr) end def reset(label, attr = {}) return Form::Reset.get_tag(label, attr) end def checkbox(name, label, attr = {}) return Form::CheckBox.get_tag(name, label, attr, @params, self.get_label_no) end def radio(name, label, value, attr = {}) return Form::Radio.get_tag(name, label, value, attr, @params, self.get_label_no) end def textarea(name, attr = {}) return Form::TextArea.get_tag(name, attr, @params) end def select(name, options, attr = {}) return Form::Select.get_tag(name, options, attr, @params) end protected # idがユニークになるようにする def get_label_no @label_no += 1 return @label_no end end class Form::Element # valueを決める def self.get_value(name, attr, params) value = attr.delete(:value) if value == nil if params.key?(name) value = params[name][0] elsif attr.key?(:default) value = attr.delete(:default) end end attr.delete(:default) return value.to_s end # 指定されなかった場合の属性 def self.default_attr(attr, key, value) attr[key] = value unless attr.key?(key) end # 属性を組み立てる def self.hash2str(hash_attr) str_attr = "" hash_attr.each do |k, v| if v != "" && v != nil str_attr += ' ' + k.to_s + '="' + v.to_s + '"' end end return str_attr end end class Form::Input < Form::Element def self.get_input_tag(type, attr) attr[:type] = type attr[:value] = h(attr[:value]) return "<input#{self.hash2str(attr)} />" end end class Form::Text < Form::Input def self.get_tag(name, attr, params) attr[:name] = name attr[:value] = self.get_value(name, attr, params) return self.get_input_tag(:text, attr) end end class Form::Hidden < Form::Input def self.get_tag(name, value, attr) attr[:name] = name attr[:value] = value return self.get_input_tag(:hidden, attr) end end class Form::Password < Form::Input def self.get_tag(name, attr) attr[:name] = name return self.get_input_tag(:password, attr) end end class Form::File < Form::Input def self.get_tag(name, attr) attr[:name] = name return self.get_input_tag(:file, attr) end end # ボタン系 class Form::Pushable < Form::Input def self.get_pushable_tag(type, label, attr) attr[:value] = label return self.get_input_tag(type, attr) end end class Form::Submit < Form::Pushable def self.get_tag(label, attr) return self.get_pushable_tag(:submit, label, attr) end end class Form::Button < Form::Pushable def self.get_tag(label, onclick, attr) attr[:onclick] = onclick return self.get_pushable_tag(:button, label, attr) end end class Form::Reset < Form::Pushable def self.get_tag(label, attr) return self.get_pushable_tag(:reset, label, attr) end end # チェック系 class Form::Checkable < Form::Input def self.get_checkable_tag(type, name, label, checked, attr, label_no) attr[:name] = name attr[:checked] = :checked if checked self.default_attr(attr, :id, type.to_s + label_no.to_s) return '<label for="' + attr[:id] + '">' + self.get_input_tag(type, attr) + h(label) + "</label>" end end class Form::CheckBox < Form::Checkable def self.get_tag(name, label, attr, params, label_no) self.default_attr(attr, :value, 1) checked = false if params.key?(name) checked = true if params[name].include?(attr[:value].to_s) elsif attr.key?(:default) checked = true end dummy = Form::Hidden.get_tag(name, "", {}) # 送信確認用 return self.get_checkable_tag(:checkbox, name, label, checked, attr, label_no) + dummy end end class Form::Radio < Form::Checkable def self.get_tag(name, label, value, attr, params, label_no) attr[:value] = value checked = false checked = true if value.to_s == params[name][0] || attr.key?(:default) return self.get_checkable_tag(:radio, name, label, checked, attr, label_no) end end # テキストエリア class Form::TextArea < Form::Element def self.get_tag(name, attr, params) attr[:name] = name self.default_attr(attr, :cols, 50) self.default_attr(attr, :rows, 5) return "<textarea#{self.hash2str(attr)}>#{h(self.get_value(name, attr, params))}</textarea>" end end # 選択リスト class Form::Select < Form::Element def self.get_tag(name, options, attr, params) selected = self.get_value(name, attr, params) attr[:name] = name t = "<select#{self.hash2str(attr)}>\n" options.each do |k, v| option_attr = {:value => h(k)} option_attr[:selected] = :selected if k.to_s == selected t += "<option#{self.hash2str(option_attr)}>#{h(v)}</option>\n" end return t + "</select>" end end
サンプル
40行の Ruby製 簡易テンプレートエンジンを使ったテンプレートでの例。
<html> <head> <title>form</title> </head> <body> <form action="sample.rb"> !{load 'form.rb'; f = Form::Form.new} ノーマル#{f.text('normal')} デフォルト#{f.text('default', :default => 'DEFAULT')} 値持ち#{f.text('value', :value => 'VALUE', :size => 40)}<br /> #{f.button('BUTTON', 'alert(4649)')}<br /> #{f.hidden('hide', 'HIDDEN')} #{f.password('pass')}<br /> #{f.file('upload')}<br /> #{f.checkbox('cb', 'チェックボックス')}<br /> #{f.checkbox('color', '赤', :value => 'red', :default => 'checked')} #{f.checkbox('color', '青', :value => 'blue')} #{f.checkbox('color', '黄', :value => 'yellow')}<br /> #{f.radio('rdo', 'ラジオボタン1', 'A', :default => 'checked')} #{f.radio('rdo', 'ラジオボタン2', 'B')}<br /> #{f.radio('rdo2', 'デフォルト無し1', 100)} #{f.radio('rdo2', 'デフォルト無し2', 200)}<br /> #{f.textarea('ta')}<br /> #{f.select('sel', @options, :default => 2)}<br /> #{f.reset('キャンセル')} #{f.submit('送る')}<br /> </form> </body>
実行結果のHTML
<html> <head> <title>form</title> </head> <body> <form action="sample.rb"> ノーマル<input name="normal" type="text" /> デフォルト<input name="default" value="DEFAULT" type="text" /> 値持ち<input name="value" value="VALUE" size="40" type="text" /><br /> <input value="BUTTON" type="button" onclick="alert(4649)" /><br /> <input name="hide" value="HIDDEN" type="hidden" /> <input name="pass" type="password" /><br /> <input name="upload" type="file" /><br /> <label for="checkbox1"><input name="cb" value="1" id="checkbox1" type="checkbox" />チェックボックス</label><input name="cb" type="hidden" /><br /> <label for="checkbox2"><input name="color" default="checked" value="red" checked="checked" id="checkbox2" type="checkbox" />赤</label><input name="color" type="hidden" /> <label for="checkbox3"><input name="color" value="blue" id="checkbox3" type="checkbox" />青</label><input name="color" type="hidden" /> <label for="checkbox4"><input name="color" value="yellow" id="checkbox4" type="checkbox" />黄</label><input name="color" type="hidden" /><br /> <label for="radio5"><input name="rdo" value="A" default="checked" checked="checked" id="radio5" type="radio" />ラジオボタン1</label> <label for="radio6"><input name="rdo" value="B" id="radio6" type="radio" />ラジオボタン2</label><br /> <label for="radio7"><input name="rdo2" value="100" id="radio7" type="radio" />デフォルト無し1</label> <label for="radio8"><input name="rdo2" value="200" id="radio8" type="radio" />デフォルト無し2</label><br /> <textarea name="ta" cols="50" rows="5"></textarea><br /> <select name="sel"> <option value="0"></option> <option value="1">北海道</option> <option value="2" selected="selected">本州</option> <option value="3">四国</option> <option value="4">九州</option> </select><br /> <input value="キャンセル" type="reset" /> <input value="送る" type="submit" /><br /> </form> </body>
ruby-etude/form-elements-helper.txt · 最終更新: 2008/08/01 22:56 by dgbadmin