Home » Javascript » Is there a way to regenerate link_to_add_association (specifically data-association-insertion-template)?

Is there a way to regenerate link_to_add_association (specifically data-association-insertion-template)?

Posted by: admin November 1, 2017 Leave a comment

Questions:

Built a very basic rails app to manipulate nested attributes using cocoon and the add and remove links work great. However, it wasn’t too long until I wanted to alter the underlying content of what was inserted, say in response to another field changing the list of option values in an included select tag. It appears that the contents to be added are contained in an ‘a’ tag data element (data-association-insertion-template). I can quite easily change the select options for all included lines via jQuery but changing the behavior of the link_to_add_association is beyond me.

Here are snippets of my example:

_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)

I have tried to manipulate the template data string directly via js str.replace but that is one ugly regular expression because of the unescapeHTML and htmlsafe operations done to make it an attribute in the first place. And, that approach doesn’t smell good to me. I have been slowly working through the cocoon view_helpers and javascript but nothing seems to fit or I don’t seem to have the right methods/data values to build a replacement link. Suggestions?

BTW, kudos for cocoon gem.

Answers: