2016-07-27 25 views
3

Ich habe eine Vorlage, die mehrere PropertyLists haben kann, mein Ziel ist es, ein Formular mit den zugehörigen PropertyLists und den verfügbaren PropertyLists zu haben. In diesem Formular möchte ich ziehen können & Drop und sortieren von Elementen. Ich verwende Rails 5, mit nested_form_fields und JQuery-UI (nur das jquery-UI/sortierbare Modul).Rails Drag & Drop & Sortierung von Elementen zu einem verschachtelten Formular

Hier sind meine Modelle:

Vorlage:

class Template < ApplicationRecord 
    has_many :template_property_lists 
    has_many :property_lists, through: :template_property_lists 
    accepts_nested_attributes_for :property_lists 
    validates_presence_of :name 
end 

Property:

class PropertyList < ApplicationRecord 
    has_many :properties, -> { order(position: :asc) }, dependent: :destroy 
    has_many :template_property_lists 
    has_many :templates, through: :template_property_lists 

    accepts_nested_attributes_for :properties, allow_destroy: true, reject_if: :all_blank 
    acts_as_list scope: :template, top_of_list: 0 

    validates_presence_of :name 
    validates_uniqueness_of :name 
end 

TemplatePropertyList:

Und der JavaScript-Code:

$(function() { 
    $(".sortable").sortable({ 
     update: function(event, ui) { 
      var index = ui.item.index(); 
      ui.item.find('input.position').val(index); 
     } 
    }).disableSelection(); 
}); 


$(function() { 
    $(".used, .available").sortable({ 
    connectWith: ".connected-sortable", 
     placeholder: "ui-state-highlight" 
    }).disableSelection(); 
}); 

Die Form Teil:

<div class="panel panel-default"> 
    <div class="panel-heading"> 
    <h1 class="panel-title"> 
     <%= t(:template) %> 
    </h1> 
    </div> 

    <div class="panel-body"> 
    <div class="col-md-6"> 
     <div class="form-group <%= 'has-error' if @template.errors[:name].present? %>"> 
     <%= f.label :name, t(:name) %> 
     <%= f.text_field :name, class: 'form-control' %> 
     </div> 
    </div> 

    <div class="col-md-6"> 
     <div class="form-group <%= 'has-error' if @template.errors[:description].present? %>"> 
     <%= f.label :description, t(:description) %> 
     <%= f.text_field :description, class: 'form-control' %> 
     </div> 
    </div> 

    </div> 
</div> 

<!-- Template Property Lists --> 
<div class="panel panel-default"> 
    <div class="panel-heading"> 
    <h1 class="panel-title"> 
     <%= t(:property_lists) %> 
    </h1> 
    </div> 

    <div class="panel-body"> 
    <ul class="list-group"> 
     <li class="list-group-item"> 
     <div class="row text-center"> 
      <div class="col-md-1"></div> 
      <div class="col-md-5"> 
      <%= label_tag t(:name) %> 
      </div> 
      <div class="col-md-5"> 
      <%= label_tag t(:description) %> 
      </div> 
      <div class="col-md-1 text-center"></div> 
     </div> 
     </li> 
    </ul> 

    <ul class="list-group used connected-sortable"> 
     <%= f.nested_fields_for :property_lists do |p| %> 
     <li class="list-group-item"> 
     <%= p.hidden_field :position, class: 'position' %> 
     <%= p.hidden_field :name %> 
     <%= p.hidden_field :description %> 
     <div class="row text-center"> 
      <div class="col-md-1"> 
      <span class="glyphicon glyphicon-sort"></span> 
      </div> 
      <div class="col-md-5"> 
      <%= p.object.name%> 
      </div> 
      <div class="col-md-5"> 
      <%= p.object.description%> 
      </div> 
      <div class="col-md-1 text-center"></div> 
     </div> 
     </li> 
     <% end %> 
    </ul> 
    </div> 

</div> 

<!-- Available Property Lists --> 
<div class="panel panel-default"> 
    <div class="panel-heading"> 
    <h1 class="panel-title"> 
     <%= t(:available_property_lists) %> 
    </h1> 
    </div> 

    <div class="panel-body"> 
    <ul class="list-group"> 
     <li class="list-group-item"> 
     <div class="row text-center"> 
      <div class="col-md-1"></div> 
      <div class="col-md-5"> 
      <%= label_tag t(:name) %> 
      </div> 
      <div class="col-md-5"> 
      <%= label_tag t(:description) %> 
      </div> 
      <div class="col-md-1"></div> 
     </div> 
     </li> 
    </ul> 

    <ul class="list-group available connected-sortable"> 
     <% @available_property_lists.each do |property_list| %> 
     <li class="list-group-item"> 
     <%= hidden_field_tag :position, class: 'position' %> 
     <%= hidden_field_tag :id, property_list.id %> 
     <div class="row text-center"> 
      <div class="col-md-1"> 
      <span class="glyphicon glyphicon-sort"></span> 
      <% property_list.id %> 
      </div> 
      <div class="col-md-5"> 
      <%= property_list.name %> 
      </div> 
      <div class="col-md-5"> 
      <%= property_list.description %> 
      </div> 
     </div> 
     </li> 
     <% end %> 
    </ul> 
    </div> 
</div> 

Mein Problem: Wenn ich das Formular Ich möchte die gewählten TemplateLists im Zusammenhang mit der Vorlage, Bedeutung einreichen Das property_lists_attributes wird PropertyLists in dem Abschnitt Template PropertyLists und mit dem richtigen Reihenfolge-Parameter haben. Beachten Sie, dass dies eine einfache Formularübergabe ist, nicht ein AJAX, wenn Sie & Drop oder Sort ziehen.

Antwort

2

Um dies zu lösen ich ein versteckten Felder in der available_property_lists.by verwendet hinzugefügt habe:

<%= hidden_field_tag "template[template_property_lists_attributes][#{property_list.id}][property_list_id]", property_list.id %> 
<%= hidden_field_tag "template[template_property_lists_attributes][#{property_list.id}][position]", property_list.position, class: 'position' %> 
<%= hidden_field_tag "template[template_property_lists_attributes][#{property_list.id}][template_id]", template.id %> 
<%= hidden_field_tag "template[template_property_lists_attributes][#{property_list.id}][_destroy]", true, class: 'destroy' %> 

und auch versteckte Felder auf die benutzten:

<%= p.hidden_field :id %> 
<%= p.hidden_field :position, class: 'position' %> 
<%= p.hidden_field :property_list_id %> 
<%= p.hidden_field :template_id %> 
<%= p.hidden_field :_destroy, class: 'destroy' %> 

und dieser Javascript zu sortieren und aktivieren oder Deaktivieren Sie das Kontrollkästchen _destroy:

$(function() { 
    $(".used, .available").sortable({ 
     connectWith: ".connected-sortable", 
     placeholder: "ui-state-highlight", 
    }); 
    $(".available").on("sortremove", function(event, ui) { 
     ui.item.find('input.destroy').val(false); 
    }); 

    $(".used").on("sortremove", function(event, ui) { 
     ui.item.find('input.destroy').val(true); 
    }); 
});