81

I have downloaded select2 and "installed it" by putting it into my folder.
I then loaded it on my site and when I check the console I can see the file select2.js (where I see all of the scripts being loaded).

I went to their documentation, copied it and added $("#e9").select2();

However, when I load the page I get the following error:

TypeError: $(...).select2 is not a function

$("#e9").select2();

Has anyone else experienced anything like this?

For additional information, here is my script:

    jQuery(document).ready(function(){
    var max_amount = parseFloat($('#max_amount').val());
    $( "#item_amount" ).keyup(function() {
           if($(this).val() > max_amount){
            $(this).val( max_amount);
        }
        if( /\D/.test($(this).val()) ){
            alert('Må kun indeholde tal!');
            $(this).val('');
        }
        if($(this).val()== '0'){
            alert('Må ikke være 0!');
            $(this).val('');
        }
    });
    $("#e1").select2();

});
function addToBasket(){
    var amount = $('#item_amount').val();
    if(amount == ""){
        amount = 1;
    }

    if(amount > 0){
    $.ajax({
        type: 'POST',
        url: myBaseUrl + 'Products/addItemToBasket',
        dataType: 'json',
        data: {
            id: window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1),
            amount: amount
        },
        success: function (data) {
            var urlToBasket = myBaseUrl+'Products/basket';
            var newAmount = parseInt(amount)
            var price = data[0]['Product']['pris'];
            var id = data[0]['Product']['id'];
            var dat = data;
            var tmp_basket_html = $('#basket_amount').html();
           if($('#basket_amount').html() !== " Tom"){
              $('#shopping_table_body').append(
                  "<tr id='"+id+"'>" +
                      "<td class='image'>" +
                      ""+
                      "</td>" +
                      "<td class='name'>" +
                      " "+data[0]['Product']['name'] +
                      "</td>"+
                      "<td class='quantity'>" +
                      "x "+amount +""+
                      "</td>"+
                      "<td class='total'>" +
                      ""+price*amount+
                      "</td>" +
                      ""+
                      "<td class='remove'>" +
                      "<input class='icon-remove' type='button' onclick='removeItemFromBasket("+id+")'>"+
                      "</td>"+
                      "</tr>"
              );
           }else{
               $("#shopping_menu").append(
                   "<ul class='dropdown-menu topcartopen'>"+
                       "<li id='basket_list'>"+
                      "<table id='shopping_table'>"+
                        "<tbody id='shopping_table_body'>"+
                       "<tr id='"+id+"'>" +
                       "<td class='image'>" +
                       ""+
                       "</td>" +
                       "<td class='name'>" +
                       " "+data[0]['Product']['name'] +
                       "</td>"+
                       "<td class='quantity'>" +
                       "x "+amount +""+
                       "</td>"+
                       "<td class='total'>" +
                       ""+price*amount+
                       "</td>" +
                       ""+
                       "<td class='remove'>" +
                       "<input class='icon-remove' type='button' onclick='removeItemFromBasket("+id+")'>"+
                       "</td>"+
                       "</tr>"+
                       "</table>"+
                       "</li>"+
                       "<div class='well pull-right'>"+
                       "<input type='button' onclick='goToBasket()' class='btn btn-success' value='Tjek ud'>"+
                       "</div>"+
                       "</ul>"

               )
           }
            updateTotal(amount,price);
            updateBasketAmount();
        }
    });
    }
    Notifier.success('Vare tilføjet', 'Tilføjet'); // text and title are both optional.
}
function updateTotal(amount, price){
    var price = parseFloat(price);
    var oldValue = parseFloat($('#basket_total_cost').html());
    var newPrice = amount*price+oldValue;
    $('#basket_total_cost').html(newPrice);
}
function updateBasketAmount(){
   var tmp =  $('#basket_amount').html();
    if(!isNaN(tmp)){
   var oldAmount = parseInt(tmp.substr(0,2));
    var i = oldAmount + 1;;
    $('#basket_amount').html(
        ""+i+" vare(r)"
    );
    }else{
        $('#basket_amount').html(
            "1"+" vare(r)"
        );
    }
}
function goToBasket(){
    window.location.href = myBaseUrl+'Products/basket';
}
moken
  • 3,227
  • 8
  • 13
  • 23
