How to create dynamic two relational dropdown in Vuejs - javascript

I am new to vue.js. I'm stuck trying to dynamically set the options of one select based on the selected value in another.
For example, I have two dropdowns named division and district.
var A = [{1: 'a'},{2:'b'}];
If value of A is 1, then the district select should load the related codes. I can do it with jQuery but not with Vue.
Here is my template.
<div class="form-group" :class="class_obj">
<select name="div_code" v-model="div_code" class="form-control" required>
<option value="">Choose One</option>
<option v-for="option in div_list" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
</div>
<div class="form-group" :class="class_label">
<label for="">District</label>
</div>
<div class="form-group" :class="class_obj">
<select name="dist_code" v-model="dist_code" class="form-control" required>
<option value="">Choose One</option>
</select>
</div>
Here is my javascript.
export default {
data():{
div_list: [
{'1': "ABC"} , {'2': "DEF"}
];
}
}
How can I load the dist_code select with related data from ajax when div_code value is 1?

Handle a change event on the div_code change
<select name="div_code"
v-model="div_code"
#change="onDivCodeChange"
class="form-control"
required>
<option value="">Choose One</option>
<option v-for="option in div_list" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
And add the onDivCodeChange method to your Vue.
methods:{
onCodeChange(){
// make an ajax call and set the options for your
// dist_code here. For example:
$.ajax({
url: "...",
data: {div_code: this.div_code},
success: codes => this.code_list = codes
error: err => console.log(err)
})
}
}
And of course add code_list as a property of your data and update your template.
<select name="dist_code" v-model="dist_code" class="form-control" required>
<option value="">Choose One</option>
<option v-for="code in code_list" :value="code.value">{{code.text}}</option>
</select>

Create computed property. Basically, when data property changes(should be used in computed property) the computed property will update itself.
As in below example, when message property changes the reverseMessage will update itself.
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
1- In your example, bind your first dropdown value to a data property.
2 -Create a computed property for the second dropdown and use the data
property in it.
3 -Write the template of it.
Done.
When the first dropdown changes the second dropdown will update itself.
Note: Vue documentation advise to use Watcher for Ajax requests instead of computed properties. Both are very similar.
https://v2.vuejs.org/v2/guide/computed.html#Watchers

Related

Select input cannot have a default value (Vue.js)

Trying to set a default value to a simple select input with "selected" doesn't work.
I am making a blog in Vue.js and the blog posts can be assigned to different categories. However, when editing a post, I want the select input to have a default value if the post is already inside a category. The pseudo-code would look like so: "if category.id equals post.category.id".
This is my input:
<label>
<VeeValidateField name="post_category" as="select">
<option value="" disabled>Set to folder</option>
<option value="0">none</option>
<option v-for="category in categories"
:key="category.id"
:value="category.id"
:selected="category.id === post.category.value"
>
{{ category.category_name }}
</option>
</VeeValidateField>
</label>
Although there can be a default value with a multiple select input, that is not my use case.
Is this a bug or am I doing something wrong?!
Thank you!
I solved this by using v-model and setting the value in data to the following expression:
data() {
return {
categoryValue: this.$props.login ? this.$props.login.login_category.value : ""
}
}
and this is the markup:
<label>
<VeeValidateField v-model="categoryValue" name="login_category" as="select">
<option value="" disabled>Set to folder</option>
<option value="0">none</option>
<option v-for="category in categories"
:key="category.id"
:value="category.id">
{{ category.category_name }}
</option>
</VeeValidateField>
</label>
So when the property categoryValue evaluates, the select input either gets a default value or none at all.

Default option in <select> not showing

