Подтвердить что ты не робот

Как вы получаете идентификатор Ruby on Rails для элемента формы для ссылки в JavaScript?

При использовании вызова form_for и вызова text_field Ruby on Rails генерирует уникальный идентификатор для элемента <input />, который он выдает. Как я могу сгенерировать один и тот же идентификатор для последующего включения в JavaScript, сгенерированный позже?

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

Затем на странице:

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

Ответ 1

В итоге я создал настраиваемый конструктор форм, чтобы напрямую открыть свойство

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

Затем установите конструктор форм по умолчанию

ActionView::Base.default_form_builder = FormBuilder 

Ответ 2

Посмотрите варианты компоновщика форм:

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

Параметры должны включать по меньшей мере следующие данные: класс css, id, метод http и токен аутентификации.

Ответ 3

Вам нужно указать идентификатор самостоятельно. Здесь генерирование id из object_id формы гарантирует, что оно не будет конфликтовать с другим текстовым полем для имени пользователя в случае вложенных форм.

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

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

Ответ 4

Если у кого-то есть объект FormBuilder из блока fields_for, получите его id с помощью этого фрагмента:

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

FieldsForm#object_name возвращает идентификатор поля как что-то вроде этого: user[address][0]. Далее, замещение регулярного выражения изменяет группы из одного или нескольких скобок для подчеркивания. Эта замена оставляет конечное подчеркивание, к которому оно добавляет буквы id. В приведенном выше примере это приводит к user_address_0_id.

Ответ 5

В Rails 4.1 мне удалось получить идентификатор с этим:

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

Он работает с вложенными формами (fields_for).

Ответ 6

Мне не очень нравится мое собственное решение, но я старался не идти и исправлять 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

Ответ 7

Так как ваш Javascript-код помещается в встроенный в Ruby файл (.erb), который интерпретируется сервером перед отправкой в ​​клиентский браузер, вы можете сгенерировать требуемую переменную JS с помощью фрагмента ruby, например:

var id='#id_for_'+<%= @user.username %>
var id='#comment_info_'+<%= n %>

а затем используйте его просто как $(id).doSomethingReallyCool();.

Если вам нужно контролировать значение идентификатора, сгенерированного формой в первом экземпляре, вы можете сделать это, передав id в хэш-хеш-вариантах:

f.text_field :username, id:"id_for_#{…}"

Если вы используете ненавязчивый подход 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-код. Если эти переменные пришли из формы, поместите их в подходящие скрытые поля формы. И затем используйте параметр render locals, чтобы они были доступны вашим частичным, как в:

format.js { render 'foo_doo', locals: {n:n} }

Если код JS обновляет шаблон, который использует некоторые переменные, используйте тот же подход:

var id='#comment_info_'+<%= n %>
$(id).replaceWith("<%= j (render partial:…, locals: {…}) %>")

Ответ 8

Я предполагаю, что на странице есть несколько form_for, и каждая из них имеет собственную кнопку отправки. Я думаю, именно так я бы сделал это:

Введите скрытое поле в form_for и установите его значение для идентификатора поля ввода. Здесь я выбрал input_#{n} как идентификатор поля ввода. Конечно, я определяю идентификатор для каждого ввода.

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

Затем на submit я могу получить идентификатор формы в моих параметрах params[:user][:input_id], которые я могу передать в js.erb с помощью locals.

Надеюсь, что это поможет:)