Class | Merb::Helpers::Form::Builder::Base |
In: |
merb-helpers/lib/merb-helpers/form/builder.rb
|
Parent: | Object |
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 8 8: def initialize(obj, name, origin) 9: @obj, @origin = obj, origin 10: @name = name || @obj.class.name.snake_case.split("/").last 11: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 44 44: def bound_check_box(method, attrs = {}) 45: name = control_name(method) 46: update_bound_controls(method, attrs, "checkbox") 47: unbound_check_box({:name => name}.merge(attrs)) 48: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 61 61: def bound_radio_button(method, attrs = {}) 62: name = control_name(method) 63: update_bound_controls(method, attrs, "radio") 64: unbound_radio_button({:name => name, :value => control_value(method)}.merge(attrs)) 65: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 72 72: def bound_radio_group(method, arr) 73: val = control_value(method) 74: arr.map do |attrs| 75: attrs = {:value => attrs} unless attrs.is_a?(Hash) 76: attrs[:checked] = true if (val == attrs[:value]) 77: radio_group_item(method, attrs) 78: end.join 79: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 90 90: def bound_select(method, attrs = {}) 91: name = control_name(method) 92: update_bound_controls(method, attrs, "select") 93: unbound_select({:name => name}.merge(attrs)) 94: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 102 102: def bound_text_area(method, attrs = {}) 103: name = "#{@name}[#{method}]" 104: update_bound_controls(method, attrs, "text_area") 105: unbound_text_area(control_value(method), {:name => name}.merge(attrs)) 106: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 113 113: def button(contents, attrs) 114: update_unbound_controls(attrs, "button") 115: tag(:button, contents, attrs) 116: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 19 19: def fieldset(attrs, &blk) 20: legend = (l_attr = attrs.delete(:legend)) ? tag(:legend, l_attr) : "" 21: tag(:fieldset, legend + @origin.capture(&blk), attrs) 22: # @origin.concat(contents, blk.binding) 23: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 13 13: def form(attrs = {}, &blk) 14: captured = @origin.capture(&blk) 15: fake_method_tag = process_form_attrs(attrs) 16: tag(:form, fake_method_tag + captured, attrs) 17: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 118 118: def submit(value, attrs) 119: attrs[:type] ||= "submit" 120: attrs[:name] ||= "submit" 121: attrs[:value] ||= value 122: update_unbound_controls(attrs, "submit") 123: self_closing_tag(:input, attrs) 124: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 50 50: def unbound_check_box(attrs) 51: update_unbound_controls(attrs, "checkbox") 52: if attrs.delete(:boolean) 53: on, off = attrs.delete(:on), attrs.delete(:off) 54: unbound_hidden_field(:name => attrs[:name], :value => off) << 55: self_closing_tag(:input, {:type => "checkbox", :value => on}.merge(attrs)) 56: else 57: self_closing_tag(:input, {:type => "checkbox"}.merge(attrs)) 58: end 59: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 67 67: def unbound_radio_button(attrs) 68: update_unbound_controls(attrs, "radio") 69: self_closing_tag(:input, {:type => "radio"}.merge(attrs)) 70: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 81 81: def unbound_radio_group(arr, attrs = {}) 82: arr.map do |ind_attrs| 83: ind_attrs = {:value => ind_attrs} unless ind_attrs.is_a?(Hash) 84: joined = attrs.merge(ind_attrs) 85: joined.merge!(:label => joined[:label] || joined[:value]) 86: unbound_radio_button(joined) 87: end.join 88: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 96 96: def unbound_select(attrs = {}) 97: update_unbound_controls(attrs, "select") 98: attrs[:name] << "[]" if attrs[:multiple] && !(attrs[:name] =~ /\[\]$/) 99: tag(:select, options_for(attrs), attrs) 100: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 108 108: def unbound_text_area(contents, attrs) 109: update_unbound_controls(attrs, "text_area") 110: tag(:textarea, contents, attrs) 111: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 294 294: def add_css_class(attrs, new_class) 295: attrs[:class] = attrs[:class] ? "#{attrs[:class]} #{new_class}" : new_class 296: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 277 277: def considered_true?(value) 278: value && value != "false" && value != "0" && value != 0 279: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 281 281: def control_name(method) 282: @obj ? "#{@name}[#{method}]" : method 283: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 285 285: def control_value(method) 286: value = @obj ? @obj.send(method) : @origin.params[method] 287: if Merb.disabled?(:merb_helper_escaping) 288: value.to_s 289: else 290: Merb::Parse.escape_xml(value.to_s) 291: end 292: end
This can be overridden to use another method to fake out methods
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 143 143: def fake_out_method(attrs, method) 144: self_closing_tag(:input, :type => "hidden", :name => "_method", :value => method) 145: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 249 249: def options(col, text_meth, value_meth, sel, b = nil) 250: ([b] + col.map do |item| 251: text_meth = text_meth && item.respond_to?(text_meth) ? text_meth : :last 252: value_meth = value_meth && item.respond_to?(value_meth) ? value_meth : :first 253: 254: text = item.is_a?(String) ? item : item.send(text_meth) 255: value = item.is_a?(String) ? item : item.send(value_meth) 256: 257: unless Merb.disabled?(:merb_helper_escaping) 258: text = Merb::Parse.escape_xml(text) 259: value = Merb::Parse.escape_xml(value) 260: end 261: 262: option_attrs = {:value => value} 263: if sel.is_a?(Array) 264: option_attrs.merge!(:selected => "selected") if value.in? sel 265: else 266: option_attrs.merge!(:selected => "selected") if value == sel 267: end 268: tag(:option, text, option_attrs) 269: end).join 270: end
Accepts a collection (hash, array, enumerable, your type) and returns a string of option tags. Given a collection where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values become lasts. If selected is specified, the matching "last" or element will get the selected option-tag. Selected may also be an array of values to be selected when using a multiple select.
attrs<Hash>: | HTML attributes and options |
selected: | The value of a selected object, which may be either a string or an array. |
prompt: | Adds an addtional option tag with the provided string with no value. |
include_blank: | Adds an additional blank option tag with no value. |
String: | HTML |
<%= options_for [["apple", "Apple Pie"], ["orange", "Orange Juice"]], :selected => "orange" => <option value="apple">Apple Pie</option><option value="orange" selected="selected">Orange Juice</option> <%= options_for [["apple", "Apple Pie"], ["orange", "Orange Juice"]], :selected => ["orange", "apple"], :prompt => "Select One" => <option value="">Select One</option><option value="apple" selected="selected">Apple Pie</option><option value="orange" selected="selected">Orange Juice</option>
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 231 231: def options_for(attrs) 232: blank, prompt = attrs.delete(:include_blank), attrs.delete(:prompt) 233: b = blank || prompt ? tag(:option, prompt || "", :value => "") : "" 234: 235: # yank out the options attrs 236: collection, selected, text_method, value_method = 237: attrs.extract!(:collection, :selected, :text_method, :value_method) 238: 239: # if the collection is a Hash, optgroups are a-coming 240: if collection.is_a?(Hash) 241: ([b] + collection.map do |g,col| 242: tag(:optgroup, options(col, text_method, value_method, selected), :label => g) 243: end).join 244: else 245: options(collection || [], text_method, value_method, selected, b) 246: end 247: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 128 128: def process_form_attrs(attrs) 129: method = attrs[:method] 130: 131: # Unless the method is :get, fake out the method using :post 132: attrs[:method] = :post unless attrs[:method] == :get 133: # Use a fake PUT if the object is not new, otherwise use the method 134: # passed in. Defaults to :post if no method is set. 135: method ||= (@obj.respond_to?(:new_record?) && !@obj.new_record?) || (@obj.respond_to?(:new?) && !@obj.new?) ? :put : :post 136: 137: attrs[:enctype] = "multipart/form-data" if attrs.delete(:multipart) || @multipart 138: 139: method == :post || method == :get ? "" : fake_out_method(attrs, method) 140: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 272 272: def radio_group_item(method, attrs) 273: attrs.merge!(:checked => "checked") if attrs[:checked] 274: bound_radio_button(method, attrs) 275: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 156 156: def update_bound_check_box(method, attrs) 157: raise ArgumentError, ":value can't be used with a bound_check_box" if attrs.has_key?(:value) 158: 159: attrs[:boolean] = attrs.fetch(:boolean, true) 160: 161: val = control_value(method) 162: attrs[:checked] = attrs.key?(:on) ? val == attrs[:on] : considered_true?(val) 163: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 147 147: def update_bound_controls(method, attrs, type) 148: case type 149: when "checkbox" 150: update_bound_check_box(method, attrs) 151: when "select" 152: update_bound_select(method, attrs) 153: end 154: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 165 165: def update_bound_select(method, attrs) 166: attrs[:value_method] ||= method 167: attrs[:text_method] ||= attrs[:value_method] || :to_s 168: attrs[:selected] ||= control_value(attrs[:value_method]) 169: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 184 184: def update_unbound_check_box(attrs) 185: boolean = attrs[:boolean] || (attrs[:on] && attrs[:off]) ? true : false 186: 187: case 188: when attrs.key?(:on) ^ attrs.key?(:off) 189: raise ArgumentError, ":on and :off must be specified together" 190: when (attrs[:boolean] == false) && (attrs.key?(:on)) 191: raise ArgumentError, ":boolean => false cannot be used with :on and :off" 192: when boolean && attrs.key?(:value) 193: raise ArgumentError, ":value can't be used with a boolean checkbox" 194: end 195: 196: if attrs[:boolean] = boolean 197: attrs[:on] ||= "1"; attrs[:off] ||= "0" 198: end 199: 200: attrs[:checked] = "checked" if attrs.delete(:checked) 201: end
# File merb-helpers/lib/merb-helpers/form/builder.rb, line 171 171: def update_unbound_controls(attrs, type) 172: case type 173: when "checkbox" 174: update_unbound_check_box(attrs) 175: when "radio" 176: update_unbound_radio_button(attrs) 177: when "file" 178: @multipart = true 179: end 180: 181: attrs[:disabled] ? attrs[:disabled] = "disabled" : attrs.delete(:disabled) 182: end