How to retain dependent dropdown values using Select2 and Ajax - javascript

I have a script that populates the state dropdown based on country id and while everything is working great I can only save the countries dropdown option on page reload but not the state option using html localStorage.
Here is my code:
$(document).ready(function() {
var country_id = null;
var state_id = null;
$('#country').select2();
$('#state').select2();
$('#city').select2();
$('select[name="country"]').on('change', function() {
var country_id = $(this).val();
if (country_id) {
$.ajax({
url: "/world/getStates.php",
type: "GET",
data: {
'country_id': country_id
},
dataType: "json",
success: function(data) {
$('select[name="state"]').empty();
$('select[name="city"]').empty();
$('select[name="state"]').append('<option value="">Select State</option>');
$.each(JSON.parse(data), function(key, value) {
$('select[name="state"]').append('<option value="' + value.id + '">' + value.name + '</option>');
});
}
});
} else {
$('select[name="state"]').empty();
}
});
$('select[name="state"]').on('change', function() {
var country_id = $('#country').val();
var state_id = $(this).val();
if (state_id) {
$.ajax({
url: "/world/getCities.php",
type: "GET",
data: {
'country_id': country_id,
'state_id': state_id
},
dataType: "json",
success: function(data) {
$('select[name="city"]').empty();
$('select[name="city"]').append('<option value="">Select City</option>');
$.each(JSON.parse(data), function(key, value) {
$('select[name="city"]').append('<option value="' + value.id + '">' + value.name + '</option>');
});
}
});
} else {
$('select[name="city"]').empty();
}
});
$('#country').val("value from localStorage").trigger('change');
$('#state').val("value from localStorage").trigger('change');
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<label for="country">Country</label>
<select class="csc-select" name="country" id="country">
<option value="">Select Country</option>
<option>Australia</option>
<option>Denmark</option>
<option>Japan</option>
<option>Norway</option>
<option>Switzerland</option>
</select>
<label for="state">State</label>
<select class="csc-select" name="state" id="state">
<option value="">Select State</option>
</select>
<label for="city">City</label>
<select class="csc-select" name="city" id="city">
<option value="">Select City</option>
</select>
So when I call this after the first on change for the country select, it selects the country based on the localStorage value and triggers the change but it does not do the same for the state, any ideas what I am missing here?

Your options inside state dropdown is loaded after the ajax success is executed so your other code doesn't wait for that and .val() fired before only that's the reason the value is not marked as selected inside state dropdown. Now , to fix this you can move that part inside success function of ajax and then call your change event after the options are appended inside state dropdown.
Demo Code :
$(document).ready(function() {
var country_id = 1 //localStorage.getItem("select2CountryValue");
var state_id = 3 //localStorage.getItem("select2StateValue");
var page_load = true; //added this
var data = [{
"id": 1,
"name": "xyz_State1"
}, {
"id": 2,
"name": "xyz_State2"
}, {
"id": 3,
"name": "xyz_State3"
}] //this is just the demo datas
$('#country').select2();
$('#state').select2();
$('select[name="country"]').on('change', function() {
var country_id = $(this).val();
//localStorage.setItem("select2CountryValue", country_id);
if (country_id) {
/*$.ajax({
url: "/world/getStates.php",
type: "GET",
data: {
'country_id': country_id
},
dataType: "json",
success: function(data) {
console.log(data);
$('select[name="city"]').empty();*/
$('select[name="state"]').empty();
$('select[name="state"]').append('<option value="">Select State</option>');
$.each(data, function(key, value) {
$('select[name="state"]').append('<option value="' + value.id + '">' + value.name + '</option>');
});
//check if the change is called on page load
if (page_load == true) {
$('#state').val(state_id).trigger('change'); //assign slected value after elemnt option is added in dom
page_load = false; //add this so that next time this doesn't get execute
}
/* }
});*/
} else {
$('select[name="state"]').empty();
}
});
$('#country').val(country_id).trigger('change');
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" />
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.full.min.js"></script>
<p>
<span>Country</span>
<select class="csc-select" name="country" id="country">
<option value="">Select Country</option>
<option value="1">
xyz
</option>
<option value="2">
xyz2
</option>
</select>
</p>
<p>
<span>State</span>
<select class="csc-select" name="state" id="state">
<option value="">Select State</option>
</select>
</p>

when I call this after the first on change for the country select, it selects the country based on the localStorage value and triggers the change but it does not do the same for the state, any ideas what I am missing here?
When you trigger the change event for your #country list, the list of countries already contains values.
When you trigger the change event for your #state list immediately after that, the list is still empty. There can't be any value selected, so the change event does nothing.
You need to wait until the state list is populated, and then trigger the change event.
// this works immediately, because there are countries in your HTML
$('#country').val("value from localStorage").trigger('change');
// this needs to happen in the `success` callback of country Ajax call
$('#state').val("value from localStorage").trigger('change');
The alternative is that you create a temporary option first:
$('#state').append("temporary <option> created from localStorage");
$('#state').val("value from localStorage").trigger('change');
This way you would not have to wait.
That being said, Select2 supports remote data, you don't have to write the Ajax requests or the <option> creation yourself.
$("#country").select2({
ajax: {
url: "/world/getCountries.php"
},
placeholder: 'Pick a country',
minimumInputLength: 1
}).change(function () {
$("#state").val("").trigger("change");
});
$("#state").select2({
ajax: {
url: "/world/getStates.php",
data: (params) => {
// add selected country ID to URL params
params.country_id = $("#country").val();
return params;
}
},
placeholder: 'Pick a state',
minimumInputLength: 1
});
// initialize selection from previous state...
$("#country").append('<option value="5">Switzerland</option>');
$("#country").val("5");
$("#state").append('<option value="9">Appenzell</option>');
$("#state").val("9");
// server side mock-up -------------------------------------------------
const countries = [
{id: 1, text: 'Australia'},
{id: 2, text: 'Denmark' },
{id: 3, text: 'Japan'},
{id: 4, text: 'Norway'},
{id: 5, text: 'Switzerland'}
];
const states = [
{id: 1, text: 'New South Wales', country_id: 1},
{id: 2, text: 'Victoria', country_id: 1},
{id: 3, text: 'Hovedstaden', country_id: 2},
{id: 4, text: 'Midtjylland', country_id: 2},
{id: 5, text: 'Hokkaido', country_id: 3},
{id: 6, text: 'Shikoku', country_id: 3},
{id: 7, text: 'Northern Norway', country_id: 4},
{id: 8, text: 'Southern Norway', country_id: 4},
{id: 9, text: 'Appenzell', country_id: 5},
{id: 10, text: 'Zürich', country_id: 5},
];
$.mockjaxSettings.logging = 1;
$.mockjax({
url: "/world/getCountries.php",
contentType: "application/json",
response: function(settings) {
this.responseText = {
results: countries.filter(item =>
!settings.data.term || item.text.toLowerCase().includes(settings.data.term.toLowerCase())
)
};
}
});
$.mockjax({
url: "/world/getStates.php",
contentType: "application/json",
response: function(settings) {
console.log(settings.data);
this.responseText = {
results: states.filter(item =>
item.country_id == settings.data.country_id && (
!settings.data.term || item.text.toLowerCase().includes(settings.data.term.toLowerCase())
)
)
};
}
});
select {
width: 200px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/2.6.0/jquery.mockjax.min.js"></script>
<select id="country"></select>
<select id="state"></select>

Related

How to enable/disable 2nd dropdownlist value based on the selection of the previous dropdown value

We have 2 dropdowns. On selection of the first dropdown the value related to it show be enabled or get highlighted and rest other options should be in disabled in the second dropdown. Both the dropdowns are multiselect and are array of objects.
I am able to append the conditional value in the second dropdown but rest other options are getting hide.I want all options to be visible and teh one selcted should be enabled/highlighted.
var firstVal = [
{ id: 1, value: 'foo1' },
{ id: 2, value: 'foo2' },
{ id: 3, value: 'foo3' },
]
var secondVal = [
{ id: 1, value: 'foo11' },
{ id: 2, value: 'foo21' },
{ id: 2, value: 'foo22' },
{ id: 3, value: 'foo31' },
{ id: 3, value: 'foo32' },
]
$('#rewardType').change(function (){
var firstSelcted = $(this).val();if (firstSelcted && firstSelcted.length > 0) {
for (var j = 0; j < firstSelcted.length; j++) {
var filtered = secondVal.filter( function(myArr){
return myArr.id == firstSelcted[j];
});for (var k = 0; k < filtered.length; k++) {
$('#rewardTypes').append('<option value="' + filtered[k].value + '">' + filtered[k].value + '</option>');
}
$('this').css('background-color','red');
$('#rewardTypes').selectpicker('refresh');
}
If I select foo2 in first dropdown then in 2nd dropdown it should get highlighted or enabled foo21,foo22. And rest others should be disabled.
You can try below approach where you can populate list using json array and on change event of first list you can enable or disable the second list options
$(document).ready(function(){
var firstVal = [
{ id: 1, value: 'foo1' },
{ id: 2, value: 'foo2' },
{ id: 3, value: 'foo3' },
] ;
var secondVal = [
{ id: 1, value: 'foo11' },
{ id: 2, value: 'foo21' },
{ id: 2, value: 'foo22' },
{ id: 3, value: 'foo31' },
{ id: 3, value: 'foo32' },
]
var $firstList = $('#rewardType');
var $secondList = $('#rewardTypes');
$.each(firstVal, function(key,val){
$firstList.append('<option value="' + val.id + '">' + val.value + '</option>');
});
$.each(secondVal, function(key,val){
$secondList.append('<option disabled value="' + val.id + '">' + val.value + '</option>');
});
$firstList.change(function(){
var value = $(this).val();
//console.log(value);
$secondList.val("");
$secondList.find('option').each(function(){
var optVal = $(this).attr('value');
//console.log("option " + optVal);
if(value.indexOf(optVal)>=0) {
$(this).removeAttr('disabled');
} else {
$(this).attr('disabled',true);
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<select id="rewardType" multiple="true"><option value=""></option></select>
<select id="rewardTypes" multiple="true"><option value=""></option></select>
First code block is for HTML and second code block is JQuery
try this:
<select id='firstval' onchange="witness();">
<option selected></option>
<option value="1">Apple</option>
<option value="2">Mango</option>
</select>
<select id='secondval'>
<option selected></option>
<option value="1">Apple</option>
<option value="2">Mango</option>
</select>
function witness(){
$("#secondval option").each(function(){
if($("#firstval option:selected").val() == $(this).val())
$(this).attr("disabled", "disabled");
else
$(this).removeAttr("disabled");
});
}

How to show the selected plan value in a text box in vue js html?

My json data is as follows
{"status": true, "plans": [{"planId": 1, "name": "Baic", "cost": 500.0, "validity": 365}, {"planId": 3, "name": "free", "cost": 0.0, "validity": 999}, {"planId": 4, "name": "Premium", "cost": 500.0, "validity": 500}, {"planId": 5, "name": "Super Premium", "cost": 750.0, "validity": 600}, {"planId": 6, "name": "New", "cost": 600.0, "validity": 180}]}
I need to select a particular category from the above list and display the corresponding cost of the category in a text box and i need to able to edit the value. How acan I able to obtain the same.
Currently my html code is
<div class="form-group">
<label>Plan <small>(select your plan)</small></label>
<select id="bas" class="selectpicker" data-live-search="true" data-live-search-style="begins" title="Select Plan" v-model="plan" name="plan" ref="plan" required="required">
<option v-for="post in plansb" v-bind:value="post.planId" v-if="plansb.indexOf(post) > 0">{{post.name}} (Rs.{{post.cost}})</option>
</select>
</div>
<div class="form-group">
<label>Plan Amount <small>(required)</small></label>
<input name="plan_amt" type="text" class="form-control" id="plan_amt" placeholder="Plan Amount" v-model="plan_amt" />
</div>
In the Plan Amount text-box I need to display the cost of which category is selected from the above selection. Now I need to enter the amount. IF is selected planId = 1, I need to display 500 in the text-box. Also i need to edit those value and send as as ajax request.
How can I able to get the result as such.
My vue js code is
vBox = new Vue({
el: "#vBox",
data: {
plansb: [],
plan: '',
plan_amt: '',
},
mounted: function() {
var vm = this;
$.ajax({
url: "http://127.0.0.1:8000/alpha/get/plan/",
method: "GET",
dataType: "JSON",
success: function(e) {
if (e.status == 1) {
vm.plansb = e.plans;
}
},
});
},
methods: {
handelSubmit: function(e) {
var vm = this;
data = {};
data['plan'] = this.plan;
data['plan_amt'] = this.plan_amt;
$.ajax({
url: 'http://127.0.0.1:8000/alpha/add/post/',
data: data,
type: "POST",
dataType: 'json',
success: function(e) {
if (e.status)
{
$("#alertModal").modal('show');
$(".alert").removeClass("hidden").html("Your data has been successfully recorded");
vm.pid=e.pid;
console.log(vm.pid);
}
else {
vm.response = e;
alert("Registration Failed")
}
}
});
return false;
},
Can anybody please help me to obtain the result. Based on the selection of plans from the select, I need to update the values in the text box. Please help me to have a result.
You need to add change event of list and get the planid of palns, and according to planid get cost of it and assign it to cost(text-box) model where u want to show change plan cost

Populate multi select select2 option from REST API

I have 3 select2 fields where I want to populate them using AJAX from API. My question is, how can I populate the first select field option directly from API and then the second field option is populated also by API but based on my selection(s) from the first select field, same goes for the third one.
For example, below are my code & data:
API
[
{
"id": 1,
"project_type": "tv",
"project_stage": "new",
"project_name": "Project A"
},
{
"id": 2,
"project_type": "game",
"project_stage": "completed",
"project_name": "Project B"
},
{
"id": 3,
"project_type": "game",
"project_stage": "new",
"project_name": "Project C"
},
{
"id": 4,
"project_stage": "completed",
"project_type": "film",
"project_name": "Project D"
}
]
HTML
<div class="group">
<select class="project_type" id="project_type" multiple="multiple">
<option value=""></option>
</select>
<select class="project_status" id="project_status" multiple="multiple"">
<option value=""></option>
</select>
<select class="project_select" id="project_select" multiple="multiple">
<option value=""></option>
</select>
</div>
Javascript
$('#project_type').select2({placeholder: "Select project type",});
$('#project_status').select2({placeholder: "Select project Status",});
$('#project_select').select2({placeholder: "Select project",});
Expected Result :
Now the project_type select field wield populate all of the project type as option and say we select "game" then the project_status option would be :
<select class="project_status" id="project_status" multiple="multiple"">
<option value="completed">Completed</option>
<option value="new">New</option>
</select>
and if we select completed, the third filter would be:
<select class="project_select" id="project_select" multiple="multiple">
<option value="Project B">Project B</option>
</select>
I populated this from jinja2 before and its not dynamic, any help is much appreciated thanks.
UPDATE :
below is my current code, for odd reason even for the first filter, its not populating the option even though I'm getting the data :
$('#project_type').select2({
placeholder: "Select project type",
ajax: {
url: '/api/filter/',
delay: 250,
type: 'GET',
data: function (params) {
var query = {
search: params.term,
type: 'public'
}
return query
},
processResults: function (data) {
var data1 = $.map(data, function (obj, idx) {
console.log(obj.project_type);
return obj;
});
console.log("processResults2:", data1);
return {
results: data1,
};
}
}
});
Here is a snippet implementing Select2 Ajax populate (in cascade):
var data = [
{
"id": 1,
"project_type": "tv",
"project_stage": "new",
"project_name": "Project A"
},
{
"id": 2,
"project_type": "game",
"project_stage": "completed",
"project_name": "Project B"
},
{
"id": 3,
"project_type": "game",
"project_stage": "new",
"project_name": "Project C"
},
{
"id": 4,
"project_stage": "completed",
"project_type": "film",
"project_name": "Project D"
}
];
sel_type();
$('#project_status').select2({placeholder: ""});
$('#project_select').select2({ placeholder: ""});
function sel_type() {
$('#project_type').select2({
placeholder: "Select project type",
ajax: {
type: "POST",
url: '/echo/json/',
data: function(params){
var query={
message:params.term,
data: data
}
return { json: JSON.stringify( query ) }
},
processResults: function (data) {
var grouped = groupBy(data.data, 'project_type');
var data1 = [], i = 0;
for (var k in grouped) {
data1.push({"id": i++, "text": k})
}
return {
results: data1,
};
}
}
});
$('#project_type').on('select2:select', function (e) {
var data = e.params.data;
console.log(data);
sel_status(data.text);
});
}
function sel_status(type) {
$('#project_status').select2({
placeholder: "Select project status",
ajax: {
type: "POST",
url: '/echo/json/',
data: function(params){
var query={
message:params.term,
data: data
}
return { json: JSON.stringify( query ) }
},
processResults: function (data) {
var data1 = $.map(data.data, function (obj, idx) {
if (obj.project_type==type)
return obj;
});
var grouped = groupBy(data1, 'project_stage');
var data1 = [], i = 0;
for (var k in grouped) {
data1.push({"id": i++, "text": k})
}
return {
results: data1,
};
}
}
});
$('#project_status').on('select2:select', function (e) {
var data = e.params.data;
console.log(data);
sel_proj(type, data.text);
});
}
function sel_proj(type, status) {
$('#project_select').select2({
placeholder: "Select project",
ajax: {
type: "POST",
url: '/echo/json/',
data: function(params){
var query={
message:params.term,
data: data
}
return { json: JSON.stringify( query ) }
},
processResults: function (data) {
var data1 = $.map(data.data, function (obj, idx) {
if (obj.project_type==type && obj.project_stage==status) {
obj.id = obj.id || idx;
obj.text = obj.project_name;
return obj;
}
});
return {
results: data1,
};
}
}
});
}
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
select {
width:200px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet"/>
<div class="group">
<select class="project_type" id="project_type" multiple="multiple">
<option value=""></option>
</select>
<br/>
<select class="project_status" id="project_status" multiple="multiple">
<option value=""></option>
</select>
<br/>
<select class="project_select" id="project_select" multiple="multiple">
<option value=""></option>
</select>
</div>
but because of the Ajax request it does not work here in StackOverflow.
A working version (using JsFiddle echo) is here: https://jsfiddle.net/beaver71/4nq62nqo/
P.S.: you have to change the uri in Ajax request to yours, and remove POST of data.

Vue js populate new selects when changing the main one

I need your help about populating or loading new select with vue js, I know how to do this with jquery but in vue i don't know how because i'm new with this library.
i have the main select :
<select>
<option value='3'>FRANCE</option>
<option value='5'>USA</option>
<option value='6'>CANADA</option>
<option value='8'>MOROCCO</option>
</select>
I want that if i choose FRANCE i get a select of FRANCE cities from database, and also when i select USA i get an other select of USA cities from database.
So for example i will get :
<select>
<option value='6'>CANADA</option>
<option value='8'>MOROCCO</option>
</select>
<select>
<option value='34'>France city one</option>
<option value='35'>France city two</option>
</select>
<select>
<option value='3'>Usa city one</option>
<option value='5'>Usa city two</option>
</select>
When choosing France and USA i will populate select of cities with an array
I appreciate any help, I don't realy know how can i do this with vue js,
I don't want add all select of cities in my html because i don't know how much countries i have.
I tried this but this not resolve my probleme :
const addProduct = new Vue({
el: '#addProduct',
data: {
name: '',
name_url: '',
cities: '',
countries: [],
range: 0
},
created: function () {
this.$http.get('/api/countries').then(response => {
this.countries = response.data
}, response => {
});
},
methods: {
addForm: function(val, data) {
this.range += 1;
alert(this.range)
var index = _.findIndex(this.countries,{city_id: val});
this.countries.splice(index, 1)
}
},
watch: {
'cities' (val, oldVal) {
this.$http.post('/api/cities/values', {city_id:val}).then(response => {
this.addForm(val, response.data);
}, response => {
});
}
}
});
in html :
<div class="uk-grid" data-uk-grid-margin>
<div class="uk-width-medium-1-4">
<label for="attribute">Countries</label>
<md-select name="country" id="country" v-model="country">
<md-option v-for="country in countries" :value="country.country_id">#{{ country.name }}</md-option>
</md-select>
</div>
</div>
<div class="uk-grid" data-uk-grid-margin>
<my-cities v-for="n in range"></my-cities>
</div>
<script type="x-template" id="my-cities">
<div class="uk-width-medium-1-4">
<label for="attr">Cities</label>
<md-select name="attr" id="attr" v-model="attr">
<md-option value="">Select </md-option>
<md-option value="val in values">Select</md-option>
</md-select>
</div>
</script>
an example like this on Jsfiddle : http://jsfiddle.net/pu8pp62v/3/
This is an example that you can maybe use (but need some modifications to use your API call) :
new Vue({
el: "#app",
data: function() {
return {
selectedCountries: [],
selectOptionsCountries: [
{ value: 3, name: 'FRANCE' },
{ value: 5, name: 'USA' },
{ value: 6, name: 'CANADA' },
{ value: 8, name: 'MOROCCO' }
],
selectedCities: [],
selectOptionsCities: []
}
},
methods: {
},
watch: {
selectedCountries: function(newValue, oldValue) {
this.selectOptionsCities = [];
this.selectedCities = [];
for( var i = 0, length = newValue.length; i < length; i++ ){
this.selectedCities[i] = [];
if( newValue[i] === 3 ){
this.selectOptionsCities.push(
[{ value: 31, name: 'Paris' },
{ value: 32, name: 'Marseille' }]
)
}
if( newValue[i] === 5 ){
this.selectOptionsCities.push(
[{ value: 51, name: 'New-York' },
{ value: 52, name: 'Boston' }]
)
}
if( newValue[i] === 6 ){
this.selectOptionsCities.push(
[{ value: 61, name: 'Montreal' },
{ value: 62, name: 'Vancouver' },
{ value: 63, name: 'Ottawa' },
{ value: 64, name: 'Toronto' }]
)
}
if( newValue[i] === 8 ){
this.selectOptionsCities.push(
[{ value: 81, name: 'Rabat' },
{ value: 82, name: 'Casablanca' },
{ value: 83, name: 'Fes' }]
)
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.5/vue.js"></script>
<div id="app">
Selected countries : {{ selectedCountries }}
<br />
Selected cities : {{ selectedCities }}
<br />
<select v-model="selectedCountries" multiple>
<option v-for="(option, index) in selectOptionsCountries" :value='option.value'>
{{ option.name }}
</option>
</select>
<select v-for="(optionsCities, index) in selectOptionsCities" v-model="selectedCities[index]" multiple>
<option v-for="(option, index) in optionsCities" :value='option.value'>
{{ option.name }}
</option>
</select>
</div>
Added after author's comment:
Check this fiddle: http://jsfiddle.net/jjpfvx5q/1/
Inside 'chosenCities' array you have all selected cities by country (one city per country.)
Original answer:
Here is an example for you: fiddle
Is that what you are trying to achieve?
setTimeout functions are just pretending a real data fetching.
<script src="//unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<template>
<div>
<select v-model="country">
<option disabled value="">Please select one</option>
<option
v-for="c in countries"
:value="c.id">{{ c.name }}</option>
</select>
<span>Selected: {{ country }}</span>
<span v-if="cities.length">Cities:</span>
<ul v-if="cities.length">
<li v-for="c in cities">{{ c }}</li>
</ul>
</div>
</template>
</div>
<script>
var Main = {
data() {
return {
country: {},
countries: [],
cities: [],
coInit: [{ id: '3', name: 'France' }, { id: '2', name: 'USA' }],
cFrance: ['Paris', 'Whatever'],
cUSA: ['NY', 'LA']
}
},
methods: {
loadCountries: function () {
setTimeout(() => { this.countries = this.coInit }, 500);
},
getCities: function() {
if(this.country) {
switch (this.country) {
case '3':
setTimeout(() => { this.cities = this.cFrance }, 500);
break;
case '2':
setTimeout(() => { this.cities = this.cUSA }, 500);
break;
}
}
}
},
mounted() {
this.loadCountries();
},
watch: {
country: function() {
this.getCities();
}
}
}
var Ctor = Vue.extend(Main);
new Ctor().$mount('#app');
</script>

How to pre-select values in select2 multi select?

I am having a multiple select like this:
<select multiple="multiple" class="myList">
<option value="1" selected="selected">Apple</option>
<option value="2" selected="selected">Mango</option>
<option value="3" selected="selected">Orange</option>
</select>
Now, apart from those options which must come selected in the select box, I wanted additional ajax functionality which would give values from a remote source.
Here is my code for select2
$(function(){
$(".myList").each(function(){
$(this).select2({
placeholder: "Search for fruits",
minimumInputLength: 2,
multiple: true,
id: function(e) {
return e.id+":"+e.name; },
ajax: {
url: "https://localhost:8443/fruit_search",
dataType: 'json',
data: function(term, page) {
return {
q: term
};
},
results: function(data, page) {
var frts=[];
$.each(data,function(idx,Frt){
frts[frts.length]=Frt;
});
return {
results: frts
};
}
},
initSelection: function(element, callback) {
var data = [];
},
formatResult: formatResult,
formatSelection: formatSelection
});
});
});
But I am getting the error:
Error: Option 'id' is not allowed for Select2 when attached to a
<select> element.
But when I use <input type="hidden"> then where should I keep the pre-selected options? How do I show them up when the select2 box appears?
If you only have values then you can use 'val' to get pre-selected values like this.
var PRESELECTED_FRUITS = [ '1','2','3'];
$('.myList').select2({}).select2('val', PRESELECTED_FRUITS);
You can use the "data" function to set the initial values:
var PRESELECTED_FRUITS = [
{ id: '1', text: 'Apple' },
{ id: '2', text: 'Mango' },
{ id: '3', text: 'Orange' }
];
$('.myList').select2('data', PRESELECTED_FRUITS)
Note: The "val" function is another way to set the initial values, but you only specify the ids with that function. In that case you would have to supply an "initSelection" function that builds the objects from the ids.
Also note that the "id" option is not the only option that is forcing you to use a hidden input. You cannot use the "ajax" option with a select element either.
As for the "id" option, I don't think you need it. Just put logic in the ajax "results" function so it builds an array of objects that have the proper id and text properties, or have the server return objects with those properties.
jsfiddle demo
To preset values use the 'val' property to preset the selected values.
$(this).select2({
val: ["1","2","3"]
}
But why not remove the 'id' function? If possible you could return the correct 'id' from the server without the need of the id function.
You can also load the values into the HTML:
<select class="selector" multiple="multiple" >
<option selected value="1">Apple</option>
<option selected value="2">Mango</option>
<option selected value="3">Orange</option>
</select>
And connect select2 to it:
$(".selector").select2({
width: 'inherit',
minimumInputLength: 2,
minimumResultsForSearch: 10,
placeholder: "Search for fruits",
ajax: {
delay: 1000,
url: "/bla_foo",
dataType: 'json',
type: "GET",
}
})
and select2 will prefill the form.
$('select').select2({
multiple: true,
data: [
{id: 1, text: 'Foo', selected: true},
{id: 2, text: 'Bar', selected: true}
]
})
$("#select2").select2('data', {id: '3', text: 'myText'});

Categories