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.
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
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.
I am new to angularjs. The project is getting transitioned from jquery to angular. Initially, it was a nightmare with all the new terms and scarry topics. I am getting used to it now and actually enjoying working on angular.
I am stuck at one part and i hope someone could help me or suggest me here. Please refer to the jsfiddle.
http://jsfiddle.net/ash12/kk1s3a1d/12/
Here is th HTML code....
<div ng-controller="ListController"><br>
File:
Name:
City:<br/>
<input type='file' ng-model="activeItem.name">
<select name="singleSelect" ng-model="activeItem.content">
<option value="" disabled="" selected="" style="display:none;">Select Name</option>
<option>Rob</option>
<option>Dilan</option>
</select>
<select name="singleSelect1" ng-model="activeItem.content1">
<option value="" disabled="" selected="" style="display:none;">Select City</option>
<option>China</option>
<option>Korea</option>
<option>United States</option>
</select>
<button ng-click="addItem()">+</button><br>
<ul>
<li ng-repeat="item in items"> <a>{{item.name}}</a><a>{{item.content}}</a>
<a>{{item.content1}}</a>
</li>
</ul>
</div>
Here is the controller function...
function ListController($scope) {
$scope.items = [{
}];
$scope.activeItem = {
name: '',
content: '',
content1:''
}
$scope.addItem = function () {
$scope.items.push($scope.activeItem);
$scope.activeItem = {} /* reset active item*/
}
}
Here, if i select the file name, name and city and then press on add button. It shows the list below. The problem is that it doesnot show the file which we have selected.
Can someone please tell me what to do in this case ? Also, i need the click button to be active only for 6 times. after adding the 6th time, it should not let me add any further. can someone suggest here ??
You need to do that by handling the onchange event of the file input
<input type='file' onchange="angular.element(this).scope().fileNameChanged(this)">
and In your controller
$scope.fileNameChanged = function(el){
$scope.activeItem.name = el.files[0].name
}
To disable your add button, in your additem check for the length of your items array and disable the button using ng-disabled
See the updated fiddle here : http://jsfiddle.net/kk1s3a1d/15/
here is the working jsfiddle of your problem
http://jsfiddle.net/adiioo7/fA968/
you need to use onchange as mentioned below as ng-model and ng-change doesnt work with input type="file"
<input type="file" ng-model="image" onchange="angular.element(this).scope().uploadImage(event)" />
I am currently learning angularJS and so far so good, but I'm having a problem that I cant seem to figure out.
I have 2 select boxes, one with top level categories in it, and a second one for sub-categories which is supposed to dynamically update when a change is made to the first select.
The first select box is populating fine, but despite the values being set for the second binding array by the event function I developed, the view never updates the second select box with the new values. I'm not sure what I'm doing wrong, and have tried a bunch of things but with no luck.
Here is what I've got:
var themebucketApp = angular.module('themebucketApp',[]);
//category list controller
themebucketApp.controller('CategoriesOptions',function($scope) {
$scope.thememap = {"wordpress":[{"category":"Activism"},{"category":"Art"},{"category":"Blog \/ Magazine"},{"category":"BuddyPress"},{"category":"Business"},{"category":"Cart66"},{"category":"Charity"},{"category":"Children"},{"category":"Churches"},{"category":"Computer"},{"category":"Corporate"},{"category":"Creative"},{"category":"eCommerce"},{"category":"Entertainment"},{"category":"Environmental"},{"category":"Events"},{"category":"Experimental"},{"category":"Fashion"},{"category":"Film & TV"},{"category":"Food"},{"category":"Government"},{"category":"Health & Beauty"},{"category":"Hosting"},{"category":"Jigoshop"},{"category":"Marketing"},{"category":"Miscellaneous"},{"category":"Mobile"},{"category":"Music and Bands"},{"category":"News \/ Editorial"},{"category":"Nightlife"},{"category":"Nonprofit"},{"category":"Personal"},{"category":"Photography"},{"category":"Political"},{"category":"Portfolio"},{"category":"Restaurants & Cafes"},{"category":"Retail"},{"category":"Shopping"},{"category":"Software"},{"category":"Technology"},{"category":"Travel"},{"category":"Wedding"},{"category":"WooCommerce"},{"category":"WordPress"},{"category":"WP e-Commerce"}],"magento":[{"category":"Entertainment"},{"category":"Fashion"},{"category":"Health & Beauty"},{"category":"Magento"},{"category":"Miscellaneous"},{"category":"Shopping"},{"category":"Technology"}],"designs":[{"category":"404 Pages"},{"category":"Activism"},{"category":"Admin Templates"},{"category":"Art"},{"category":"Business"},{"category":"Charity"},{"category":"Children"},{"category":"Churches"},{"category":"Computer"},{"category":"Corporate"},{"category":"Creative"},{"category":"Electronics"},{"category":"Entertainment"},{"category":"Environmental"},{"category":"Events"},{"category":"Experimental"},{"category":"Fashion"},{"category":"Film & TV"},{"category":"Food"},{"category":"Government"},{"category":"Health & Beauty"},{"category":"Hosting"},{"category":"Marketing"},{"category":"Miscellaneous"},{"category":"Mobile"},{"category":"Music and Bands"},{"category":"Nightlife"},{"category":"Nonprofit"},{"category":"Personal"},{"category":"Photo Gallery"},{"category":"Photography"},{"category":"Political"},{"category":"Portfolio"},{"category":"Restaurants & Cafes"},{"category":"Resume \/ CV"},{"category":"Retail"},{"category":"Shopping"},{"category":"Site Templates"},{"category":"Social Media Home"},{"category":"Software"},{"category":"Specialty Pages"},{"category":"Technology"},{"category":"Travel"},{"category":"Under Construction"},{"category":"Virtual Business Card"},{"category":"Wedding"}],"opencart":[{"category":"Entertainment"},{"category":"Fashion"},{"category":"Miscellaneous"},{"category":"OpenCart"},{"category":"Shopping"},{"category":"Technology"}]};
$scope.categories = [{'name' : 'WordPress', 'value' : 'wordpress'},{'name' : 'Magento', 'value' : 'magento'},{'name' : 'OpenCart', 'value' : 'opencart'},{'name' : 'Designs', 'value' : 'designs'}];
$scope.subcategories = [];
$scope.loadSubcategories = function(){
$scope.subcategories = $scope.thememap[$('#theme-type').val()];
};
});
...
<div class="navbar-text pull-right" style="margin-top:10px;">
<select id="theme-type" name="themetype" ng-controller="CategoriesOptions" ng-click="loadSubcategories();">
<option value="">Theme Type</option>
<option ng-repeat='category in categories' value="{{category.value}}">{{category.name}}</option>
</select>
<select id="theme-cat" name="themecat" ng-controller='CategoriesOptions'>
<option value="All">All</option>
<option ng-repeat='subcategory in subcategories' value='{{subcategory.category}}'>{{subcategory.category}}</option>
</select>
</div>
Can anyone show me what I'm doing wrong or what I'm missing?
There are several issues:
One: ng-controller="CategoriesOptions" should be declared only once and not one per control Like this:
<div class="navbar-text pull-right" style="margin-top:10px;" ng-controller="CategoriesOptions">
<select id="theme-type" name="themetype" ng-click="loadSubcategories();">
<option value="">Theme Type</option>
<option ng-repeat='category in categories' value="{{category.value}}">{{category.name}}</option>
</select>
<select id="theme-cat" name="themecat" >
<option value="All">All</option>
<option ng-repeat='subcategory in subcategories' value='{{subcategory.category}}'>{{subcategory.category}}</option>
</select>
Two for selects it better to use ng-options and ng-model:
http://docs.angularjs.org/api/ng.directive:select
About:
ng-model="{string}"
It is what associates the selected value of the control with your model.
About:
[ng-options="{comprehension_expression}"]
it works something like this:
<select ng-model="mySelectedValue" ng-options="c.name for c in categories"></select>