Marc Rasmussen
  • 19,771
  • 79
  • 203
  • 364
  • 8
    Either you have not loaded jQuery, or some other script has taken control of the global `$`. No relation to select2. – Jon Nov 17 '13 at 18:31
  • 1
    jquery is loaded and is being used other places in my code everything works as it should.. – Marc Rasmussen Nov 17 '13 at 18:32
  • 2
    Are you sure you have fully loaded the scripts prior to using them? Try putting `$("#e9").select2();` in the console. If it works in the console and not when you run it on your page then you are probably running into an error with the asynchronous functionality of javascript. – DutGRIFF Nov 17 '13 at 18:33
  • 1
    @DutGRIFF this is my console: $('#e1').select2() TypeError: $(...).select2 is not a function $('#e1').select2() – Marc Rasmussen Nov 17 '13 at 18:35
  • @Jon explain taken control of the global? – Marc Rasmussen Nov 17 '13 at 18:38
  • And what does `$().select2` output when you type it in console just as I have it? If it is a function and is included in the code like you say it surely is then this should output `function(){/*some stuff here*/}` which will mean it is a function. – DutGRIFF Nov 17 '13 at 18:38
  • 1
    also possible you have sevral versions of jQuery being loaded....one version loading after your plugin will over write the plugin bound to first version ( over writes the whole jQuery object). only load jQuery once, before all plugins – charlietfl Nov 17 '13 at 18:45
  • @MarcRasmussen Before posting my answer I need to know the output of my previous comment in console? – DutGRIFF Nov 17 '13 at 18:49
  • @Jon but error would get thrown at first instance of `$().method` in conflict case and in case of library not loaded `jQuery is undefined` would be thrown where it is used – charlietfl Nov 17 '13 at 18:52
  • @DutGRIFF it outputs the same TypeError: $(...).select2 is not a function im using firefox btw (firebug) – Marc Rasmussen Nov 17 '13 at 18:56
  • @charlietfl: Not necessarily, if conflicted it's possible that there are no problematic calls prior to the select2 one. And if not loaded then `$` is de facto equivalent to `document.getElementById`. Load an empty page and try it in your browser. – Jon Nov 17 '13 at 19:04
  • @MarcRasmussen check valid path to plugin file and that jQuery onnly loaded once in page – charlietfl Nov 17 '13 at 19:05
  • @MarcRasmussen Then you didn't put `$().select2`. You must have put `$().select2()`? If you put `$().select2` it will tell you what is defined for that. Are you typing directly into the console? You shouldn't be putting this in your script but directly in the console instead. – DutGRIFF Nov 17 '13 at 19:05
  • @DutGRIFF $().select2 undefined – Marc Rasmussen Nov 17 '13 at 19:11
  • @Jon but can't get to `$` inside `jQuery(document).ready` for not loaded case without `jQuery` not being defined. Can rule that one out for sure – charlietfl Nov 17 '13 at 19:13
  • post link to live page that replicates problem... `$().select` is a worthless test without a selector...far better is test for existence of `$.fn.select2` or `jQuery.fn.select2`...can try `jQuery.("#e9")select2()` in console just in case `$` isn't `jQuery` but sure seems like it is. `console.log( typeof jQuery.fn.select2)`..if that's undefined you have path issue or overwrite of jQuery – charlietfl Nov 17 '13 at 19:20
  • @charlietfl It isn't 'worthless' if it outputs what is there. You don't need a selector to see what it is defined as in console. What is the difference between `$().select` and `$.fn.select2` or `jQuery.fn.select2`? – DutGRIFF Nov 17 '13 at 19:28
  • I seem to have the same problem as you, did you find a solution ? – Johanna Dec 06 '13 at 16:48

15 Answers15

110

I was having this problem when I started using select2 with XCrud. I solved it by disabling XCrud from loading JQuery, it was it a second time, and loading it below the body tag. So make sure JQuery isn't getting loaded twice on your page.

Finbar Dooley
  • 1,116
  • 1
  • 8
  • 3
  • 10
    Yeap, double loading jQuery for me! Thanks – Heroselohim May 09 '15 at 20:40
  • 1
    Spot on, saved few of hours! In my Asp.Net MVC project I had a js bundle which had Jquery in it, where it gets loaded for the second time in the partial view. Layout page already had the jquery. – Dhanuka777 Feb 02 '16 at 05:35
65

Had the same issue. Sorted it by defer loading select2

<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js" defer></script>
Aivis Zvezdovs
  • 751
  • 5
  • 3
58

This error raises if your js files where you have bounded the select2 with select box is loading before select2 js files. Please make sure files should be in this order like..

  • Jquery
  • select2 js
  • your js
Ashutosh Singh
  • 806
  • 1
  • 8
  • 20
  • after reordering the way the scripts where loaded it started working for me. But Strangely no such error was noticed when I ran locally. Only upon deploying it showed up. so the issue is due to asynchronous loading and latency issue which exists only upon deploying. – Ananda Apr 29 '16 at 05:08
  • Potential Duplicate reference of jquery – leeroya Aug 16 '17 at 21:22
  • @Ashutosh Singh thanks this is my main problem you saved my time! – Khalid May 29 '21 at 22:32
  • That solved my problem too. – lStoilov Mar 17 '22 at 19:28
10

I was also facing same issue & notice that this error occurred because the selector on which I am using select2 did not exist or was not loaded.

So make sure that $("#selector") exists by doing

if ($("#selector").length > 0)
   $("#selector").select2();
Shilpa
  • 217
  • 4
  • 14
Irfan Ashraf
  • 2,430
  • 21
  • 20
  • 2
    the error message in that case is not the same. the OP's error message says "$(...).select2 is not a function" but your should say "can't find select2 of a null object" something like this – serge Aug 09 '19 at 08:46
10

Add $("#id").select2() out of document.ready() function.

sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
Arslan Ishfaq
  • 101
  • 1
  • 2
3

you might be referring two jquery scripts which is giving the above error.

3

I used the jQuery slim version and got this error. By using the normal jQuery version the issue got resolved.

Orhan
  • 420
  • 1
  • 6
  • 12
2

The issue is quite old, but I'll put some small note as I spent couple of hours today investigating pretty same issue. After I loaded a part of code dynamically select2 couldn't work out on a new selectboxes with an error "$(...).select2 is not a function".

I found that in non-packed select2.js there is a line preventing it to reprocess the main function (in my 3.5.4 version it is in line 45):

if (window.Select2 !== undefined) {
    return;
}

So I just commented it out there and started to use select2.js (instead of minified version).

//if (window.Select2 !== undefined) {
//    return;
//}

And it started to work just fine, of course it now can do the processing several times loosing the performance, but I need it anyhow.

Hope this helps, Vladimir

Vladimir T
  • 340
  • 3
  • 8
0

Put config.assets.debug = false in config/environments/development.rb.

Rio Dermawan
  • 133
  • 1
  • 4
  • 1
    I'm developing a Rails3 app, using the select2-rails gem, and your advice has solved the problem. However I have to give up the assets' debug. Why? Is there another solution? – Hobbes Feb 11 '15 at 09:36
  • who says it was a ruby project? – serge Aug 09 '19 at 08:48
0

For me, select2.min.js file worked instead of select2.full.min.js. I have manually define files which I have copied from dist folder that I got from github page. Also make sure that you have one jQuery(document).ready(...) definition and jquery file imported before select2 file.

Deniz Kaplan
  • 1,549
  • 1
  • 13
  • 18
0

For newbies like me, who end up on this question: This error also happens if you attempt to call .select2() on an element retrieved using pure javascript and not using jQuery.

This fails with the "select2 is not a function" error:

document.getElementById('e9').select2();

This works:

$("#e9").select2();
jgerman
  • 1,143
  • 8
  • 14
0

In my case, I was getting this error in my rails app when both webpacker and sprockets were trying to import jQuery. I didn't notice it until my code editor automatically tried to import jQuery into a webpacker module.

Austin
  • 387
  • 6
  • 11
0

I was having the same problem today and none of the other answers worked. I don't understand how or why this worked, but it did and (knock on wood) still does.

But first, a bit about my specific situation:

I was using select2 in one .js file and trying to get it into another one, but got this error. jQuery was working fine in the other .js document, and the second one I tried to use was called LATER in the html than the first .js document I was writing, and both later than the jquery and select2 tags.

OK, now for the solution that doesn't make sense, but does work:

I put the definition of the jQuery element into the earlier .js file and the .select2 on that variable in the later .js file. Weird, right? So, like this:

<head>
*blah blah blah html headers*
<script src="/static/js/jquery-3.6.0.js"></script>  
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
</head>
<body>
*blah blah blah page stuff*
<script src="/static/js/first.js"></script>
*blah blah some more stuff*
<script src="/static/js/second.js"></script>

first.js

const selector = $('#select-this')

second.js

selector.select2({
*&c, &c, &c.*
kingtor
  • 1
  • 2
0

ControlId.select2({...}); was not working but following worked:

$(ControlId).select2({...});

AbhishekS
  • 71
  • 8
0

sometimes the page unable to call the file you can reuse by the cdn in the same page in can be solved

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 07 '23 at 11:11