Skip Navigation

[Resolved] Reloading Select2 Javascript After AJAX Submission / Validation

This thread is resolved. Here is a description of the problem and solution.

Problem:

Select2 jQuery library is not initiated after an Ajax load of the Toolset form.

Solution:

According to the customer:

Add the Select2 jQuery library code inside the "cred_form_ready" event using jQuery ON function. For example:

jQuery(document).on( 'cred_form_ready', function($) {
  jQuery('#cred_form_1283_1_1_select-children').select2({
    dropdownParent: '#addChildModal',
    multiple: 'true',
    placeholder: 'Select Child(ren)'
  });
});
This support ticket is created 2 years, 1 month ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 3 replies, has 2 voices.

Last updated by Dave 2 years, 1 month ago.

Assisted by: Christopher Amirian.

Author
Posts
#2476101
Screenshot (61).png
Screenshot (60).png

Tell us what you are trying to do?
Use a Select2 field on my forms, and have it maintain after AJAX submission of the form or validation triggering.

I have numerous forms that are using Select2 (See Screenshot(60).png for an example), and some of them use validation via your cred_form_validate hook. When the validation is triggered (so that the error messages appear), the Select2 features disappear (See Screenshot(61).png). This must, I assume, be because the JS code on the form is not being rerun upon submission and the initial form elements are being destroyed during submission. The same is true if a successful submission is made via AJAX, the form reloads / resets, and the Select2 features are again missing.

Here is the Select2 JS for reference:

jQuery(document).ready(function() {
  jQuery('#cred_form_1283_1_1_select-children').select2({
    dropdownParent: '#addChildModal',
    multiple: 'true',
    placeholder: 'Select Child(ren)'
  });
});

I've seen it mentioned here:

https://toolset.com/forums/topic/modifying-form-select-fields-with-select2-not-working/#post-2076477

That hooks exist for Views, and there must be similar ones for Cred forms. I've had a look through the frontend.js and there appear to be hooks like:

'toolset-ajax-submit'
'toolset-form-onsubmit-validation-success'
'cred_form_ajax_completed'

Could someone please advise on the best hook to use to get this working as it seems a bit of an oversight for Cred not to rerun it's JS when reloading, given that most JS is there to modify the form functionality.

Many thanks.

#2476965

Christopher Amirian
Supporter

Languages: English (English )

Hi there,

This is not a Toolset issue and it is a jQuery thing. jQuery needs special syntax to poll an element and see what changes in ajax there.

Here is a good example that you can use:

https://stackoverflow.com/questions/21664212/jquery-selector-not-finding-elements-when-it-loaded-by-ajax

$(document).on('change','#cred_form_1283_1_1_select-children', function(){
   //Add select 2 code
});

Replace "document" with the wrapper of the whole form.

Replace " //Add select 2 code" with the Select 2 code that you use. with $(this) selector as a starter.

The idea is that jQuery will check for the "change" event on the form wrapper and then if there is a change it will check the proper selector and apply the code.

If you need more jQuery help try to search for "jquery selector ajax loaded elements" in Google and you will get good results.

As this is not a Toolset question, we will not be able to give you the exact code

Thank you.

#2480647

Hi Christopher,

I've read around based on what you've said, and I see what you're saying about it reloading etc. But no matter what I've tried, I can't get it to work. I've spent ages trying different configurations of jQuery and no matter what I do the Select2 will not reload. I've tried the way you and numerous others have suggested via the .on() method like this:

jQuery(document).ready(function(){
  jQuery('#cred_form_1283_1_1').on('change','#cred_form_1283_1_1_select-children', function(){
    alert($(this).attr('id'));
    jQuery(this).select2({
      dropdownParent: '#addChildModal',
      multiple: 'true',
      placeholder: 'Select Child(ren)'
    });
  });
});

I know the .on() method is working and the this context is correct because the alert box will fire and show the correct element ID. But the Select2 does not initialise after the ajax call still.

I've even tried binding it to the ajax success outcome like this:

$('body').on('click','#cred_form_1283_1_1_select-children', function(){
    $.ajax({
      type: "GET",
      cache: false,
      dataType: "html",
      success: function(res) {
        $('#cred_form_1283_1_1_select-children').select2({
          dropdownParent: '#addChildModal',
          multiple: 'true',
          placeholder: 'Select Child(ren)'
        });
      }
    });
  });

Again, it fires but doesn't reload the Select2. I've tried adjusting the scope between the form ID, document and body, all three have the same result. If I remove the initial Select2 call then I can see the Select2 kick in on the change or click events, but still never after a reload.

I've attempted to seek help elsewhere, but no one has been able to tell me why my code won't work. The best suggestion I've had is that something Toolset related is interfering, but I can't see how that makes any sense either as all the parts work, just not together.

For reference here is the full code I'm using at the moment:

jQuery(document).ready(function($) {
  $('#cred_form_1283_1_1_select-children').select2({
    dropdownParent: '#addChildModal',
    multiple: 'true',
    placeholder: 'Select Child(ren)'
  });

  $('#cred_form_1283_1_1').on('click', '#cred_form_1283_1_1_select-children', function(){
    alert($(this).attr('id'));
    $(this).select2({
      dropdownParent: '#addChildModal',
      multiple: 'true',
      placeholder: 'Select Child(ren)'
    });
  });

  $("select[name='select-children'] option:first").remove();
});

I'm really stuck as to why this Select2 won't work after the ajax call, and I get you're not in a position to give me full code and I'm not asking for it. Simply help determining why something that I'm told should work, won't work in this context.

#2480701

The issue WAS Toolset related!

Because the form is being generated by Cred, it is obviously having some extra loading methods or something applied to it, I don't honestly know what. But I was digging through the JS code being called as I mentioned in my original post, and I spotted the cred_form_ready hook or whatever it is.

The second I used this instead of looking at a click event or anything else, the Select2 started working perfectly on every load, no issues. Here is the working code:

jQuery(document).on( 'cred_form_ready', function($) {
  jQuery('#cred_form_1283_1_1_select-children').select2({
    dropdownParent: '#addChildModal',
    multiple: 'true',
    placeholder: 'Select Child(ren)'
  });
});

That's it. That's all that is needed. No initial setup call like I had before, no looking at click or change events, nothing like that. Simply telling the jQuery to run whenever the cred_form_ready hook is run solves everything.

It's very disappointing that the advice I was given sent me on a wild goose chase and the generic advice offered was literally from the first search result suggested. I don't know if there is a way to get it working as suggested by support, but given the results I've seen, I'm pretty certain that THIS is the only way to make it work with Toolset as is.

Hopefully this is of some use to others looking for this issue.