I am experiencing a stupid issue with a <select>. My toolchain of choice is Vue.js with Bootstrap and I am trying to create a dynamic <select> that is populated with Vue. My issue however is that the default option in the <select> is not showing, instead the form-element is blank.
This is my coding, the input group is almost identical to the example provided in the Bootstrap documentation. I also tried the suggestions mentioned in this question however they did not work.
<div class="input-group mb-3">
<div class="input-group-prepend">
<label
class="input-group-text"
for="action_manufacturer_input">Manufacturer</label>
</div>
<select
v-model="form.manufacturer"
class="custom-select"
id="manufacturer_input">
<option disabled selected value="undefined">Please select one...</option>
<option
v-for="manufacturer in manufacturers"
v-bind:value="manufacturer.id">
{{ manufacturer.display_name }} : {{ manufacturer.full_name }}
</option>
<option v-on:click="toggle_input()">Add new manufacturer...</option>
</select>
</div>
As a sanity check I removed the Bootstrap styling however that did not change anything. My question: how do I get the default selected option to show?
P.S. For what it's worth my back-end is Laravel, however I don't see how it could cause an issue.
The v-model of your select is binded with form.manufacturer state
What is the value of form.manufacturer ?
You need to cheek that, because, Vue is searching an option that match to the value of form.manufacturer.
I have created this codepen as example
<div id="app">
<!--Bind select value with form.category-->
<select name="options" v-model="form.category">
<!--Add an empty (no value) option-->
<option :value="null">Choose a Category</option>
<!--Add options when value is id-->
<option v-for="category in categories"
:key="category.id"
:value="category.id"
>
{{category.name}}
</option>
</select>
<br><br>
<!--See how the state change when option select change-->
<div>Value of Category: {{form.category}}</div>
</div>
var app = new Vue({
el: '#app',
data: {
form:{
category: null
},
categories: [
{id: 1, name:"Category 1"},
{id: 2, name:"Category 2"},
{id:3, name:"Category 3"}
]
}
})
Thanks to #Martin who in the comments section prompted me to look elsewhere and I found it. (#Cristian Incarnato answered the question as I answered it). I have a habit from C++ of initializing all my data variables with null values. So my data variables were being set as:
data() {
return {
form: {
manufacturer: null,
}
};
},
By changing the above to the following:
data() {
return {
form: {
manufacturer: "Please select one...",
}
};
},
This fixed the issue. Thanks to all for the help!
I had a similar issue where my disabled option was not showing in a Select and the only thing that was missing was the binding of the value property on the disabled (desired default) option.
Not working:
<option disabled value="null">Select one</option>
vs. Short hand Working:
<option disabled :value="null">Select one</option>
Long form working:
<option disabled v-bind:value="null">Select one</option>
Notice the value attribute is not bound to anything in the first example, thus Vue is unable to assign it.

EmberJS Select onChange event not passing selected value

