如何获得RubyonRails生成的表单元素id,以供JavaScript中引用?

如何获得RubyonRails生成的表单元素id,以供JavaScript中引用?,javascript,ruby-on-rails,forms,Javascript,Ruby On Rails,Forms,当为助手使用表单和文本字段调用时,Ruby on Rails将为它输出的元素生成一个唯一的id。如何生成相同的id,以便以后包含到以后生成的JavaScript中 <%= form_for @user do |f| %> <%= f.text_field :username %> <% end %> 然后在本页的后面: <%= javascript_tag do %> $('<%= id of the :username fie

当为助手使用
表单和
文本字段
调用时,Ruby on Rails将为它输出的
元素生成一个唯一的id。如何生成相同的id,以便以后包含到以后生成的JavaScript中

<%= form_for @user do |f| %>
  <%= f.text_field :username %>
<% end %>

然后在本页的后面:

<%= javascript_tag do %>
  $('<%= id of the :username field %>').doSomethingReallyCool();
<% end %>

$('').doSomethingReallyCool();

您需要自己指定id。在这里,从表单的object_id生成id可以保证在嵌套表单的情况下,它不会与用户名的另一个text_字段冲突

<%= form_for @user do |f| %>
  <%- id = "username_#{f.object_id}" %>
  <%= f.text_field :username, :id=>id %>
<% end %>

<%= javascript_tag do %>
  $("##{id}").doSomethingReallyCool();
<% end %>

id%>
$(“##{id}”).doSomethingReallyCool();

我最终创建了一个自定义表单生成器来直接公开属性

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

我真的不太喜欢自己的解决方案,但我尽量不去修补InstanceTag

不幸的是,这意味着从
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
class MyColFormBuilder
查看表单生成器选项:

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


选项应至少包括以下数据:css类、id、http方法和真实性令牌。

如果有人从
块的
字段中拥有FormBuilder对象,则可以使用此代码段获取其
id

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

身份证件

FieldsForm#object_name
返回字段的ID,如下所示:
user[address][0]
。接下来,正则表达式替换将一个或多个方括号中的组更改为下划线。此替换将留下一个尾随下划线,并在下划线后面附加字母
id
。对于前面提供的示例,这将导致
用户地址\u 0\u id

,因为您的Javascript代码放在ruby嵌入文件(.erb)中在发送到客户端浏览器之前,服务器会对其进行解释,您可以使用ruby代码段生成所需的JS变量,如:

var id='#id_for_'+<%= @user.username %>
var id='#comment_info_'+<%= n %>
如果您使用的是不引人注目的JS方法,您希望将JS代码放入部分(.JS.erb)中,并在用户客户端允许JS的情况下让控制器使用它。例如:

class FooController < ApplicationController

def foo_doo
  … # some logic
  respond_to do |format|
    format.js # this will render javascript in file “foo_doo.js.erb” if allowed
    format.html { … } # html fallback for unobtrusive javascript
  end
end
如果JS代码正在更新使用某些变量的模板,请使用相同的方法:

var id='#comment_info_'+<%= n %>
$(id).replaceWith("<%= j (render partial:…, locals: {…}) %>")
var id='#注释信息'+
$(id)。替换为(“”)

我假设页面中有多个
表单,每个表单都有自己的提交按钮。我想我会这样做:

在表单_for中有一个隐藏字段,并将其值设置为输入字段的id。在这里,我选择了
input 35;{n}
作为输入字段的id。当然,我将为每个输入定义id

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

然后在提交时,我可以在我的params
params[:user][:input_id]
中获取表单输入的id,我可以使用
本地变量将其传递到
js.erb


希望这有帮助:)

在Rails 4.1中,我可以通过以下方式获得id:

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

它适用于嵌套表单(
字段\u用于
).

在这种情况下,这不是一个真正的选项,因为JavaScript和表单字段是动态的,我不一定能够控制
f.text\u字段的调用。这是一个明显的答案,适用于Rails应用程序不动态生成id的特定情况。很好,谢谢!在Rails应用程序中放置此项的最佳位置是哪里?Mike:config/initializers/{file_name}.rb文件可以解决这个问题。我在概念化这是如何调用方面有困难。对我的大脑来说太复杂了,我的姿势。你能提供一个简单的例子吗?在Rails 5中,
ActionView::Helpers::InstanceTag
应该替换为
ActionView::Helpers::Tags::Base
InstanceTag.new(object\u name,method,self,object)
应该是
InstanceTag.new(object\u name,method,self,options)
而不是。f.options[:html]对我来说是零。对我来说不是零!我希望我能更上一层楼。这对HTML5的新“表单”特别有用属性。请尝试以下操作:
。现在您可以使用javascript将该表单移动到您想要的任何位置,提交表单仍然有效。太好了!嵌套对象的值似乎为零,但在父表单上效果很好。更清楚的是,OP询问如何获取用户名字段的id,而不是表单id。这将返回表单id。我将ke to指出,赏金中的附加示例只是另一个特定案例,答案将是有用的。这不是一个不同的问题。要被接受,答案应该足够通用,以符合原始示例和我的示例。这两个示例都显示了需要“获取Ruby on Rails生成的表单元素id,以供JavaScript中引用”.关于当前赏金的元问题@ClaudioFloreani不,那不好。请记住,赏金到期或授予后,你的赏金文本不再可见。在赏金消失后,回答赏金中的问题将毫无意义。请问一个新问题。@Daskwuff我想你是在问c不理解这两个例子是同一个一般情况下的两个特殊情况的注释。作者只给出了一个“RubyonRails生成的表单元素id”的示例,我给出了另一个示例。示例a和示例B。但问题是“如何获得RubyonRails生成的表单元素id,以便在JavaScript中引用?”但仍然缺乏一个合适的答案。目前接受的答案是(“创建自定义表单生成器”)现在被认为是不好的做法。id name-of-model\u name-of-the-attribute不是吗?你不能给它一个id吗?我在html选项中指定它?我正在尝试你添加的代码段。是吗
var id='#comment_info_'+<%= n %>
$(id).replaceWith("<%= j (render partial:…, locals: {…}) %>")
<%= form_for @user do |f| %>
  <%= f.text_field :username, id: "input_#{n}" %>
  <%= hidden_field_tag 'user[input_id]', value: "input_#{n}" %>
  <%= f.submit %>
<% end %>   
ActionView::Base::Tags::Base.new(
  f.object_name,
  :username,
  :this_param_is_ignored,
).send(:tag_id)