How do you get the Ruby on Rails generated id of a form element for reference in JavaScript?

前端 未结 8 886
無奈伤痛
無奈伤痛 2021-02-05 01:01

When using the form_for helper and a text_field call, Ruby on Rails will generate a unique id for the element that it outp

相关标签:
8条回答
  • 2021-02-05 01:33

    Look at the form builder options:

    <%= form_for @user do |f| %>
      <% form_css_id = "#" + f.options[:html][:id] %>
    <% end %>
    

    Options should at least include the following data: css class, id, http method and authenticity token.

    0 讨论(0)
  • 2021-02-05 01:34

    I don't really like my own solution that much, but I tried not to go and patch InstanceTag.

    Unfortunately that meant lifting the sanitization code from ActionView::Helpers::InstanceTagMethods

    class MyCoolFormBuilder < ActionView::Helpers::FormBuilder
        def sanitized_object_name
          @sanitized_object_name ||= object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
        end
    
        def field_id_for(method)
          "#{sanitized_object_name}_#{method.to_s.sub(/\?$/,"")}"
        end
    end
    
    0 讨论(0)
  • 2021-02-05 01:39

    In case someone has a FormBuilder object from a fields_for block, it is possible to get its id using this snippet:

    <%= form.fields_for :something do |fields_form| %>
      <%= fields_form.object_name.gsub(/[\[\]]+/, '_').chop %>id
    <% end %>
    

    FieldsForm#object_name returns the field's ID as something like this: user[address][0]. Next, the regex substitution changes groups of one or more brackets to underscores. This substitution leaves a trailing underscore, to which it appends the letters id. For the example provided before, this results in user_address_0_id.

    0 讨论(0)
  • 2021-02-05 01:43

    In Rails 4.1 I was able to get the id with this:

    ActionView::Base::Tags::Base.new(
      f.object_name,
      :username,
      :this_param_is_ignored,
    ).send(:tag_id)
    

    It works with nested forms (fields_for).

    0 讨论(0)
  • 2021-02-05 01:43

    I assume that there are multiple form_for in the page and each has it's own submit button. I think this is how I would do this:

    Have a hidden field in the the form_for and set it's value to the id of the input field. Here I've chosen input_#{n} as the id of the input field. Of course I'll define the id for each input.

    <%= form_for @user do |f| %>
      <%= f.text_field :username, id: "input_#{n}" %>
      <%= hidden_field_tag 'user[input_id]', value: "input_#{n}" %>
      <%= f.submit %>
    <% end %>   
    

    Then on submit I can get the id the form input in my params params[:user][:input_id] which I can pass to the js.erb using the locals.

    Hope this helps :)

    0 讨论(0)
  • 2021-02-05 01:48

    I ended up creating a custom form builder to expose the property directly

    class FormBuilder < ActionView::Helpers::FormBuilder
      def id_for(method, options={})
       InstanceTag.new( object_name, method, self, object ) \
                   .id_for( options )               
      end
    end
    
    class InstanceTag < ActionView::Helpers::InstanceTag
      def id_for( options )
        add_default_name_and_id(options)
        options['id']
      end
    end
    

    Then set the default form builder

    ActionView::Base.default_form_builder = FormBuilder 
    
    0 讨论(0)
提交回复
热议问题