Ajax के साथ Select2 4.0.0 प्रारंभिक मूल्य


97

मेरे पास एक अलेक्स सरणी से पॉपुलेटेड 2 v4.0.0 है। यदि मैं select2 की वैल सेट करता हूं तो मैं जावास्क्रिप्ट डिबगिंग के माध्यम से देख सकता हूं कि उसने सही आइटम (मेरे मामले में # 3) का चयन किया है, हालांकि यह चयन बॉक्स में नहीं दिखाया गया है, यह अभी भी प्लेसहोल्डर दिखा रहा है। यहां छवि विवरण दर्ज करें

जबकि मुझे कुछ इस तरह से देखना चाहिए: यहां छवि विवरण दर्ज करें

मेरे फार्म फ़ील्ड में:

<input name="creditor_id" type="hidden" value="3">
<div class="form-group minimal form-gap-after">
    <span class="col-xs-3 control-label minimal">
        <label for="Creditor:">Creditor:</label>
    </span>
    <div class="col-xs-9">
        <div class="input-group col-xs-8 pull-left select2-bootstrap-prepend">
            <select class="creditor_select2 input-xlarge form-control minimal select2 col-xs-8">
                <option></option>
            </select>
        </div>
    </div>
</div>

मेरी जावास्क्रिप्ट:

var initial_creditor_id = "3";
$(".creditor_select2").select2({
    ajax: {
       url: "/admin/api/transactions/creditorlist",
       dataType: 'json',
       delay: 250,
       data: function (params) {
           return {
                q: params.term,
                c_id: initial_creditor_id,
                page: params.page
           };
       },
       processResults: function (data, page) {
            return {
                results: data
            };
       },
       cache: true
   },
   placeholder: "Search for a Creditor",
   width: "element",
   theme: "bootstrap",
   allowClear: true
   }).on("select2:select", function (e) {
      var selected = e.params.data;
      if (typeof selected !== "undefined") {
           $("[name='creditor_id']").val(selected.creditor_id);
           $("#allocationsDiv").hide();
           $("[name='amount_cash']").val("");
           $("[name='amount_cheque']").val("");
           $("[name='amount_direct']").val("");
           $("[name='amount_creditcard']").val("");
        }
    }).on("select2:unselecting", function (e) {
        $("form").each(function () {
            this.reset()
        });
        ("#allocationsDiv").hide();
        $("[name='creditor_id']").val("");
    }).val(initial_creditor_id);

मैं प्लेसहोल्डर के बजाय चयनित बॉक्स को चयनित आइटम कैसे बना सकता हूं? क्या मुझे यह AJAX JSON प्रतिक्रिया के भाग के रूप में भेजना चाहिए?

अतीत में, Select2 को initSelection नामक एक विकल्प की आवश्यकता थी जिसे परिभाषित किया गया था जब भी एक कस्टम डेटा स्रोत का उपयोग किया जा रहा था, घटक के लिए प्रारंभिक चयन के लिए निर्धारित किया गया था। यह मेरे लिए v3.5 में ठीक काम किया।


यह कैसे संभव है? जब मैं इसके selectसाथ बाँधने की कोशिश कर रहा हूँ ajax, त्रुटि बढ़ जाती है, तो उस विकल्प को इसके चयन की अनुमति नहीं है ...
Daggeto

जवाबों:


109

आप ज्यादातर चीजें सही तरीके से कर रहे हैं, यह केवल एक ही समस्या है जो आप मार रहे हैं, यह है कि आप changeनए मूल्य सेट करने के बाद विधि को ट्रिगर नहीं कर रहे हैं। एक changeघटना के बिना , Select2 यह नहीं जान सकता कि अंतर्निहित मूल्य बदल गया है, इसलिए यह केवल प्लेसहोल्डर को प्रदर्शित करेगा। अपना अंतिम भाग बदलना

.val(initial_creditor_id).trigger('change');

अपना मुद्दा ठीक करना चाहिए, और आपको तुरंत UI अपडेट देखना चाहिए।


यह मान रहा है कि आपके पास <option>पहले से ही एक valueहै initial_creditor_id। यदि आप Select2, और ब्राउज़र नहीं करते हैं, तो वास्तव में मूल्य को बदलने में सक्षम नहीं होगा, क्योंकि स्विच करने के लिए कोई विकल्प नहीं है, और Select2 नए मूल्य का पता नहीं लगाएगा। मैंने देखा कि आपके <select>एकमात्र विकल्प में एक है, प्लेसहोल्डर के लिए एक, जिसका अर्थ है कि आपको <option>मैन्युअल रूप से नया बनाने की आवश्यकता होगी ।

var $option = $("<option selected></option>").val(initial_creditor_id).text("Whatever Select2 should display");

और फिर इसे उस पर जोड़ें <select>कि आपने Select2 को इनिशियलाइज़ किया है। आपको पाठ को एक बाहरी स्रोत से प्राप्त करने की आवश्यकता हो सकती है, जो कि initSelectionखेल में आने के लिए उपयोग किया जाता है, जो अभी भी Select2 4.0.0 के साथ संभव है। एक मानक चयन की तरह, इसका मतलब है कि आपको मान को पुनः प्राप्त करने के लिए AJAX अनुरोध करना होगा और फिर <option>समायोजित करने के लिए मक्खी पर पाठ सेट करना होगा ।

var $select = $('.creditor_select2');

$select.select2(/* ... */); // initialize Select2 and any events

var $option = $('<option selected>Loading...</option>').val(initial_creditor_id);

$select.append($option).trigger('change'); // append the option and update Select2

$.ajax({ // make the request for the selected data object
  type: 'GET',
  url: '/api/for/single/creditor/' + initial_creditor_id,
  dataType: 'json'
}).then(function (data) {
  // Here we should have the data object
  $option.text(data.text).val(data.id); // update the text that is displayed (and maybe even the value)
  $option.removeData(); // remove any caching data that might be associated
  $select.trigger('change'); // notify JavaScript components of possible changes
});

हालांकि यह बहुत सारे कोड की तरह लग सकता है, यह ठीक है कि आप यह सुनिश्चित करने के लिए कि गैर-Select2 चुनिंदा बक्से के लिए यह कैसे करेंगे ताकि सभी बदलाव किए जा सकें।


14
किसी भी विचार बहु ​​चयन बक्से के लिए कई विकल्पों का चयन कैसे करें?
user396404

6
@ user396404 वही अवधारणाएं लागू होनी चाहिए, बस एक आईडी के val()बजाय आईडी की सूची पास करें । या बस कई जोड़ते हैं <option selected>और इसे स्वचालित रूप से नियंत्रित किया जाना चाहिए।
केविन ब्राउन

5
मुझे लगता है कि यह उत्तर एक वर्ष से अधिक पुराना है, लेकिन FAQ प्रश्न के लिए Select2 के लिए प्रलेखन: "मैं AJAX का उपयोग करते समय प्रारंभिक रूप से चयनित विकल्पों को कैसे सेट कर सकता हूं?" अभी भी इस ओर इशारा करता है। मैंने v4.0.3 jsfiddle.net/57co6c95 के
क्लिंट

2
वहाँ एक समस्या है। क्या होगा यदि मैं केवल आईडी और पाठ से अधिक अनुरोध करना चाहता हूं? मैंने कोशिश की है, लेकिन डेटा विकल्प केवल templateResult के लिए डेटा प्राप्त कर रहा है और टेम्पलेट के लिए इसे अनदेखा कर रहा है। कोई उपाय?
क्लियरबोथ

2
इसके अलावा, मैंने इस समाधान की कोशिश की, लेकिन दुर्भाग्य $select.trigger('change');से विकल्प को कॉल करने के बाद अभी भी लोड हो रहा है ... पाठ, भले ही data.textमेरे द्वारा वांछित पाठ था। शायद यह अब 4.0.6 में समर्थित नहीं है ।
Alisson

28

मैंने जो किया है वह अधिक साफ है और दो सरणियाँ करने की आवश्यकता है:

  • एक में आईडी के साथ ऑब्जेक्ट की एक सूची और एक पाठ होता है (मेरे मामले में इसकी आईडी और नाम, आपके टेम्पलेट पर निर्भर करता है) (इसके बारे में जो आपको ajax क्वेरी से मिलता है)
  • दूसरा आईडी का एक सरणी है (चयन मूल्य)

मैं पहले सरणी को डेटा के रूप में और दूसरे को वैल के रूप में उपयोग करके select2 को इनिशियलाइज़ करता हूँ।

एक उदाहरण आईडी के एक पैरामीटर के रूप में कार्य करता है: नाम।

function initMyList(values) {
    var selected = [];
    var initials = [];

    for (var s in values) {
        initials.push({id: s, name: values[s].name});
        selected.push(s);
    }

    $('#myselect2').select2({
        data: initials,
        ajax: {
            url: "/path/to/value/",
            dataType: 'json',
            delay: 250,
            data: function (params) {
                return {
                    term: params.term,
                    page: params.page || 1,
                };
            },
            processResults: function (data, params) {
                params.page = params.page || 1;

                return {
                    results: data.items,
                    pagination: {
                        more: (params.page * 30) < data.total_count
                    }
                };
            },
            cache: true
        },
        minimumInputLength: 1,
        tokenSeparators: [",", " "],
        placeholder: "Select none, one or many values",
        templateResult: function (item) { return item.name; },
        templateSelection: function (item) { return item.name; },
        matcher: function(term, text) { return text.name.toUpperCase().indexOf(term.toUpperCase()) != -1; },
    });

    $('#myselect2').val(selected).trigger('change');
}

आप ajax कॉल का उपयोग करके प्रारंभिक मूल्य को फ़ीड कर सकते हैं, और चयन 2 आरंभीकरण करने के लिए jquery वादों का उपयोग कर सकते हैं।


3
यह निश्चित रूप से इसे करने का बेहतर तरीका है। जोड़कर DOM को मैनिप्युलेट करना <option>ऐसा करने का सबसे तार्किक तरीका नहीं लगता है। यह मैं इसे 4.0 में कैसे करता हूँ
जियाविज़ैंग

2
@ firebird631, आपका समाधान शानदार है, यह काम करता है और बहुत बड़ा धन्यवाद!
userlond

यह सबसे साफ समाधान है जिसे मैंने अब तक देखा है
जिमी इलेनॉला

मैं ध्यान दूंगा कि आंतरिक रूप से dataविकल्प केवल <option>टैग बना रहा है और उन्हें चयन में जोड़ रहा है। यह उत्तर कवर नहीं करता है कि आप ऐसे मामलों को कैसे संभालते हैं, जहां आपको अधिक जानकारी प्राप्त करने के लिए एपीआई से बाहर जाने की आवश्यकता होती है, लेकिन मुझे लगता है कि यह कम विशिष्ट मामला है।
केविन ब्राउन

नमस्ते अजाक्स के साथ मैं यह करने में सक्षम नहीं हूं। जब मैं दो ऑब्जेक्ट के साथ एक सूची भेजता हूं तो उन दो ऑब्जेक्ट को सम्मिलित करने में कोई समस्या नहीं होती है लेकिन केवल एक ही सम्मिलित होती है। और पहले से ही स्वचालित रूप से चयनित। मैं कभी भी दो विकल्प नहीं देख पाया, यहां तक ​​कि मैंने दो आइटम भेजे।
साहिन यान्लिक

7

यह मेरे लिए काम कर रहा है ...

JQuery का उपयोग न करें, केवल HTML: बनाएं विकल्प मान के रूप में आप प्रदर्शित करेगा चयनित । यदि ID यह select2 डेटा में है तो यह अपने आप चयनित हो जाएगा।

<select id="select2" name="mySelect2">
  <option value="mySelectedValue">
        Hello, I'm here!
  </option>
</select>

Select2.org - डिफ़ॉल्ट पूर्व चयनित मान


6

trigger('change')मुझे पागल करने के लिए मजबूर करने का मुद्दा , क्योंकि मेरे पास changeट्रिगर में कस्टम कोड था , जिसे केवल तभी ट्रिगर करना चाहिए जब उपयोगकर्ता ड्रॉपडाउन में विकल्प बदलता है। प्रारंभ में इनिट मान सेट करते समय IMO, परिवर्तन को ट्रिगर नहीं किया जाना चाहिए।

मैंने गहरी खाई और निम्नलिखित पाया: https://github.com/select2/select2/issues/3620

उदाहरण:

$dropDown.val(1).trigger('change.select2');


4

एक परिदृश्य जिसे मैंने लोगों को वास्तव में जवाब देते नहीं देखा है, वह यह है कि जब विकल्प AJAX के लिए विकल्प हो, तो एक चयन कैसे किया जाए, और आप कई का चयन कर सकते हैं। चूंकि यह AJAX preselection के लिए पृष्ठ पर जाना है, मैं यहां अपना समाधान जोड़ूंगा।

$('#mySelect').select2({
    ajax: {
        url: endpoint,
        dataType: 'json',
        data: [
            { // Each of these gets processed by fnRenderResults.
                id: usersId,
                text: usersFullName,
                full_name: usersFullName,
                email: usersEmail,
                image_url: usersImageUrl,
                selected: true // Causes the selection to actually get selected.
            }
        ],
        processResults: function(data) {

            return {
                results: data.users,
                pagination: {
                    more: data.next !== null
                }
            };

        }
    },
    templateResult: fnRenderResults,
    templateSelection: fnRenderSelection, // Renders the result with my own style
    selectOnClose: true
}); 

3

यदि आप एक टेम्पलेट का उपयोग कर रहे हैंइलेक्ट्रेशन और अजाक्स, इनमें से कुछ अन्य उत्तर काम नहीं कर सकते हैं। ऐसा लगता है कि एक नया optionतत्व बनाना और सेट करना valueऔर textटेम्पलेट पद्धति को संतुष्ट नहीं करेगा जब आपके डेटा ऑब्जेक्ट आईडी और पाठ के अलावा अन्य मूल्यों का उपयोग करते हैं।

यहाँ मेरे लिए क्या काम किया गया है:

$("#selectElem").select2({
  ajax: { ... },
  data: [YOUR_DEFAULT_OBJECT],
  templateSelection: yourCustomTemplate
} 

यहाँ jsField देखें : https://jsfiddle.net/shanabus/f8h1xnv4

मेरे मामले में, मुझे processResultsअपने डेटा में आवश्यक idऔर textफ़ील्ड शामिल नहीं करने थे । यदि आपको ऐसा करने की आवश्यकता है, तो आपको उसी फ़ंक्शन के माध्यम से अपना प्रारंभिक चयन चलाने की आवश्यकता होगी। इस तरह:

$(".js-select2").select2({
  ajax: {
    url: SOME_URL,
    processResults: processData
  },
  data: processData([YOUR_INIT_OBJECT]).results,
  minimumInputLength: 1,
  templateSelection: myCustomTemplate
});

function processData(data) {
  var mapdata = $.map(data, function (obj) {      
    obj.id = obj.Id;
    obj.text = '[' + obj.Code + '] ' + obj.Description;
    return obj;
  });
  return { results: mapdata }; 
}

function myCustomTemplate(item) {
     return '<strong>' + item.Code + '</strong> - ' + item.Description;
}

आखिरकार!!!!! वाह, इससे ज्यादा निराशा नहीं हो सकती थी !! मैं "पाठ" के बजाय "नाम" का उपयोग कर रहा था और यह मुझे मार रहा था। मैंने डिफ़ॉल्ट "टेक्स्ट" कुंजी पर स्विच किया और यह अब पूरी तरह से काम कर रहा है। धन्यवाद!
HTMLGuy

1

एक समाधान के लिए खोज करने के कुछ घंटे बिताने के बाद, मैंने अपना खुद का निर्माण करने का फैसला किया। वह यह है:

 function CustomInitSelect2(element, options) {
            if (options.url) {
                $.ajax({
                    type: 'GET',
                    url: options.url,
                    dataType: 'json'
                }).then(function (data) {
                    element.select2({
                        data: data
                    });
                    if (options.initialValue) {
                        element.val(options.initialValue).trigger('change');
                    }
                });
            }
        }

और आप इस फ़ंक्शन का उपयोग करके चयन को इनिशियलाइज़ कर सकते हैं:

$('.select2').each(function (index, element) {
            var item = $(element);
            if (item.data('url')) {
                CustomInitSelect2(item, {
                    url: item.data('url'),
                    initialValue: item.data('value')
                });
            }
            else {
                item.select2();
            }
        });

और हां, यहाँ html है:

<select class="form-control select2" id="test1" data-url="mysite/load" data-value="123"></select>

एक सामान्य प्रारंभिक प्रक्रिया के लिए महान विचार।
कार्लोस मोरा

1

एक सरल और अर्थपूर्ण समाधान के लिए मैं HTML में प्रारंभिक मूल्य को परिभाषित करना पसंद करता हूं, उदाहरण:

<select name="myfield" data-placeholder="Select an option">
    <option value="initial-value" selected>Initial text</option>
</select>

इसलिए जब मैं कहता हूं $('select').select2({ ajax: {...}});कि प्रारंभिक मूल्य है initial-valueऔर इसका विकल्प पाठ है Initial text

मेरा वर्तमान Select2 संस्करण 4.0.3 है , लेकिन मुझे लगता है कि अन्य संस्करणों के साथ इसकी एक बड़ी संगतता है।


मुझे लगता है कि आप न केवल एक चुनिंदा मूल्य बचा रहे हैं, बल्कि आपके डेटाबेस के लिए एक पाठ भी है, इसलिए आप इसे इस तरह से पुनः प्राप्त कर सकते हैं ... शीश!
ITDesigns.eu 19:

@ ITDesigns.eu, मुझे नहीं लगता कि, डेटाबेस को भेजा गया मान है initial-valueऔर पाठ Initial textएक प्लेसहोल्डर के रूप में कार्य करता है, यह डेटाबेस को नहीं भेजा जाता है। यह मेरे आवेदन में काम कर रहा है।
मारीसो माज़ुकाटो

मुझे वास्तविक विकल्प में एक वास्तविक पाठ के बजाय एक प्लेसहोल्डर की आवश्यकता क्यों होगी ! "
ITDesigns.eu

@ ITDesigns.eu, Select2 इस जानकारी को पकड़ता है और खुद को माउंट करता है
Marcio Mazzucato

1

https://github.com/select2/select2/issues/4272 केवल इसने मेरी समस्या हल कर दी। यहां तक ​​कि आप विकल्प द्वारा डिफ़ॉल्ट मान सेट करते हैं, आपको ऑब्जेक्ट को प्रारूपित करना होगा, जिसमें पाठ विशेषता है और यही आप अपने विकल्प में दिखाना चाहते हैं। इसलिए, आपके प्रारूप फ़ंक्शन का उपयोग ||उस विशेषता को चुनने के लिए करना है जो खाली नहीं है।


0

मैं इस उत्तर को मुख्य रूप से जोड़ रहा हूँ क्योंकि मैं ऊपर टिप्पणी नहीं कर सकता हूँ! मैंने पाया कि यह @Nicki और उसकी jsfiddle, https://jsfiddle.net/57co6c95/ की टिप्पणी थी , आखिरकार मुझे यह काम मिल गया।

अन्य बातों के अलावा, इसने आवश्यक जोंस के प्रारूप का उदाहरण दिया। मुझे जो एकमात्र बदलाव करना था, वह यह था कि मेरे प्रारंभिक परिणाम उसी प्रारूप में वापस आ गए थे, जैसे कि अन्य अजाक्स कॉल के लिए मुझे उपयोग करना था

$option.text(data[0].text).val(data[0].id);

बजाय

$option.text(data.text).val(data.id);

0

चयन के लिए सरल प्रारंभिक मूल्य के साथ सरल अजाक्स कॉम्बो बनाएँ

<select name="mycombo" id="mycombo""></select>                   
<script>
document.addEventListener("DOMContentLoaded", function (event) {
    selectMaker.create('table', 'idname', '1', $("#mycombo"), 2, 'type');                                
});
</script>  

पुस्तकालय .js

var selectMaker = {
create: function (table, fieldname, initialSelected, input, minimumInputLength = 3, type ='',placeholder = 'Select a element') {
    if (input.data('select2')) {
        input.select2("destroy");
    }
    input.select2({
        placeholder: placeholder,
        width: '100%',
        minimumInputLength: minimumInputLength,
        containerCssClass: type,
        dropdownCssClass: type,
        ajax: {
            url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type,
            type: 'post',
            dataType: 'json',
            contentType: "application/json",
            delay: 250,
            data: function (params) {
                return {
                    term: params.term, // search term
                    page: params.page
                };
            },
            processResults: function (data) {
                return {
                    results: $.map(data.items, function (item) {
                        return {
                            text: item.name,
                            id: item.id
                        }
                    })
                };
            }
        }
    });
    if (initialSelected>0) {
        var $option = $('<option selected>Cargando...</option>').val(0);
        input.append($option).trigger('change'); // append the option and update Select2
        $.ajax({// make the request for the selected data object
            type: 'GET',
            url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type + '&initialSelected=' + initialSelected,
            dataType: 'json'
        }).then(function (data) {
            // Here we should have the data object
            $option.text(data.items[0].name).val(data.items[0].id); // update the text that is displayed (and maybe even the value)
            $option.removeData(); // remove any caching data that might be associated
            input.trigger('change'); // notify JavaScript components of possible changes
        });
    }
}
};

और php सर्वर साइड

<?php
if (isset($_GET['getQuery']) && isset($_GET['table']) && isset($_GET['fieldname'])) {
//parametros carga de petición
parse_str(file_get_contents("php://input"), $data);
$data = (object) $data;
if (isset($data->term)) {
    $term = pSQL($data->term);
}else{
    $term = '';
}
if (isset($_GET['initialSelected'])){
    $id =pSQL($_GET['initialSelected']);
}else{
    $id = '';
}
if ($_GET['table'] == 'mytable' && $_GET['fieldname'] == 'mycolname' && $_GET['type'] == 'mytype') {

    if (empty($id)){
        $where = "and name like '%" . $term . "%'";
    }else{
         $where = "and id= ".$id;
    }

    $rows = yourarrayfunctionfromsql("SELECT id, name 
                    FROM yourtable
                    WHERE 1 " . $where . "
                    ORDER BY name ");
}

$items = array("items" => $rows);
$var = json_encode($items);
echo $var;
?>

-4

हाय लगभग इसे छोड़ रहा था और 3.5.1 का चयन करने के लिए वापस चला गया। लेकिन आखिरकार मुझे जवाब मिल गया!

$('#test').select2({
    placeholder: "Select a Country",
    minimumResultsForSearch: 2,
    ajax: {
        url: '...',
        dataType: 'json',
        cache: false,
        data: function (params) {
                var queryParameters = {
                    q: params.term
                }
                return queryParameters;
        },
        processResults: function (data) {
            return {
                results: data.items
            };
        }
    }
});

var option1 = new Option("new",true, true);

$('#status').append(option1);

$('#status').trigger('change');

बस यह सुनिश्चित करें कि नया विकल्प Select2 विकल्पों में से एक है। मुझे यह एक जुबान से मिला है।


हाय - - #status ’क्या है? कंधे से कंधा मिलाकर '# बेस्ट' होना चाहिए?
user2808054
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.