Loading values into Selectize.js
Asked Answered
C

3

19

Problem

I have a text input that I have selectized as tags which works fine for querying remote data, I can search and even create new items using it and that all works OK.

Using 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);
            }
        });
    }
});

The text box:

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

Examples:

Authors working

Then when I select one (in this case 'apple') it comes up in a badge as you'd expect, and the underlying value of the textbox is a comma separated list of the values of these items.

Author with badge

Current Output

The problem is when I load a page and want values retrieved from the database to be displayed in the selectized text input as tags, it only loads the values and I can see no way of displaying the displayname instead.

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

Numbers only

Desired Ouput

I have tried all sorts of values for the inputs value field to have it load the items as showing their displayname and not their values. Below is an example of a single object being returned as JSON, being able to load a JSON array of these as selectized tags would be ideal.

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

enter image description here

How can I go about this? Do I need to form the value of the text box a particular way, or do I need to load my existing values using some javascript?

Cataract answered 11/9, 2014 at 3:46 Comment(1)
As an update, I have created a jsfiddle here which can be used to test the preloading / behaviour out.Cataract
C
11

I ended up using the onInitialize callback to load the JSON values stored in a data-* field. You can see it in action here in this jsfiddle.

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

Basically it parses the data-selectize-value value and then adds the option(s) to the selectize then adds the items themselves.

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]);
    }
}

My solution does presume my JSON object is formed correctly, and that it's either a single object or an object Array, so it may or may not be appropriate for someone elses needs.

So it parses:

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

To:

enter image description here

Based of course on my selectize settings in my original post above.

Cataract answered 11/9, 2014 at 5:38 Comment(1)
The CDN the jsfiddle used back in 2014 is no longer responding. I edited in a link to a working jsfiddle again.Cataract
P
11

Thanks to your answer and based on your onInitialize() approach I ended up with a similar solution. In my case I just needed to translate one value, thus I was able to store the id and label as data attributes in the input field.

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

Then on initialization:

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

According to these options:

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

I know this does not answer your question but wanted to share just in case this could help someone.

Prolongate answered 12/12, 2014 at 12:8 Comment(0)
C
6

Even simpler on new version of selectize using items attribute. Basically to set a selected item you need to have it first in the options. But if you use remote data like me, the options are empty so you need to add it to both places.

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

This is working for me and took me a while to figure it out... so just sharing

Cushion answered 16/7, 2017 at 3:50 Comment(1)
do you always have to do this for remote data? I'm wondering if this is my problem over here at #46802564 if you have a sec to check it out maybe you can see what I'm doing wrong.Hardhearted

© 2022 - 2024 — McMap. All rights reserved.