Mark Kaplun
Mark Kaplun

Reputation: 285

How can select2 3.5 and 4.0 conflicts be resolved

While not that specific issue, the issue described here - https://wordpress.org/support/topic/select2-conflicting-with-acf-v5 is basically my problem as well.

A wordpress site has two wordpress plugins, one uses select2 version 3.5 to handle all select elements, the other (included in a plugin I wrote) uses 4.0 to handle some specific ones. This result in an error of

Error: select2.min.js?ver=3.4.5:21 Uncaught Error: Option 'multiple' is not allowed for Select2 when attached to a element.

Is there any possible solution to this kind of problem? Should I just try to detect that 3.5 is loaded and try to avoid conflicting settings? maybe try to have "my" select2 to load first and hope that since I am more specific, there will not be conflicts with the code that uses 3.5? (my knowledge of jQuery internals is lacking, what does happen when different plugins try to use the same name?)

Upvotes: 2

Views: 2489

Answers (2)

Marc Wiest
Marc Wiest

Reputation: 359

For WordPress plugin authors using select2 my answer here: Jquery Select2 plugin version check could provide some guidance on version checking.

Upvotes: 0

Daniel Iser
Daniel Iser

Reputation: 441

I am facing the exact same issue with my plugin Popup Maker. I found this select2 multiple versions on same page/site that may be useful, the only issue I forsee there is that we can't always control the order plugins load their JS using wp_enqueue_script.

Ok so what I did was made my script require select2 (DUH), then just inside my scripts enclosure I did something like this.

$.fn.pumSelect2 = $.fn.select2;

Then later instead of calling .select2() I use .pumSelect2().

This works great for my situation which is that I use v4, others use v3.5, some even bootstrap it into their own admin.js file so it loads even though select2 is already loaded.

So all in all its a hack but since we are doing it the right way by loading using wp_enqueue_script.

I also dequeue select2 if its enqueued.

// Deregister older versions, loaded by Types, Advanced Custom Fields etc.
if ( wp_script_is( 'select2', 'registered' ) ) {
    wp_deregister_script( 'select2' );
}
wp_register_script( 'select2', $js_dir . 'select2.full' . $suffix, array( 'jquery' ), '4.0.1' );

`

Final Method For Now

After further testing and since so many other plugins use old versions with customizations that will likely break this is what I came up with.

In my select2.full.js file

For the opening section that loads jQuery and calls factory

(function (factory) {
    var existingVersion = jQuery.fn.select2 || null;

    if (existingVersion) {
        delete jQuery.fn.select2;
    }

    if (typeof define === 'function' && define.amd !== undefined && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS
        factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }

    jQuery.fn.pumselect2 = jQuery.fn.select2;

    if (existingVersion) {
        delete jQuery.fn.select2;
        jQuery.fn.select2 = existingVersion;
    }
}(function (jQuery) {

Basically I bootstrap it to a new name in this case pumselect2, and if there was previously a loaded version I restore it, otherwise I wipe the slate so that if another is loaded no conflict arises.

Also I modified my wp_enqueue_script handle to be pumselect2 so that it gets loaded even if someone else loads select2.

Hope that helps.

Upvotes: 4

Related Questions