Select2 4.0.0 начальное значение с помощью AJAX



у меня есть select2 v4.0.0 заполняется из массива Ajax. Если я установил val select2, я могу видеть через отладку javascript, что он выбрал правильный элемент (#3 в моем случае), однако это не показано в поле выбора, оно все еще показывает заполнитель.
enter image description here



в то время как я должен видеть что-то вроде этого:
enter image description here



в полях моей формы:



<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>


мой javascript:



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.

516   11  

11 ответов:

вы делаете большинство вещей правильно, похоже, что единственная проблема, которую вы бьете, заключается в том, что вы не запускаете change метод после установки нового значения. Без change событие, Select2 не может знать, что базовое значение изменилось, поэтому он будет отображать только заполнитель. Изменение последней части на

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

должно исправить вашу проблему, и вы должны увидеть обновление пользовательского интерфейса сразу.


это при условии, что у вас есть <option> уже есть value на initial_creditor_id. Если вы не выберете 2, а браузер, фактически не сможет изменить значение, так как нет возможности переключиться, и Select2 не обнаружит новое значение. Я заметил, что ваш <select> содержит только один параметр, один для заполнителя, что означает, что вам нужно будет создать новый <option> вручную.

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

а затем добавить его к <select> что вы инициализировали Select2 on. Вы можете получить текст из внешнего источника, где initSelection используется для вступления в игру, что по-прежнему возможно с Select2 4.0.0. Как и стандартный select, это означает, что вам придется сделать запрос 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 установите флажки, чтобы убедиться, что все изменения были сделаны.

то, что я сделал, более чистое и должно сделать два массива:

  • один содержит список объектов с идентификатором и текстом (в моем случае его идентификатор и имя, в зависимости от вашего templateResult) (его то, что вы получаете от запроса ajax)
  • второй-это только массив идентификаторов (стоимость выбора)

Я инициализирую select2, используя первый массив в качестве данных, а второй в качестве val.

пример функции с параметрами a dict of идентификационное имя.

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-вызовов и использовать jQuery обещает выполнить инициализацию select2.

вопрос о том, чтобы быть вынужденным trigger('change') сводили меня с ума, так как у меня был пользовательский код change триггер, который должен срабатывать только тогда, когда пользователь изменяет параметр в раскрывающемся списке. ИМО, изменение не должно запускаться при установке значения инициализации в начале.

я копнул глубоко и нашел следующее:https://github.com/select2/select2/issues/3620

пример:

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

один сценарий, который я не видел, чтобы люди действительно отвечали, - Это как иметь предварительный выбор, когда параметры AJAX sourced, и вы можете выбрать несколько. Поскольку это страница перехода для предварительного выбора AJAX, я добавлю свое решение здесь.

$('#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
}); 

если вы используете templateSelection и ajax, некоторые из этих других ответов могут не работать. Кажется, что создание нового option элемент и задание value и text не будет удовлетворять метод шаблона, когда ваши объекты данных используют другие значения, чем id и текст.

вот что сработало для меня:

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

Проверьте jsFiddle здесь: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;
}

это работает для меня ...

Не используйте jQuery, только HTML: создайте Параметр Значение будет отображаться как избранные. Если ID это select2 data он будет выбран автоматически.

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

Select2.org -предварительно выбранные значения по умолчанию

проведя несколько часов в поисках решения, я решил создать свой собственный. Он это:

 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>

Я добавляю этот ответ в основном потому, что я не могу прокомментировать выше! Я обнаружил, что это был комментарий @Nicki и ее jsfiddle,https://jsfiddle.net/57co6c95/, что в конечном итоге заставило это работать на меня.

среди прочего, он привел примеры формата для необходимого json. Единственное изменение, которое я должен был сделать, это то, что мои первоначальные результаты были возвращены в том же формате, что и другой вызов ajax, поэтому мне пришлось использовать

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

, а не

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

создать простой ajax комбо с de начальное значение seleted для select2 4.0.3

<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;
?>

для простого и семантического решения я предпочитаю определять начальное значение в 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, но я думаю, она имеет большую совместимость с другими версиями.

Привет почти бросил это и вернулся к выбору 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. Я получаю это от json.

Comments

    Ничего не найдено.