ゼロと無限の間に

フリーでオープンソースなJavaScriptとかPHPとか。

ユーザ用ツール

サイト用ツール


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

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki