Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger cocoon add_association from javascript

I am using cocoon and I want to automatically add a child record when a date(can be multiple dates) in a date picker is selected.

I can trap the date selections in coffeescript like this, but I don't know how to get a child record added through cocoon i.e. by emulating what happens when the link_to_add_association is fired.

$(".form_multidate").datepicker().on 'changeDate', (e) -> alert(e.dates)

the cocoon setup is a standard nested form, no tricks, working fine on the page.

EDIT: Code mentioned in comment re binding calendar:

$(document).ready(function() {
  $('#other_request_details')
    .bind('cocoon:after-insert', function() {
      return $('.datepicker-single').datepicker({
        dateFormat: "DD, dd M yy"
      });
    });
});    
like image 564
Craig McGuff Avatar asked Nov 11 '22 09:11

Craig McGuff


1 Answers

Calling a JS function in order to add a new record with Cocoon is not possible. The only thing you can do is trigger the click event of the add association button.

If you see Cocoon's library code you will see that all new record functionality is bound to the click button

 $(document).on('click', '.add_fields', function(e) {
    e.preventDefault();
    var $this                 = $(this),
        assoc                 = $this.data('association'),
        assocs                = $this.data('associations'),
        content               = $this.data('association-insertion-template'),
        insertionMethod       = $this.data('association-insertion-method') || $this.data('association-insertion-position') || 'before',
        insertionNode         = $this.data('association-insertion-node'),
        insertionTraversal    = $this.data('association-insertion-traversal'),
        count                 = parseInt($this.data('count'), 10),
        regexp_braced         = new RegExp('\\[new_' + assoc + '\\](.*?\\s)', 'g'),
        regexp_underscord     = new RegExp('_new_' + assoc + '_(\\w*)', 'g'),
        new_id                = create_new_id(),
        new_content           = content.replace(regexp_braced, newcontent_braced(new_id)),
        new_contents          = [];


    if (new_content == content) {
      regexp_braced     = new RegExp('\\[new_' + assocs + '\\](.*?\\s)', 'g');
      regexp_underscord = new RegExp('_new_' + assocs + '_(\\w*)', 'g');
      new_content       = content.replace(regexp_braced, newcontent_braced(new_id));
    }

    new_content = new_content.replace(regexp_underscord, newcontent_underscord(new_id));
    new_contents = [new_content];

    count = (isNaN(count) ? 1 : Math.max(count, 1));
    count -= 1;

    while (count) {
      new_id      = create_new_id();
      new_content = content.replace(regexp_braced, newcontent_braced(new_id));
      new_content = new_content.replace(regexp_underscord, newcontent_underscord(new_id));
      new_contents.push(new_content);

      count -= 1;
    }

    var insertionNodeElem = getInsertionNodeElem(insertionNode, insertionTraversal, $this)

    if( !insertionNodeElem || (insertionNodeElem.length == 0) ){
      console.warn("Couldn't find the element to insert the template. Make sure your `data-association-insertion-*` on `link_to_add_association` is correct.")
    }

    $.each(new_contents, function(i, node) {
      var contentNode = $(node);

      insertionNodeElem.trigger('cocoon:before-insert', [contentNode]);

      // allow any of the jquery dom manipulation methods (after, before, append, prepend, etc)
      // to be called on the node.  allows the insertion node to be the parent of the inserted
      // code and doesn't force it to be a sibling like after/before does. default: 'before'
      var addedContent = insertionNodeElem[insertionMethod](contentNode);

      insertionNodeElem.trigger('cocoon:after-insert', [contentNode]);
    });
  });
like image 144
mentalic Avatar answered Nov 14 '22 21:11

mentalic