I would like to add the number_field form helper that exists in rails 3 to my rails 2.3.15 app, but i'm having trouble extending the module.
These are the methods I need from rails 3
class InstanceTag
def to_number_field_tag(field_type, options = {})
options = options.stringify_keys
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
to_input_field_tag(field_type, options)
end
end
def number_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options)
end
def number_field_tag(name, value = nil, options = {})
options = options.stringify_keys
options["type"] ||= "number"
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
text_field_tag(name, value, options)
end
I'm adding this to a module which i include in my application helper. The to_number_field_tag
method is easy because i can just open the class and add the override.
The FormHelper module methods I'm having trouble with because i can't quite figure out the ancestors chain and don't know how to scope my override. I don't know how to make it work basically.
My problem above was that i was not overriding the FormBuilder. Here is a solution for those who might need this in the future.
Rather than just implementing the type="number"
input type, i decided to make a generic helper for all new HTML5 inputs. I place this code in an overrides file which i include in application_helper.rb .
# file 'rails_overrides.rb`
ActionView::Helpers::InstanceTag.class_eval do
def to_custom_field_tag(field_type, options = {})
options = options.stringify_keys
to_input_field_tag(field_type, options)
end
end
ActionView::Helpers::FormBuilder.class_eval do
def custom_field(method, options = {}, html_options = {})
@template.custom_field(@object_name, method, objectify_options(options), html_options)
end
end
# form.custom_field helper to use in views
def custom_field(object_name, method, options = {}, html_options = {})
ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_custom_field_tag(options.delete(:type), options)
end
# form.custom_field_tag helper to use in views
def custom_field_tag(name, value = nil, options = {})
options = options.stringify_keys
# potential sanitation. Taken from rails3 code for number_field
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
text_field_tag(name, value, options)
end
Then to use this in your views:
<% form_for... do |form| %>
<%= form.custom_field :user_age, :type=>"number", :min=>"0", :max=>"1000" %>
<%= form.custom_field :email, :type=>"email", :required=>"true" %>
<% end %>
Which will generate an <input type='number', and an <input type='email'
If you have a custom form builder, you will need to expand/override that as well. Namespace may vary, but most standard is like this:
MySpecialFormBuilder.class_eval do
def custom_field(method, options = {}, html_options = {})
...custom form builder implementation
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.