How to get HTML 5 data-* values in Vue.js? - javascript

Assume I have this :
<select class="form-control" name="gateway">
<option data-type="typeA" value="1">Test String</option>
<option data-type="typeB" value="2">Test String</option>
<option data-type="typeC" value="3">Test String</option>
</select>
<span>#{{ typeMapper(data-type) }}</span>
Here is my Vue.js script :
const app = new Vue({
el: '#vue-app',
data: {},
methods: {
typeMapper: function (type) {
var array = {
'typeA':'You selected Type A',
'typeB':'You selected Type B',
'typeC':'You selected Type C',
};
return array[type];
}
}
});
Now how can I get data-type values in Vue.js ?
I want to pass selected option data-type value to Vue.js typeMapper method and show the result in the span tag.
I don't know how to pass data-type value to Vue.js !
P.S:
I'm using Vue.js 2

Your data isn't a true javascript array so I used the Object.keys function to grab the key names. Here's a quick way of doing what you're looking for:
<div id="app">
<select class="form-control" name="gateway">
<option v-for="(key,index) in Object.keys(array)" :value="index+1" :data-type="key">
{{ array[key]}}
</option>
</select>
</div>
And the Vue code:
new Vue({
el: '#app',
data: {
array: {
'typeA': 'You selected Type A',
'typeB': 'You selected Type B',
'typeC': 'You selected Type C',
}
}
});
Here's a working fiddle.

I have no clue as to why you'd want to gather data sets from a given html5 structure. Since you'd usually want to get that trough ajax calls or set the select options trough some other component or whatever.
If you however want to get the elements given from a html structure you'd do something like this.
codepen
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>
<div id="vue-app">
<select class="form-control" v-on:change="typeMapper">
<option data-type="" value="">Select Type</option>
<option data-type="typeA" value="1">typeA</option>
<option data-type="typeB" value="2">typeB</option>
<option data-type="typeC" value="3">typeC</option>
</select>
<span>{{ gateway }}</span>
</div>
JS
const app = new Vue({
el: '#vue-app',
data: {
gateway: "",
},
methods: {
typeMapper: function (event) {
this.gateway = event.target[event.target.value].dataset.type;
}
}
});
This is by far from optimal or a cross browser variant. If I were you I'd scrap this approach.

Related

How to reset a form field conditionally when another one changes using vue.js

