Загрузка значений в Selectize.js

Проблема

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

Использование selectize:

var $select = $('.authorsearch').selectize({
    valueField: 'AuthorId',
    labelField: 'AuthorName',
    searchField: ['AuthorName'],
    maxOptions: 10,
    create: function (input, callback) {
        $.ajax({
            url: '/Author/AjaxCreate',
            data: { 'AuthorName': input },
            type: 'POST',
            dataType: 'json',
            success: function (response) {
                return callback(response);
            }
        });
    },
    render: {
        option: function (item, escape) {
            return '<div>' + escape(item.AuthorName) + '</div>';
        }
    },
    load: function (query, callback) {
        if (!query.length) return callback();
        $.ajax({
            url: '/Author/SearchAuthorsByName/' + query,
            type: 'POST',
            dataType: 'json',
            data: {
                maxresults: 10
            },
            error: function () {
                callback();
            },
            success: function (res) {
                callback(res);
            }
        });
    }
});

Текстовое поле:

<input class="authorsearch" id="Authors" name="Authors" type="text" value="" />

Примеры:

Authors working

Затем, когда я выбираю один (в данном случае "яблоко" ), он появляется в значке, как и следовало ожидать, а базовое значение текстового поля представляет собой список значений этих элементов, разделенных запятыми.

Author with badge

Текущий выход

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

<input class="authorsearch" id="Authors" name="Authors" type="text" value="1,3,4" />

Numbers only

Желаемый вывод

Я пробовал всевозможные значения для поля значений входов, чтобы он загружал элементы, показывая их отображаемое имя, а не их значения. Ниже приведен пример одного объекта, возвращаемого как JSON, возможность загрузки массива JSON из них в качестве выбранных тегов будет идеальной.

[{"AuthorId":1,"AuthorName":"Test Author"},
 {"AuthorId":3,"AuthorName":"Apple"},
 {"AuthorId":4,"AuthorName":"Test Author 2"}]

enter image description here

Как я могу это сделать? Нужно ли мне форматировать значение текстового поля, или мне нужно загрузить мои существующие значения с помощью javascript?

Ответы

Ответ 1

В итоге я использовал onInitialize вызов onInitialize для загрузки значений JSON, хранящихся в поле data-*. Вы можете увидеть это в действии здесь, в этом jsfiddle.

<input class="authorsearch" id="Authors" name="Authors" type="text" value="" 
 data-selectize-value='[{"AuthorId":1,"AuthorName":"Test"},{"AuthorId":2,"AuthorName":"Test2"}]'/>

В основном он анализирует значение data-selectize-value а затем добавляет опцию (и) к выбору, а затем добавляет сами элементы.

onInitialize: function() {
    var existingOptions = JSON.parse(this.$input.attr('data-selectize-value'));
    var self = this;
    if(Object.prototype.toString.call( existingOptions ) === "[object Array]") {
        existingOptions.forEach( function (existingOption) {
            self.addOption(existingOption);
            self.addItem(existingOption[self.settings.valueField]);
        });
    }
    else if (typeof existingOptions === 'object') {
        self.addOption(existingOptions);
        self.addItem(existingOptions[self.settings.valueField]);
    }
}

Мое решение предполагает, что мой JSON-объект сформирован правильно, и что это либо отдельный объект, либо массив объектов, поэтому он может подходить или не подходить для других нужд.

Так что разбирает:

[{"AuthorId":1,"AuthorName":"Test"},
 {"AuthorId":2,"AuthorName":"Test2"}]

Для того, чтобы:

enter image description here

Основываясь, конечно, на моих настройках выбора в моем оригинальном посте выше.

Ответ 2

Благодаря вашему ответу и исходя из вашего подхода onInitialize(), у меня получилось аналогичное решение. В моем случае мне просто нужно было перевести одно значение, таким образом, я смог сохранить идентификатор и метку в качестве атрибутов данных в поле ввода.

<input type="text" data-actual-value="1213" data-init-label="Label for 1213 item">

Затем при инициализации:

onInitialize: function() {
        var actualValue = this.$input.data('actual-value');
        if (actualValue){
            this.addOption({id: actualValue, value: this.$input.data('init-label')});
            this.setValue(actualValue);
            this.blur();
        }
    }

В соответствии с этими параметрами:

$('input').selectize({
    valueField: 'id',
    labelField: 'value',
    searchField: 'value',
    create: false,
    maxItems: 1,
    preload: true,
    // I had to initialize options in order to addOption to work properly 
    // although I'm loading the data remotely
    options: [],
    load: ... ,
    render: ...,
    onInitialize: ....
});

Я знаю, что это не отвечает на ваш вопрос, но хочет поделиться на всякий случай, это может помочь кому-то.

Ответ 3

Еще проще в новой версии selectize, используя атрибут items. В основном, чтобы установить выбранный элемент, вам нужно сначала его использовать в настройках. Но если вы используете удаленные данные, подобные мне, параметры пустые, поэтому вам нужно добавить их в оба места.

$('select').selectize({
        valueField: 'id',
        labelField: 'name',
        options:[{id:'123',name:'hello'}],
        items: ['123'],
        ...

Это работает для меня, и мне потребовалось некоторое время, чтобы понять это... так просто обмениваться