I'm trying to get the selected value from a select tag, I have tried these cases but I'm not able to get the selected value, Does anyone have an idea on what is wrong with the way I'm declaring the action on the select tag?
UPDATE 1
I tried to recreate the problem on ember-twiddle but for some reason it won't run as it does on my project, it seems that ember-twiddle does not read the actions declared on the route. However here is the example:
Example on ember-twiddle
Case 1
In this case I got an error:
Uncaught TypeError: Cannot read property 'apply' of undefined
Template:
{{#each model.items as |item|}}
<select class="form-control" onchange={{action 'ChangeCombo' item "Price" value='target.value'}}>
<option value="">Select an option</option>
<option value="1000">$1000</option>
<option value="100">$100</option>
<option value="10">$10</option>
</select>
{{/each}}
Route Actions:
actions: {
ChangeCombo(paramOne, paramTwo, paramThree) {
console.info(paramOne, paramTwo, paramThree);
},
}
Case 2
In this case the first parameter is the current Item from de model array, the second one is the string "Price" but the third parameter is undefined and the last parameter which is supposed to be the event object is also undefined.
Console output:
{object}, "Price", undefined, undefined
Template:
{{#each model.items as |item|}}
<select class="form-control" {{action 'ChangeCombo' item "Price" value='target.value' on='change'}}>
<option value="">Select an option</option>
<option value="1000">$1000</option>
<option value="100">$100</option>
<option value="10">$10</option>
</select>
{{/each}}
Route Actions:
actions: {
ChangeCombo(paramOne, paramTwo, paramThree, paramFour) {
console.info(paramOne, paramTwo, paramThree, paramFour);
},
}
Ember version
ember-cli: 3.7.1
node: 10.1.0
os: win32 x64
If you wan't to use the action value option, you can't have any other params directly in the action helper.
You need to use closure actions, i.e.
<select class="form-control" onchange={{action (action 'ChangeCombo' item "Price") value='target.value'}}>
<option value="">Select an option</option>
<option value="1000">$1000</option>
<option value="100">$100</option>
<option value="10">$10</option>
</select>

Javascript - return selected value of a select MVC6 taghelper element using a function

I am using ASP.NET core MVC6 so I'm using a select taghelper for the dropdown. This all works and I have a dropdown with states. As can be seen below there is a selected state.
In Javascript I wanted to get the selected value of this dropdown. I tried each of these:
var getSelectedState1 = function () {
return $State.val;
};
var getSelectedState2 = function () {
return $("#State").val;
};
..and both returned empty strings.
As "State" is the element ID of the state select element which I've identified both from Dave Paquette's blog and also from the page source...
<div class="form-group">
<label class="col-md-2 control-label" for="State">State:</label>
<div class="col-md-10">
<select class="form-control" data-val="true" data-val-required="A State name is required" id="State" name="State"><option value="NSW">New South Wales</option>
<option selected="selected" value="VIC">Victoria</option>
<option value="QLD">Queensland</option>
<option value="SA">South Australia</option>
<option value="WA">Western Australia</option>
<option value="TAS">Tasmania</option>
<option value="NT">Nothern Territory</option>
<option value="ACT">Australian Captial Territory</option>
</select>
<span class="text-danger field-validation-valid" data-valmsg-for="State" data-valmsg-replace="true" />
</div>
eg id="State".
Using a breakpoint and checking the value of "getSelectedState" I get an empty return for both attempts.
How do I populate a variable "getSelectedState" with the selected value of the dropdown using a function?
Note: Whilst this is aimed at Javascript people the problem might be in relation to the fact that its an MVC6 Taghelper element and I'm not accessing it correctly - this might be why its returning "" and not the javascript.

Passing an ng-model value to an object

I have a list made with ng-repeat with options. I'm trying to make it so that when I click an option, the value of the selection will be passed to an object.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" >
<option value="1" ng-repeat="t in klas" ng-model="vakselect">{{ t.Name }}</option>
</select>
$scope.user = {
vak: klas.vakselect,
};
I have small experience with Angular, so I'm not sure how to make it work correctly.
Edit:
I have adjusted my code and user.vak does seem to catch the selectvak field, but now passes it as an array. How do I make it so it's a string in $scope.user? So whenever I log user, I will see a string of vak and then an array of students.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" ng-model="user.vak" ng-options="t.Name as t.Name for t in klas" ng-click="getJSON1()">
$scope.user = {
vak: '',
// klas: klasselect,
student: [$scope.student] -1
};
TLJ and Arnaud are correct.
But answering your initial question, in the select tag, instead of ng-model="vakselect" just use ng-model="user.vak".
Then, when the value of the select changes, the value of user.vak will change automatically.
real code is this : (and nothing to do inside the controller.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" ng-model="user.vak">
<option value="1" ng-repeat="t in klas">{{ t.Name }}</option>
</select>
And you should use ng-options instead of ng-repeat to create your options
https://docs.angularjs.org/api/ng/directive/ngOptions
This will add t.name to an array when you click the option. Take a look at the controller function and the ng-click in the partial.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" >
<option value="1" ng-repeat="t in klas" ng-click="add(t.Name)" ng-model="vakselect">{{ t.Name }}</option>
</select>
var string_option;
$scope.add = function(t) {
string_option = t;
console.log(string_option )
}

Categories