2017-10-26 1 views
1

Erbaut eine sehr einfache Rails-App, um verschachtelte Attribute mit Hilfe von Cocoon zu manipulieren und die Add- und Remove-Links funktionieren großartig. Es dauerte jedoch nicht lange, bis ich den zugrunde liegenden Inhalt des eingefügten Elements ändern wollte, etwa als Reaktion auf ein anderes Feld, das die Liste der Optionswerte in einem eingeschlossenen Auswahl-Tag änderte. Es scheint, dass die hinzuzufügenden Inhalte in einem "a" -Tag-Datenelement enthalten sind (data-association-insertion-template). Ich kann die Auswahloptionen für alle eingeschlossenen Zeilen ganz einfach über jQuery ändern, aber das Ändern des Verhaltens von link_to_add_association ist mir nicht möglich.Gibt es eine Möglichkeit, Link_to_add_association (speziell Daten-Association-Insertion-Template) zu regenerieren?

Hier sind Schnipsel meines Beispiel:

_form.html.erb

<div> 
    <strong>Entries:</strong> 
    <div id="entries" style="border: thin solid"> 
     <%= f.fields_for :entries do |oi| %> 
     <%= render "entry_fields", f: oi %> 
     <% end %> 
     <div class="links"> 
     <%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry'} %> 
     </div> 
    </div> 
    </div> 

_entry_fields.html.erb

<div class="nested-fields"> 
    <%= f.label :item_id %> 
    <%= f.select :item_id, @items.collect {|i| [i.style, i.id]}, {include_blank: true}, {selected: :item_id, multiple: false} %> 

    <%= f.label :decoration_id, 'Decoration' %> 
    <%= f.select :decoration_id, @decorations.collect { |d| [ d.name, d.id ] }, {include_blank: true}, {selected: :decoration_id, multiple: false, class: 'decoration'} %> 

    <%= f.label :color %> 
    <%= f.text_field :color %> 

    <%= f.label :size_id %> 
    <%= f.select :size_id, @sizes.collect { |s| [ s.name, s.id ] }, {include_blank: true}, {selected: :size_id, multiple: false} %> 

    <%= f.label :number %> 
    <%= f.number_field :number, value: 1, min: 1 %> 

    <%= f.check_box :_destroy, hidden: true %> 

    <%= link_to_remove_association "Remove Entry", f %> 
</div> 

orders.coffee

ready = -> 
    $('.customer').change -> 
    $.ajax 
     url: '/orders/change_customer' 
     data: { customer_id : @value } 

$(document).ready(ready) 
$(document).on('turbolinks:load', ready) 

order_controller .rb

def change_customer 
    @decorations = Decoration.joins(:logo).where('logos.customer_id = ?', params[:customer_id]) 
    respond_to do |format| 
     format.js 
    end 
    end 

change_customer.js.erb

// update all existing entry decorations with new customer driven options 
<% new_decor = options_from_collection_for_select(@decorations, :id, :name) %> 
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>"; 
$('.decoration').html(new_decor_options); 

// now need to change $('#cocoon-add-entry').attr('data-association-insertion-template, ???); 
// or regenerate link entirely - but don't have required data to do so here (form builder from original) 

ich versucht habe, die Vorlage Datenfolge direkt über js str.replace zu manipulieren, aber das ist ein hässlicher regulärer Ausdruck wegen der unescapeHTML und htmlsafe Operationen getan mach es zu einem Attribut an erster Stelle. Und diese Vorgehensweise riecht mir nicht gut. Ich habe langsam durch den Kokon View_Helpers und Javascript gearbeitet, aber nichts scheint zu passen oder ich habe nicht die richtigen Methoden/Datenwerte, um einen Ersatzlink zu bauen. Vorschläge?

BTW, Kudos für Kokon gem.

+0

Schauen Sie sich den Callback an, der es erlaubt, die einzufügende (oder eingefügte html) vor oder nach dem Einfügen zu manipulieren. Überprüfen Sie: https://github.com/nathanvda/cocoon#callbacks-upon-insert-and-remove-of-items – nathanvda

+0

Vielen Dank für die Richtung - ich habe diesen Artikel überflogen. Es gibt leider einen Punkt, den ich nicht ganz verstehe. Es passiert zufällig in der "tue etwas hier" -Referenz, glaube ich. Was ich versuche zu tun, ist eine neue Sammlung von Sammlungsoptionen für den Link Assoziation hinzufügen. Ich sende eine Anfrage zurück an den Server, um sie zu erhalten, und möchte dann entweder den Link neu erstellen (aber den ursprünglichen FormBuilder nicht verwenden, um einen Link zu link_to_add_association zu verwenden) oder diesen Teil der Einfügemaske im vorhandenen HTML ändern. Wie und wo würde diese Änderung im Beispiel umgesetzt? – Rondo

+0

Ein Callback ermöglicht es, den einzufügenden HTML-Code mit Javascript zu manipulieren, zB die Liste der verfügbaren Optionen zu ändern. Das wäre viel sauberer als das, was Sie jetzt vorschlagen. Auch beiseite: wenn sich der Kunde ändert (was nicht in der Form ist?) Sollten nicht alle Dropdowns geändert werden? Oder nur neue? – nathanvda

Antwort

1

Nach viel Zähneknirschen habe ich eine mögliche Lösung zusammengeschustert. Ich habe noch nicht entschieden, ob ich das in die Produktion gehen lassen noch wegen der Einschränkungen aber dank verschiedenen SO Fragen und Antworten, die Kombination, die folgenden Werke:

change_customer.js.erb

// update all existing entry decorations with new customer driven options 
<% new_decor = options_from_collection_for_select(@decorations, :id, :name) %> 
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>"; 
$('.decoration').html(new_decor_options); 

// update the Add Entry link to capture new decorations set. 
// Note use of ugly hack to recreate 'similar' form. 
// Also note that this will only work for new order; will have to revise for edit. 
'<%= form_for(Order.new) do |ff| %>' 
$('#cocoon-add-entry').replaceWith("<%=j render partial: 'add_entry_link', locals: {f: ff} %>"); 
'<% end %>' 

_add_entry_link .html.erb

<%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry', data: {'association-insertion-method' => 'after'}} %> 
+0

rettete mein Leben, thx – MurifoX

Verwandte Themen