Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If I got you right...</p> <p><strong>1. Add a generated ID as a hidden field to your form</strong><br> This ID does not really have to be a virtual attribute for your model but can be. Another option is to put it outside of your mass-assignment array, like e.g <code>params[:controller]</code> also is. </p> <p>Example: <code>&lt;%= hidden_field_tag :temporary_id, SecureRandom.hex %&gt;</code>. For other possibilities on creating a random string, have a look at <a href="https://stackoverflow.com/questions/88311/how-best-to-generate-a-random-string-in-ruby">how-best-to-generate-a-random-string-in-ruby </a>.</p> <p>Also make sure that your form (or the first element which gets rendered in your form partial) has that generated random string as <code>id</code> or <code>data-</code> attribute, so you can access it without using a complicated selector in the next step.</p> <p><strong>2. Update your create.js.erb</strong><br> I assume your <code>format.js</code> in your create action passes over to <code>create.js.erb</code>. So in there, you replace the whole form with a new one, by searching for that temporary id which got passed on submit.</p> <p>Example: <code>$('#&lt;random_id_of_your_form&gt;').replaceWith('&lt;%= j render(partial: 'form', locals: {...}) %&gt;');</code></p> <p>Make sure to not omit <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html" rel="nofollow noreferrer">the <code>j</code> helper</a> as it encodes your rendered form for save use in javascript. As you are rendering your usual form, the create action does its usual business, and now also replaces the form with a new rendered one, where automatically, the "update" action is called (the usual rails "magic" stuff in routing, that is. like you'd render another usual edit form).</p> <p><strong>Javascript</strong> </p> <blockquote> <p>After the ratings forms are replaced, the Javascript no longer works on that partial.</p> </blockquote> <p>Of course it isn't. You're binding events to specific elements on document load. The elements you insert afterwards (via create/update) are newly added, and thus do not have that event binding because they were not available at the time of the event-binding taking place. </p> <p>Since <a href="https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing">events are "bubbling"</a>, you need to bind your code to a container which is persistent across your js-modifications. Lets say your create.js only updates/replaces elements in <code>#rating_questions_container</code>, you'd need to rewrite the js to e.g. </p> <pre><code>$('#rating_questions_container').on('click', 'form.rating_ballot &gt; label', function(e) { # code }); </code></pre> <ul> <li><code>$('#rating_questions_container')</code> is the "persistent" container on your page, that can capture the events</li> <li><code>.on('click', 'form.rating_ballot &gt; label'</code> watches for click events on elements matching the selector in the second argument, here <code>form.rating_ballot &gt; label</code>. </li> </ul> <p>This allows to dynamically append/remove DOM nodes inside of <code>#rating_questions_container</code> without losing event listeners.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload