'Select2 4 custom data adapter

I am trying to create a custom data adapter according to an example here: http://select2.github.io/announcements-4.0.html#query-to-data-adapter. How can I move the line that creates the select2 control outside the function with definition of DataAdapter (see the code below)?

<!DOCTYPE html>
<head>
    <title></title>
    <link href="select2.css" rel="stylesheet" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.js"></script>
    <script type="text/javascript" src="select2.full.js"></script>
    <script type="text/javascript">
        $.fn.select2.amd.require(
            ['select2/data/array', 'select2/utils'],
            function (ArrayData, Utils) {
                function CustomData ($element, options) {
                    CustomData.__super__.constructor.call(this, $element, options);
                }

                Utils.Extend(CustomData, ArrayData);

                CustomData.prototype.query = function (params, callback) {
                    var data = {results: []};
                    data.results.push({id: params.term, text: params.term});
                    data.results.push({id: 11, text: 'aa'});
                    data.results.push({id: 22, text: 'bb'});
                    callback(data);
                };

// Works if uncommented, but this line needs to be elsewhere (in $(document).ready()).
                //$("#my").select2({tags: true, dataAdapter: CustomData});
            });

        $(document).ready(function() {
// This line does not work here.            
            $("#my").select2({tags: true, dataAdapter: CustomData});
        });
    </script>
</head>
<body>
    <select id="my"></select>
</body>
</html>


Solution 1:[1]

you define it via AMD-Pattern:

$.fn.select2.amd.define('select2/data/customAdapter',[
        'select2/data/array',
        'select2/utils'
    ],
    function (ArrayAdapter, Utils) {

        function CustomDataAdapter ($element, options) {
            CustomDataAdapter.__super__.constructor.call(this, $element, options);
        }
        Utils.Extend(CustomDataAdapter, ArrayAdapter);

        CustomDataAdapter.prototype.current = function (callback) {

            callback(...);

        };

        return CustomDataAdapter;
    }
);

var customAdapter=$.fn.select2.amd.require('select2/data/customAdapter');

$("#my").select2({
    tags: true, 
    dataAdapter: customAdapter
});

Solution 2:[2]

For anyone trying to extend select2, here is an example :

// Require the adapter you want to override
$.fn.select2.amd.require(["select2/data/select"], function (Select) {
    let CustomDataAdapter = Select;

    // Simple example, just override the function
    CustomDataAdapter.prototype.current = function (callback) {
        // Your own code
    };

    // Example modifying data then calling the original function (which we need to keep)
    let originalSelect = CustomDataAdapter.prototype.select;
    CustomDataAdapter.prototype.select = function (data) {
        // Your own code
        // Call the original function while keeping 'this' context
        originalSelect.bind(this)(data);
    };

    // Finally, use the custom data adapter
    $('#my-select').select2({
        dataAdapter: CustomDataAdapter
    });

});

Solution 3:[3]

Example of select2 to handle big array. I am fetching data from server using ajax. Handling searching and pagination locally with more than 20000 data json.

<select id="widget_project"></select>


<script>
    $(function () {
        allProjects;// having all project json data
        
        pageSize = 50
        jQuery.fn.select2.amd.require(["select2/data/array", "select2/utils"],

        function (ArrayData, Utils) {
            function CustomData($element, options) {
                CustomData.__super__.constructor.call(this, $element, options);
            }
            Utils.Extend(CustomData, ArrayData);

            CustomData.prototype.query = function (params, callback) {

                var results = [];
                if(p_term !== "" &&  typeof params.term === "undefined"){
                    params.term = p_term;
                    console.log(params.term); 
                }
                if (params.term && params.term !== '') {
                    p_term = params.term;
                  results = findItem(params.term);
                } else {
                  results = allProjects;
                }

                if (!("page" in params)) {
                    params.page = 1;
                }
                var data = {};
                data.results = results.slice((params.page - 1) * pageSize, params.page * pageSize);
                data.pagination = {};
                data.pagination.more = params.page * pageSize < results.length;
                callback(data);
            };

            $(document).ready(function () {
                $("#widget_project").select2({
                    minimumInputLength: 3,
                    placeholder:"Select a project",
                    ajax: {},
                    dataAdapter: CustomData
                });
            });
        })
    });

</script>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ojathelonius
Solution 3 Suraj Rao