I have two form fields retrieval-method and source-url, where the later depends on the value of the former. Specifically the text box source-url should be disabled for particular values of retrieval-method. I can achieve this fairly simply as follows:
https://jsfiddle.net/o5mzhg3y/
<div id="app">
<select name="retrieval-method" v-model="retrieval_method">
<option value="">Choose a method</option>
<option value="1">Upload</option>
<option value="2">Download (Periodic)</option>
<option value="3">Download (API Triggered)</option>
</select>
<input type="text" name="source-url" :disabled="!(retrieval_method>1)">
</div>
<script>
new Vue({
el: '#app',
data: {
retrieval_method: false,
source_url: ''
}
})
</script>
However I would like to be able to also reset the fields value to an empty string when the retrieval method changes to something that causes the input to be disabled. But I can't wrap my mind around how to do this. Perhaps I need to implement a method?
Ideally the value would not be forgotten so that if the user changes retrieval-method back to a value that requires a source url the value is reinserted into the text input.
Well you need to do a few things. You can add a watcher to your retrieval_method property. Listen for changes when value changed you save your source_url into a backup field when disable condition is true. And in reverse you read back from your backup filed to your source_url. You should also change your input binding to a v-model binding in order to reflect changes.
new Vue({
el: '#app',
data: {
retrieval_method: false,
source_url: '',
backupUrl: ''
},
computed: {
disableUrl: function() {
return this.retrieval_method <= 1;
}
},
watch: {
// whenever question changes, this function will run
retrieval_method: function(newValue, oldValue) {
if (newValue <= 1) {
this.backupUrl = this.source_url;
this.source_url = '';
} else if (this.backupUrl) {
this.source_url = this.backupUrl;
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script>
<div id="app">
<select name="retrieval-method" v-model="retrieval_method">
<option value="">Choose a method</option>
<option value="1">Upload</option>
<option value="2">Download (Periodic)</option>
<option value="3">Dowload (API Triggered)</option>
</select>
<input type="text" v-model="source_url" :disabled="disableUrl" />
</div>
So I ended up figuring it out by binding a method to the change event
https://jsfiddle.net/o5mzhg3y/7/
<div id="app">
<select name="retrieval-method" v-model="retrieval_method" v-on:change="retrieval_method_changed">
<option value="">Choose a method</option>
<option value="1">Upload</option>
<option value="2">Download (Periodic)</option>
<option value="3">Dowload (API Triggered)</option>
</select>
<input type="text" name="source-url" :disabled="source_disabled" v-model="source_url">
</div>
<script>
new Vue({
el: '#app',
data: {
retrieval_method: '',
source_disabled: true,
source_url: '',
old_source_url: '',
},
methods: {
retrieval_method_changed: function (event) {
const old_source_disabled = this.source_disabled
this.source_disabled = !(this.retrieval_method>1)
if( old_source_disabled != this.source_disabled) {
if(this.source_disabled) {
this.old_source_url = this.source_url
this.source_url = ''
} else {
this.source_url = this.old_source_url
this.old_source_url = ''
}
}
}
}
})
</script>
I'm going to leave the question open though, in case someone comes up with a cleaner way to do what I wanted

Vue, get value and name of select option

I'm using html and laravel to build select box options in a foreach loop
This works and populates with ID as value and name as the option. What I want, and can't quite figure out here, is how to take my function when I call it and get the id and value as separate vue options for a post axios call I'm going to make.
So when I select the option and submit the form to call the function, how can I get the ID as one prop and the name as another?
<select>
#foreach($details as $detail)
<option value="{{$detail->id}}">{{$detail->name}}</option>
#endforeach
</select>
new Vue({
data: {
detailID: [''],
detailName: ['']
},
methods: {
let data = {
detailID: this.detailID,
detailName: this.detailName
};
}
})
Here is a code example just using vue.js
Template
<div id="app">
<select v-model="selectedDetailId">
<option v-for="detail in details" v-bind:value="detail.id">
{{ detail.name }}
</option>
</select>
</div>
Script
new Vue({
el: '#app',
data: {
selectedDetailId: null,
details: [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
{ id: 3, name: 'C' }
]
},
methods:{
post(){
//your selected Id is this.selectedDetailId
}
}
})
You can find more details and examples in the official Vue.js docs.
https://v2.vuejs.org/v2/guide/forms.html#Value-Bindings
Use v-model to bind the selection to your component data. SeeForm input bindings:
new Vue({
data: {
detailID: ""
},
// now you can access the id with this.detailID in your post request
})
<select v-model="detailID">
#foreach($details as $detail)
<option value="{{$detail->id}}">{{$detail->name}}</option>
#endforeach
</select>
And if you need both id and name, one work around could be:
new Vue({
data: {
detail: ""
},
// now you can access the id & name with this.detail.split(',') in your post request
})
<select v-model="detail">
#foreach($details as $detail)
<option value="{{$detail->id.','.$detail->name}}">{{$detail->name}}</option>
#endforeach
</select>
You would need to set a v-model to your select element and bind the entire object to each option element instead of just the id like you are doing in your example.
Here is a codepen with a simple example.

Variable in V-modal select box

I'm having an array of objects. I wanted to change value to the object property by a select box.
HTML
<div id="app">
{{ message }}<br><br>
<select v-modal="items[0].val">
<option value="newjs">New js</option>
<option value="vannilajs">Vannila js</option>
</select>
<br>
ITEM 0 = {{items[0].val }}
<br>
ITEM 1 = {{items[1].val }}
</div>
JS
new Vue({
el:'#app',
data: {
message: 'testing',
items: [{val:'VUE'},{val: 'REACT'}] //intial two items
}
});
When select box changes I wanted to change the value of ITEM 0 to Selected Value.
Just for testing purpose right now I'm trying to access 0th object from the array. This select box will be in v-for loop for multiple select box.
FIDDLE
You can't assign variables to objects and arrays that easily in Vue.js
<div id="app">
<select #input="change">
<option value="newjs">New js</option>
<option value="vannilajs">Vannila js</option>
</select>
</div>
<script>
new Vue({
el:'#app',
data:{
items:[{val:'VUE'},{val:'REACT'}]
},
methods: {
change(element) {
this.$set(this.items[0], 'val', element);
}
}
});
</script>
Vue can only migically refresh values changed by reference (message = 'hey'), or by object reference (object.message = 'hey') but only if that reference was in data() in create time.
new Vue({
data: {
object: {first:0},
array: [1,2,3]
},
methods: {
change() {
object.first = 2; // works
object.second = 3; // doesn't work
array[0] = 2; // works for 0,1,2
array[4] = 3; // doesn't work
}
}
For the object.second and array[3] you need to use $set().
Ok i misread your question. You do have a spelling mistake but you also need an intermediary variable to hold the value of the drop down
<div id="app">
{{ message }}<br><br>
<select v-model="selectedValue">
<option value="newjs">New js</option>
<option value="vannilajs">Vannila js</option>
</select>
<br>
ITEM 0 = {{selectedValue }}
<br>
ITEM 1 = {{items[1].val }}
</div>
new Vue({
el:'#app',
data: {
message: 'testing',
selectedValue: 'VUE',
items: [{val:'VUE'},{val: 'REACT'}] //intial two items
}
});

Vue.js dependent select

I'm in very beginning stage learning Vue.js and encountered problem I can't figure out right now. So I have 1 select field:
data: {
list: {
'Option 1': [ { size:'1',prize:'5' }, { size:'2',prize:'10' } ]
}
}
Then I populating first select field like this:
<select v-model="firstOptions" v-on:change="onChange">
<option v-for="(item, index) in list">{{ index }}</option>
</select>
At this point everything is fine, but how to populate another select field based on first select? I need to access size and price.
I'm think this should be done here:
methods: {
onChange: function() {
// get options for second select field
}
}
I'm assuming here in your data structure, list, that the value of each property defines the options you will use in the second select. The key here is the model for the first select drives the options for the second.
<option v-for="option in list[firstOption]" value="option.size">{{option.prize}}</option>
I'm not sure how exactly you want your text and values laid out in the first or second selects, but here is an example.
new Vue({
el:"#app",
data: {
firstOption: null,
secondOption: null,
list: {
'Option 1': [ { size:'1',prize:'5' }, { size:'2',prize:'10' } ],
'Option 2': [{size:'3', prize:'8'}]
}
}
})
and in your template
<div id="app">
<select v-model="firstOption">
<option v-for="(item, index) in list">{{ index }}</option>
</select>
<select v-model="secondOption" v-if="firstOption">
<option v-for="option in list[firstOption]" value="option.size">{{option.prize}}</option>
</select>
</div>
Example in codepen.

How to have a default option in Angular.js select box

I have searched Google and can't find anything on this.
I have this code.
<select ng-model="somethingHere"
ng-options="option.value as option.name for option in options"
></select>
With some data like this
options = [{
name: 'Something Cool',
value: 'something-cool-value'
}, {
name: 'Something Else',
value: 'something-else-value'
}];
And the output is something like this.
<select ng-model="somethingHere"
ng-options="option.value as option.name for option in options"
class="ng-pristine ng-valid">
<option value="?" selected="selected"></option>
<option value="0">Something Cool</option>
<option value="1">Something Else</option>
</select>
How is it possible to set the first option in the data as the default value so you would get a result like this.
<select ng-model="somethingHere" ....>
<option value="0" selected="selected">Something Cool</option>
<option value="1">Something Else</option>
</select>
You can simply use ng-init like this
<select ng-init="somethingHere = options[0]"
ng-model="somethingHere"
ng-options="option.name for option in options">
</select>
If you want to make sure your $scope.somethingHere value doesn't get overwritten when your view initializes, you'll want to coalesce (somethingHere = somethingHere || options[0].value) the value in your ng-init like so:
<select ng-model="somethingHere"
ng-init="somethingHere = somethingHere || options[0].value"
ng-options="option.value as option.name for option in options">
</select>
Try this:
HTML
<select
ng-model="selectedOption"
ng-options="option.name for option in options">
</select>
Javascript
function Ctrl($scope) {
$scope.options = [
{
name: 'Something Cool',
value: 'something-cool-value'
},
{
name: 'Something Else',
value: 'something-else-value'
}
];
$scope.selectedOption = $scope.options[0];
}
Plunker here.
If you really want to set the value that will be bound to the model, then change the ng-options attribute to
ng-options="option.value as option.name for option in options"
and the Javascript to
...
$scope.selectedOption = $scope.options[0].value;
Another Plunker here considering the above.
Only one answer by Srivathsa Harish Venkataramana mentioned track by which is indeed a solution for this!
Here is an example along with Plunker (link below) of how to use track by in select ng-options:
<select ng-model="selectedCity"
ng-options="city as city.name for city in cities track by city.id">
<option value="">-- Select City --</option>
</select>
If selectedCity is defined on angular scope, and it has id property with the same value as any id of any city on the cities list, it'll be auto selected on load.
Here is Plunker for this:
http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview
See source documentation for more details:
https://code.angularjs.org/1.3.15/docs/api/ng/directive/select
I think, after the inclusion of 'track by', you can use it in ng-options to get what you wanted, like the following
<select ng-model="somethingHere" ng-options="option.name for option in options track by option.value" ></select>
This way of doing it is better because when you want to replace the list of strings with list of objects you will just change this to
<select ng-model="somethingHere" ng-options="object.name for option in options track by object.id" ></select>
where somethingHere is an object with the properties name and id, of course. Please note, 'as' is not used in this way of expressing the ng-options, because it will only set the value and you will not be able to change it when you are using track by
The accepted answer use ng-init, but document says to avoid ng-init if possible.
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.
You also can use ng-repeat instead of ng-options for your options. With ng-repeat, you can use ng-selected with ng-repeat special properties. i.e. $index, $odd, $even to make this work without any coding.
$first is one of the ng-repeat special properties.
<select ng-model="foo">
<option ng-selected="$first" ng-repeat="(id,value) in myOptions" value="{{id}}">
{{value}}
</option>
</select>
---------------------- EDIT ----------------
Although this works, I would prefer #mik-t's answer when you know what value to select, https://stackoverflow.com/a/29564802/454252, which uses track-by and ng-options without using ng-init or ng-repeat.
This answer should only be used when you must select the first item without knowing what value to choose. e.g., I am using this for auto completion which requires to choose the FIRST item all the time.
My solution to this was use html to hardcode my default option. Like so:
In HAML:
%select{'ng-model' => 'province', 'ng-options' => "province as province for province in summary.provinces", 'chosen' => "chosen-select", 'data-placeholder' => "BC & ON"}
%option{:value => "", :selected => "selected"}
BC & ON
In HTML:
<select ng-model="province" ng-options="province as province for province in summary.provinces" chosen="chosen-select" data-placeholder="BC & ON">
<option value="" selected="selected">BC & ON</option>
</select>
I want my default option to return all values from my api, that's why I have a blank value. Also excuse my haml. I know this isn't directly an answer to the OP's question, but people find this on Google. Hope this helps someone else.
Use below code to populate selected option from your model.
<select id="roomForListing" ng-model="selectedRoom.roomName" >
<option ng-repeat="room in roomList" title="{{room.roomName}}" ng-selected="{{room.roomName == selectedRoom.roomName}}" value="{{room.roomName}}">{{room.roomName}}</option>
</select>
Depending on how many options you have, you could put your values in an array and auto-populate your options like this
<select ng-model="somethingHere.values" ng-options="values for values in [5,4,3,2,1]">
<option value="">Pick a Number</option>
</select>
In my case, I was need to insert a initial value only to tell to user to select an option, so, I do like the code below:
<select ...
<option value="" ng-selected="selected">Select one option</option>
</select>
When I tryed an option with the value != of an empty string (null) the option was substituted by angular, but, when put an option like that (with null value), the select apear with this option.
Sorry by my bad english and I hope that I help in something with this.
Using select with ngOptions and setting a default value:
See the ngOptions documentation for more ngOptions usage examples.
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
],
selectedOption: {id: '2', name: 'Option B'} //This sets the default value of the select in the ui
};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
<div ng-controller="ExampleController">
<form name="myForm">
<label for="mySelect">Make a choice:</label>
<select name="mySelect" id="mySelect"
ng-options="option.name for option in data.availableOptions track by option.id"
ng-model="data.selectedOption"></select>
</form>
<hr>
<tt>option = {{data.selectedOption}}</tt><br/>
</div>
plnkr.co
Official documentation about HTML SELECT element with angular data-binding.
Binding select to a non-string value via ngModel parsing / formatting:
(function(angular) {
'use strict';
angular.module('nonStringSelect', [])
.run(function($rootScope) {
$rootScope.model = { id: 2 };
})
.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
return '' + val;
});
}
};
});
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<body ng-app="nonStringSelect">
<select ng-model="model.id" convert-to-number>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{ model }}
</body>
plnkr.co
Other example:
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.availableOptions = [
{ name: 'Apple', value: 'apple' },
{ name: 'Banana', value: 'banana' },
{ name: 'Kiwi', value: 'kiwi' }
];
$scope.data = {selectedOption : $scope.availableOptions[1].value};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
<div ng-controller="ExampleController">
<form name="myForm">
<select ng-model="data.selectedOption" required ng-options="option.value as option.name for option in availableOptions"></select>
</form>
</div>
</body>
jsfiddle
This worked for me.
<select ng-model="somethingHere" ng-init="somethingHere='Cool'">
<option value="Cool">Something Cool</option>
<option value="Else">Something Else</option>
</select>
In response to Ben Lesh's answer, there should be this line
ng-init="somethingHere = somethingHere || options[0]"
instead of
ng-init="somethingHere = somethingHere || options[0].value"
That is,
<select ng-model="somethingHere"
ng-init="somethingHere = somethingHere || options[0]"
ng-options="option.name for option in options track by option.value">
</select>
In my case since the default varies from case to case in the form.
I add a custom attribute in the select tag.
<select setSeletected="{{data.value}}">
<option value="value1"> value1....
<option value="value2"> value2....
......
in the directives I created a script that checks the value and when angular fills it in sets the option with that value to selected.
.directive('setSelected', function(){
restrict: 'A',
link: (scope, element, attrs){
function setSel=(){
//test if the value is defined if not try again if so run the command
if (typeof attrs.setSelected=='undefined'){
window.setTimeout( function(){setSel()},300)
}else{
element.find('[value="'+attrs.setSelected+'"]').prop('selected',true);
}
}
}
setSel()
})
just translated this from coffescript on the fly at least the jist of it is correct if not the hole thing.
It's not the simplest way but get it done when the value varies
Simply use ng-selected="true" as follows:
<select ng-model="myModel">
<option value="a" ng-selected="true">A</option>
<option value="b">B</option>
</select>
This working for me
ng-selected="true"
I would set the model in the controller. Then the select will default to that value. Ex:
html:
<select ng-options="..." ng-model="selectedItem">
Angular controller (using resource):
myResource.items(function(items){
$scope.items=items;
if(items.length>0){
$scope.selectedItem= items[0];
//if you want the first. Could be from config whatever
}
});
If you are using ng-options to render you drop down than option having same value as of ng-modal is default selected.
Consider the example:
<select ng-options="list.key as list.name for list in lists track by list.id" ng-model="selectedItem">
So option having same value of list.key and selectedItem, is default selected.
I needed the default “Please Select” to be unselectable. I also needed to be able to conditionally set a default selected option.
I achieved this the following simplistic way:
JS code:
// Flip these 2 to test selected default or no default with default “Please Select” text
//$scope.defaultOption = 0;
$scope.defaultOption = { key: '3', value: 'Option 3' };
$scope.options = [
{ key: '1', value: 'Option 1' },
{ key: '2', value: 'Option 2' },
{ key: '3', value: 'Option 3' },
{ key: '4', value: 'Option 4' }
];
getOptions();
function getOptions(){
if ($scope.defaultOption != 0)
{ $scope.options.selectedOption = $scope.defaultOption; }
}
HTML:
<select name="OptionSelect" id="OptionSelect" ng-model="options.selectedOption" ng-options="item.value for item in options track by item.key">
<option value="" disabled selected style="display: none;"> -- Please Select -- </option>
</select>
<h1>You selected: {{options.selectedOption.key}}</h1>
I hope this helps someone else that has similar requirements.
The "Please Select" was accomplished through Joffrey Outtier's answer here.
If you have some thing instead of just init the date part, you can use ng-init() by declare it in your controller, and use it in the top of your HTML.
This function will work like a constructor for your controller, and you can initiate your variables there.
angular.module('myApp', [])
.controller('myController', ['$scope', ($scope) => {
$scope.allOptions = [
{ name: 'Apple', value: 'apple' },
{ name: 'Banana', value: 'banana' }
];
$scope.myInit = () => {
$scope.userSelected = 'apple'
// Other initiations can goes here..
}
}]);
<body ng-app="myApp">
<div ng-controller="myController" ng-init="init()">
<select ng-model="userSelected" ng-options="option.value as option.name for option in allOptions"></select>
</div>
</body>
<!--
Using following solution you can set initial
default value at controller as well as after change option selected value shown as default.
-->
<script type="text/javascript">
function myCtrl($scope)
{
//...
$scope.myModel=Initial Default Value; //set default value as required
//..
}
</script>
<select ng-model="myModel"
ng-init="myModel= myModel"
ng-options="option.value as option.name for option in options">
</select>
try this in your angular controller...
$somethingHere = {name: 'Something Cool'};
You can set a value, but you are using a complex type and the angular will search key/value to set in your view.
And, if does not work, try this :
ng-options="option.value as option.name for option in options track by option.name"
I think the easiest way is
ng-selected="$first"

Categories

Resources