Default option in <select> not showing - javascript

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.

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.

How to create dynamic two relational dropdown in Vuejs

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

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.

Input type[file] doesnot display the name of the file. Angularjs

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)" />

Cant get Select Box to update dynamically with angular.js

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>

Categories