I have a group of selects but want them all to work differently with v-model without creating separate data properties for them all.
In the example, select 1 and select 2 are one group and select 3 and select 4 are another.
When one select select 1, the expected behavior should be that, it does not affect select 2, etc.
My guess is may be a computed property for this? but can't get my head around the proper implementation
Js fiddle: https://jsfiddle.net/uxn501h2/8/
Code snippet:
new Vue({
el: '#app',
template: `
<div>
Select 1: <select v-model="selectedPerson">
<option v-for="person in people" :value="person.key">{{person.name}}</option>
</select>
Select 2: <select v-model="selectedPerson">
<option v-for="person in people" :value="person.key">{{person.name}}</option>
</select>
<h4>Selected 1 person key : {{selectedPerson}}</h4>
<h4>Selected 2 person key: {{selectedPerson}}</h4>
<br/>
Select 3: <select v-model="selectedPersonTwo">
<option v-for="person in people" :value="person.key">{{person.name}}</option>
</select>
Select 4: <select v-model="selectedPersonTwo">
<option v-for="person in people" :value="person.key">{{person.name}}</option>
</select>
<h4>Selected 3 person Two key: {{selectedPersonTwo}}</h4>
<h4>Selected 4 person Two key: {{selectedPersonTwo}}</h4>
</div>
`,
data: {
people: [{
key: 1,
name: "Carl"
},
{
key: 2,
name: "Carol"
},
{
key: 3,
name: "Clara"
},
{
key: 4,
name: "John"
},
{
key: 5,
name: "Jacob"
},
{
key: 6,
name: "Mark"
},
{
key: 7,
name: "Steve"
}
],
selectedPerson: "",
selectedPersonTwo: ""
}
});
.required-field > label::after {
content: '*';
color: red;
margin-left: 0.25rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<body>
<div id="app"></div>
</body>
It looks to me that you'd like to use two-way binding, but with more control between them in the middle. My suggestion would be:
Do not use <select v-model="selectedPerson">
Instead split them to <select :value="selectedPersonValue" #input="selectedPersonOutput> (which is basically the same thing, but you can specify different input and outputs), where selectedPersonValue can be a computed property or a regular property in data(), and selectedPersonOutput should be a method that will be called when select value changes.
This way you can directly decide what happens on each step.
PS: If you want to influence your property selectedPersonValue from a method, you might consider changing it to data() property and add a watch to it. See what works best for you.
Related
I have a json data that i've been loading into the <select>
This is a sample json data that I have:
let plans = [{id: 20, name: "test", default: 0},
{id: 19, name: "haha", default: 0},
{id: 18, name: "okok", default: 1}];
This is my select html/vue.
<select id="plans" class="form-control" v-model="company.plan_id">
<option v-for="plan in plans" :value="plan.id" :selected="plan.default">{{plan.name}}</option>
</select>
It seems it doesn't select the "okok" value even if the default is 1.
Those plans data are coming from my database which is loaded using ajax.
I'm new to VueJS, any help is greatly appreciated!
Thanks.
selected attribute no longer makes sense when you using v-model.
You can't use selected attribute if you are using v-model on the <select>, Set the v-model value to the default value instead:
<template>
<div id="app">
<select id="plans" class="form-control" v-model="company.plan_id">
<option v-for="plan in plans" :value="plan.id" :key="plan.id" :selected="plan.default">{{plan.name}}</option>
</select>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
company: {
plan_id: 18
},
plans: [
{ id: 20, name: "test" },
{ id: 19, name: "haha" },
{ id: 18, name: "okok" }
]
};
}
};
</script>
Demo here: https://codesandbox.io/s/beautiful-sound-gxmzu?file=/src/App.vue
When I try to show default selected value it doesn't show up i.e the option does not get selected in dropdown. The default value is coming from database and I'm setting that value in the model variable pageData.fields[content.id].keyFollowing is the sample JSON that I'm using to populate the dropdown:
$scope.dropdownFields = [{
groupName: 'PAGE',
isOptDisabled: false,
items: [{
name: 'PageName1',
type: 'page'
},
{
name: 'PageName2',
type: 'page'
},
{
name: 'PageName3',
type: 'page'
},
{
name: 'PageName4',
type: 'page'
}
]
},
{
groupName: 'COLOR',
isOptDisabled: false,
items: [{
name: 'COLOR1',
type: 'component'
},
{
name: 'COLOR2',
type: 'component'
},
{
name: 'COLOR3',
type: 'component'
}
]
},
{
groupName: 'OTHERS',
items: [{
name: 'Bold',
type: 'others',
isOptDisabled: false,
itemList: [{
name: 'Yes',
value: true
},
{
name: 'No',
value: false
}
]
},
{
name: 'Italic',
type: 'others',
isOptDisabled: false,
itemList: [{
name: 'Yes',
value: true
},
{
name: 'No',
value: false
}
]
}
]
}
];
<select id="{{content.id}}_filter" ng-model="pageData.fields[content.id].key" class="form-control" ng-change="onChangeFilter(pageData.fields[content.id].key, content.id)">
<option value="">[Select an option]</option>
<optgroup ng-repeat="header in dropdownFields" label="{{ header.groupName }}">
<option ng-repeat="item in header.items" value="{{ item.name }}" ng-disabled="isDisabled(header.groupName, item.name)">{{ item.name}}
</option>
</optgroup>
</select>
Is there any way to do this as I've researched a lot on this but the solutions were with ng-options and I cannot use ng-options for creating the dropdown due the disability functionality. The AngularJS version that I'm using is 1.2Any suggestion into the direction will be appreciated. Thanks.
EDIT: The code is successfully populating the dropdown and I'm able to get the value of selected option as well. But I'm not able to set an option by default into the dropdown. For eg. PageName3 is already selected in the dropdown.
EDIT2: So far now I'm able to show default value selected in this combobox on button click(here's the plnk) but I'm not able to set this value when I redirect from another page to this page.
So it goes like this, on this page(say PAGE1) I fill in these values there are multiple such dropdowns and textboxes in front of them for values, then I pass these values to the next page(say PAGE2); on PAGE2 I have a back button on the click of this button I return to PAGE1 with the same values passed before and I've to set all these values back as it were before. This is where I'm stuck! Not able to set selected values in dropdown while setting textboxes is done.
You can add default option into dropdown like so:
<input type="checkbox" ng-model="selected"></label><br/>
<select ng-model="item.name" ng-click="onChangeFilter(item.name)" class="form-control" >
<optgroup ng-repeat="header in dropdownFields" label="{{ header.groupName }}">
<option ng-selected="selected">Greetings!</option>
<option ng-repeat="item in header.items">{{item.name}}</option>
</optgroup>
</select>
plunker: http://plnkr.co/edit/vszVo3BHEA3T4yxGSUkA?p=preview
So I love Semantic UI and I just started working with Vue.js
Semantic UI dropdowns must be initialized using the dropdown() in semantic.js, it generates a complex div based HTML to show the dropdowns in a pretty way.
The problem comes when I bind Vue to a dropdown, it doesn't update the UI according to the model. Especially when I change the value of the parent dropdown.
For some reason the bidning works fine the first time an item is selected on the parent dropdown, but not after that :|
<div class="ui grid">
<div class="row">
<div class="column">
<div class="ui label">Vechicle Make</div>
<select class="ui dropdown" v-model="selected" id="vehicle-makes" v-on:change="onChange">
<option v-for="option in options" v-bind:value="option.id">
{{option.text}}
</option>
</select>
</div>
</div>
<div class="row">
<div class="column">
<div class="ui label">Vechicle Model</div>
<select class="ui dropdown" v-model="selected" id="vehicle-models">
<option v-for="option in options" v-bind:value="option.id">
{{option.text}}
</option>
</select>
</div>
</div>
</div>
var model_options = {
1: [{ text: "Accord", id: 1 }, { text: "Civic", id: 2 }],
2: [{ text: "Corolla", id: 3 }, { text: "Hi Ace", id: 4 }],
3: [{ text: "Altima", id: 5 }, { text: "Zuke", id: 6 }],
4: [{ text: "Alto", id: 7 }, { text: "Swift", id: 8 }]
};
var makes_options = [
{ text: "Honda", id: 1 },
{ text: "Toyota", id: 2 },
{ text: "Nissan", id: 3 },
{ text: "Suzuki", id: 4 }
];
var vm_makes = new Vue({
el: "#vehicle-makes",
data: {
selected: null,
options: makes_options
},
methods: {
onChange: function(event) {
vm_models.selected = null;
vm_models.options.splice(0);
for (index = 0; index < model_options[this.selected].length; index++) {
vm_models.options.push(model_options[this.selected][index]);
}
}
}
});
var vm_models = new Vue({
el: "#vehicle-models",
data: {
selected: null,
options: []
}
});
// Eveything works fine if I remove this...
$('.ui.dropdown').dropdown();
The exact code can be found here. https://codepen.io/adnanshussain/pen/KqVxXL?editors=1010
You are using a v-for directive on your option element without a key attribute. Without this key, Vue uses an "in-place patch" strategy to optimize rendering. This is most likely messing with what your Semantic UI dropdown is expecting as far as changes to the select element go.
Add a key attribute to your option tag, providing a unique id as the value:
<option v-for="option in options" :value="option.id" :key="option.id">
{{ option.text }}
</option>
To clear the value in the model's select element when the make changes, you can use $('#vehicle-models').dropdown('restore defaults').
Also, if you put all the logic in one Vue instance, things become a lot simpler: Here's an example codepen.
I'm a pretty new in this area (one mounth) and I'm developing application with angularJs, I'm getting back Json requisition with a list, I have to put the name ({{empresa.name }}) when the user select I get the ID({{empresa.IdEmpresa}}).
I want use ng-repeat for that, something like (ng-repeat="empresa in empresas").
I'm getting the Json with the list from the JavaController, my Entity is named Empresa, I declare a empty object on angular Like that ( $scope.empresas = {}) and give the callback to this emprty object, right?!
My select field is like that
<label>Empresa</label>
<select class="form-control">
<option value="{{empresa.EmpresaId}}">{{empresa.name}}</option>
</select>
how do I use repeat in this ?
Assuming your JSON data look like this
$scope.empresas = [
{ EmpresaId: 1, name: 'one' },
{ EmpresaId: 2, name: 'two' },
{ EmpresaId: 3, name: 'three' }
]
Apart from using ng-repeat on <options>, you can also utilise ng-options
<select ng-options="e.EmpresaId as e.name for e in empresas" ng-model="???"></select>
You can use ng-repeat="empresa in empresas" on the <option> tags.
Here's an example:
<select>
<option ng-repeat="empresa in empresas" value="{{empresa.EmpresaId}}">{{empresa.name}}</option>
</select>
Controller Code
$scope.empresas = [
{ EmpresaId: 101, name: 'India' },
{ EmpresaId: 102, name: 'US' },
{ EmpresaId: 103, name: 'UK' }
];
http://jsfiddle.net/WcJbu/
When I select a person, I want the favoriteThing selector to display their current selection.
<div ng-controller='MyController'>
<select ng-model='data.selectedPerson' ng-options='person.name for person in data.people'></select>
<span ...> likes </span>
<select ... ng-model='data.favoriteThing' ng-options='thing.name for thing in data.things'></select>
</div>
$scope.data.people = [{
name: 'Tom',
id: 1,
favorite_thing_id: 1
}, {
name: 'Jill',
id: 2,
favorite_thing_id: 3
}];
$scope.data.things = [{
name: 'Snails',
id: 1
}, {
name: 'Puppies',
id: 2
}, {
name: 'Flowers',
id: 3
}];
Do I need to set up a service and add watches, or is there a [good] way to use the favorite_thing_id directly in the select?
Change the second select to this:
<select ng-show='data.selectedPerson' ng-model='data.selectedPerson.favorite_thing_id'
ng-options='thing.id as thing.name for thing in data.things'></select>
Adding the thing.id as to the ng-options will allow you to select the data.things entries based on their id's instead of their references. Changing the ng-model to data.selectedPerson.favorite_thing_id will make angular automatically change to the correct option based on selectedPerson.favorite_thing_id.
jsfiddle: http://jsfiddle.net/bmleite/4Qf63/
http://jsfiddle.net/4Qf63/2/ does what I want - but it's pretty unsatisfying.
$scope.$watch(function() {
return $scope.data.selectedPerson;
}, function(newValue) {
if (newValue) {
$scope.data.thing = $filter('filter')($scope.data.things, {id: newValue.favorite_thing_id})[0];
}
})
I'd like to see all of that be possible from within the select statement.
Maybe I'll try to write a directive.
association = {key: matchValue}
So that I can do
<select ... ng-model='data.thing' ng-options='t.name for t in data.things' association='{id: "data.selectedPerson.favorite_thing_id"}'></select>