Динамические поля формы в Rails3 с помощью jquery

#jquery #ruby-on-rails #ajax #ruby-on-rails-3

#jquery #ruby-on-rails #ajax #ruby-on-rails-3

Вопрос:

Я использую rialscasts # 74 в качестве руководства.

Я пытаюсь динамически добавлять поля формы через текстовую ссылку. В эпизоде railscast он делает это очень красиво, используя следующий код:

 <!-- layouts/application.rhtml -->
<%= javascript_include_tag :defaults %>

<!-- projects/new.rhtml -->
<div id="tasks">
  <%= render :partial => 'task', :collection => @project.tasks %>
</div>
<p><%= add_task_link "Add a task" %></p>

<!-- projects/_task.rhtml -->
<div class="task">
<% fields_for "project[task_attributes][]", task do |task_form| %>
  <p>
    Task: <%= task_form.text_field :name %>
    <%= link_to_function "remove", "$(this).up('.task').remove()" %>
  </p>
<% end %>
</div>

 # projects_helper.rb

 def add_task_link(name)
    link_to_function name do |page|
      page.insert_html :bottom, :tasks, :partial => 'task', :object => Task.new
    end
 end
  

содержимое в projects_help.rb — это то, что меня больше всего интересует. Проблема в том, что он делает это через прототип. Я ищу точную дублирующую реализацию с использованием jquery (и rails3). Что вы думаете? Спасибо!

Ответ №1:

да, я собирался сказать — это очень старый railscast, использующий как устаревшие методы, так и старую структуру. Я попытаюсь вам помочь.

макеты/application.erb

 <%= javascript_include_tag :defaults %>
  

проекты/new.erb

 <div id="tasks">
  <%= render :partial => 'task', :collection => @project.tasks %>
</div>
<p><%= add_task_link "Add a task" %></p>
  

проекты/_task.erb

 <div class="task">
<!-- I think this part should still work -->
<%= fields_for "project[task_attributes][]", task do |task_form| %>
  <p>
    Task: <%= task_form.text_field :name %>
    <!-- We're going to be defining the click behavior with unobtrusive jQuery -->
    <%= link_to "remove", "#", :class => 'remove_task'
  </p>
<% end %>
</div>
  

projects_helper.rb

 def add_task_link(name)
  # This is a trick I picked up... if you don't feel like installing a
  # javascript templating engine, or something like Jammit, but still want
  # to render more than very simple html using JS, you can render a partial
  # into one of the data-attributes on the element.
  #
  # Using Jammit's JST abilities may be worthwhile if it's something you do
  # frequently though.
  link_to name, "#", "data-partial" => h(render(:partial => 'task', :object => Task.new)), :class => 'add_task'
end
  

public/javascripts/application.js

 $(function(){
  // Binds to the remove task link...
  $('.remove_task').live('click', function(e){
    e.preventDefault();
    $(this).parents('.task').remove();
  });

  // Add task link, note that the content we're appending
  // to the tasks list comes straight out of the data-partial
  // attribute that we defined in the link itself.
  $('.add_task').live('click', function(e){
    e.preventDefault();
    $('#tasks').append($(this).data('partial'));
  });
});
  

Комментарии:

1. Моя частичная обработка данных выходит неэкранированной и портит рендеринг элементов повсюду. Я чего-то здесь не хватает или делаю неправильно? Кажется, что это неправильно отображается, по крайней мере, с Rails 3.1

2. @DFischer ты позаботился о том, чтобы поместить h () вокруг рендеринга в этом атрибуте? Я заметил, что иногда по какой-то причине это не совсем работает, и мой обходной путь заключался в том, чтобы сделать это: h(render(stuff_here) '') . Я подозреваю, что проблема в том, что render () помечается как html_safe, а затем запускается h () и видит, что это безопасный html, поэтому решает по какой-то причине не избегать его. Добавление пустой строки сделает ее больше не html_safe, так что, надеюсь, это сработает 🙂

Ответ №2:

Текущие железнодорожные трансляции / ASCII-трансляции имеют #196 (см.http://asciicasts.com/episodes/196-nested-model-form-part-1 ) и 197, которые были обновлены для Rails3.

Райан Бейтс также создал драгоценный камень под названием nested_form (см. https://github.com/ryanb/nested_form), который обрабатывает большую часть этого за вас. Он также создал примеры сложных вложенных форм, используя Prototype, jQuery и свой драгоценный камень вложенных форм; вы можете найти ссылку на странице nested_forms.

Отличная штука!