nathanvda / cocoon

Dynamic nested forms using jQuery made easy; works with formtastic, simple_form or default forms
http://github.com/nathanvda/cocoon
MIT License
3.08k stars 382 forks source link

Show spinner or disable link_to_add_association while template is rendering #604

Closed varg90 closed 3 years ago

varg90 commented 3 years ago

Question Hello, I'm using cocoon (1.2.15) with rails (6.0.3.4) Rendering of the association by clicking on link_to_add_association takes a while for complex scenarios.

Is there a way to disable the link / show a loading spinner until the cocoon:after-insert triggers?

I tried to display my spinner element on cocoon:before-insert but it seems that it's triggered right before the cocoon:after-insert and visually my spinner even not appears:

$(document).on('cocoon:before-insert', () => $('.add_association_spinner').show());
$(document).on('cocoon:after-insert', () => $('.add_association_spinner').hide());

I also tried to show my spinner here:

$(document).on('click', '.add_fields', () => $('.add_association_spinner').show());

but it seems that it fires only after the same function from cocoon.js and my spinner appears too late, when the new association template is already inserted and displayed on the page.

I had thinking about to add a button instead of link_to_add_association, that will show my spinner and then trigger the link_to_add_association click, but this doesn't smell like the best practice so I decided to ask here.

Thanks

nathanvda commented 3 years ago

That is weird, that the insertion of the nested form takes so long? That is one incredibly huge form you are inserting? Or with huge drop-down selects?

I am just guessing, but the problem with the spinner is that javascript/browser does not update the screen immediately, so the spinner will never be shown. Like for example here: https://stackoverflow.com/questions/14505615/javascript-show-spinner-save-data-synchronously-remove-spinner

Not sure how you could solve this. Your suggestion with the button: would that make a difference?

From the stackoverflow suggestion, I should do something like [psuedo-code] :

triggerBeforeInsertEvent() 
setTimeout(insertHtmlAndTriggerAfterEvent, 0)

Hopefully this would trigger a repaint of the screen (by giving control back to the browser for an instant), and show the spinner if this was added/shown in a before-insert callback. However I am not sure if this would make general flow "slower" (visibly?) for normal usage.

varg90 commented 3 years ago

Hello. Thanks for your answer. Yes, the association form that user adds with the _link_to_addassociation contains a lot of inputs (most of them are hidden and are toggled with a dropdown select). I will try to show my spinner on the mousedown event, that should fire before the click event. Thanks again