I have a PHP app with a TomSelect dropdown which allows me to select persons who work on a site.
As this list is large, I fill in these options via a standard fetch
call.
Here's my code sample (which works):
<select id="persons" placeholder="Pick an person..." multiple></select>
<script>
var persons = new TomSelect("#persons", {
maxOptions: 10,
create: false,
onItemAdd: function () {
this.setTextboxValue('');
this.refreshOptions();
},
valueField: 'id',
labelField: 'completename',
searchField: 'completename',
items: [34276,2],
// fetch remote data
load: function(query, callback) {
var url = 'http://host/api/staff?q=' + encodeURIComponent(query);
fetch(url)
.then((response) => response.json())
.then(json => {
callback(json);
}).catch(()=>{
callback();
});
},
// custom rendering functions for options and items
render: {
option: function (data, escape) {
return '<div class="d-flex"><span>' + escape(data.completename) + '</span></div>';
},
item: function (data, escape) {
return '<span class="tag is-info mb-1 mr-1">' + escape(data.completename) + '</span>';
}
}
});
</script>
Everything is saved properly to the database via PHP when the form is posted.
My question is about editing a site (when I come back to edit people assigned to a site).
How can I pre-select/pre-fill the people already assigned (34276
and 2
in the sample) and put them properly in the initial options. I have tried with the initial array items[]
, but this array only takes IDs of selectedValues
but obviously not people's completenames.
I obviously have my PHP objects available like $site->getPersons()
over which I can loop to get the IDs and completenames.
If I do it with an addOption
and addItem
afterwards, (or if I add the assigned people in HTML with an <option value="1" selected="selected">Roberta</option>
) it works, but the behaviour is horrible because these pre-assigned people remain permanently at the start of the dropdown even when I deselect them and while the fetch API call is empty. As shown on the picture.
persons.addOption({
id: 4,
completename: 'Something New',
});
persons.addOption({
id: 2,
completename: 'Hans',
});
persons.addOption({
id: 1,
completename: 'Roberta',
});
persons.addItem(1);
persons.addItem(4);
persons.addItem(2);
Another shorter way of asking my question would be :
How to prevent my TomSelect dropdown (intended to receive options via fetch remote) from opening with "static" options added via addOption already visible.
I would like it to be empty until the fetch call has been made.
I found the solution.
I just needed to add the persist:false
option.
As defined in the official TomSelect documentation:
persist: If false, items created by the user will not show up as available options once they are unselected.
Now, I can pre-fill items[]
and delete them properly without polluting the dropdown.