$(document).ready(function () { $.fn.TeamTouristSelect = function ( dataset, select2options ) { /* * In this function, * we override some of the default select2 options. * Using $.extend, we can merge together the user options with these options. */ $.extend(select2options, { initSelection: function (element, callback) { /* * On first launch, look up the text that is * the value attribute of the input and return * the object in the select2 array. * Then, set it as the current select2 option by running "callback" on it */ var selection = new Array(); selection = $.grep(dataset, function (e) { return e.text == element.val(); }); callback(selection[0]); }, query: function (options) { /* * Set up the number of results we want to load at one time */ var pageSize = 25; var startIndex = (options.page - 1) * pageSize; var filteredData = dataset; /* * The user must type in a valid term */ if (options.term && options.term.length > 0) { /* * Only find the results if this is a new search * options.context will already be set if we are only loading new pages, * not finding new data. */ if (!options.context) { var term = options.term.toLowerCase(); /* * Loop through the dataset and match the text or category * to the term. * If there is a match, add it to the selection array. */ var selection = new Array(); for (x = 0; x < dataset.length; x++) { obj = dataset[x]; if (obj.text.toLowerCase().indexOf(term) !== -1 || obj.category.toLowerCase().indexOf(term) !== -1) { selection.push(obj); } } options.context = selection; } filteredData = options.context; } /* * Now, filter out the number of results we want to find * based on the pages we are loading. */ shortenedData = filteredData.slice(startIndex, startIndex + pageSize); categories = new Array(); categorisedData = new Array(); /* * Sort the final data into its categories. */ for (j=0; j < shortenedData.length; j++) { /* * If the category doesn't exist in our categories array * then create it with an empty value for children */ if (categories.indexOf(shortenedData[j].category) === -1) { categories.push(shortenedData[j].category); categorisedData.push({ text: shortenedData[j].category, children: [] }); } /* * Assuming the category has been added to the categories array, * we can insert this row into the categories children array */ index = categories.indexOf(shortenedData[j].category); categorisedData[index].children.push(shortenedData[j]); } /* * To fix a bug: if the category we are loading is the same as the last category loaded from the last search, * then don't bother showing the same category twice. */ if (startIndex > 0 && categorisedData[0].text == filteredData[startIndex - 1].category) { categorisedData[0].text = ""; } /* * Perform the callback on the new data. */ options.callback({ context: filteredData, results: categorisedData, more: (startIndex + pageSize) < filteredData.length }); } }); /* * Run select2 with the new options. */ $(this).select2(select2options); } });