So I have an AngularJS form with a select option to create an restaurant in my DB;
<div id="name-group" class="form-group" ng-init="getClasses();">
<div class="select-wrapper">
<label for="location">Resaurant Class</label>
<select name="class" ng-model="formData.class" ng-options="class.id as class.name for class in classes track by class.id">
<option value="">-- Select Class --</option>
</select>
</div>
</div>
From the above, I'm getting the classes and then listing them. Because I have track by class.id it means I can have a default option as it doesn't have a value. All good here.
Now to edit this restaurant, I retrieve it from the DB and it will have whatever class I have saved for it from the above form. This is the id of the restaurant class.
So restaurant.restaurant_class_id = class.id
Now when I retrieve the restaurant, using the code below I'm able to load the form and the restaurant class will be selected correctly;
<div id="name-group" class="form-group" ng-init="getClasses();">
<div class="select-wrapper">
<label for="location">Resaurant Class</label>
<select name="class" ng-model="restaurant.restaurant_class_id" ng-options="class.id as class.name for class in classes track by restaurant.restaurant_class_id">
<option value="">-- Select Class --</option>
</select>
</div>
</div>
Notice the track by restaurant.restaurant_class_id. This is the desired behaviour.. Load the form, load the restaurant, load the restaurant classes, and automatically set the corresponding restaurant class in the dropdown.
Now the problem is when I then want to select another restaurant class for the restaurant. This results in an undefined value.
If I remove track by restaurant.restaurant_class_id and replace it with track by class.id two things happen;
The restaurant class is not selected. So I end up with -- Select Class -- displayed which is the default
If I select a restaurant class from the drop down then the value is set correctly.
I'm using ng-inspector to check what value is being set on the $scope
So I guess my question is how can I select the correct restaurant class based on what is retrieved from DB and be able to change it without getting undefined value.
Any guidance from Angular gurus appreciated.
Yes. Db value automatically selected by model. Check whether u have another issue
Related
I have two fields.
Workshop | Participation Status
Workshop is a list of workshops that have been conducted. Whereas Participation Status Shows the Participant Status i.e Participated, Not-Participated, Guest Etc. For each Workshop there is a select box showing the possible participation status. The List of Workshop is dynamic.
So A typical row would be like
<input type="checkbox" v-model="workshop_attended">Workshop 1
<select v-model="participation_status">
<option value="P">Participant</option>
<option value="G">Guest</option>
<input type="checkbox" v-model="workshop_attended">Workshop 2
<select v-model="participation_status">
<option value="P">Participant</option>
<option value="G">Guest</option>
And So on.
In my Script I am using CDN btw.
<script>
var vm=new Vue({
el:'#app'
})
So if someone selects a workshop then they select their Participation Status. I want to store the Workshop and the status in a structure given below.
this.workshops.push({workshop:"Workshop 1", status:"P" }
However i am having problems going about it. Since all Select Boxes are bound to the same model, a change in one triggers a change in all. I want to add the info to workshops object as soon as a particular workshop is selected and participation status selected. I am having trouble going about it.
I am new to Vue and am using CDN without the Single Page Application stuff.
Thanks in Advance.
https://jsfiddle.net/zeenux/peL9acfh/7/#&togetherjs=0Qeqn23QRj
You said that you have a dynamic list of workshop.
Iterate on it then :
<div v-for="(workshop, index) in workshops" :key="index" >
<input type="checkbox" v-model="workshop.selected">
{{workshop.name}}
<select v-model="workshop.status">
<option value="P">Participant</option>
<option value="G">Guest</option>
</div>
Instead of using v-model for the checkbox, maybe you should bind a function to #input that push when true, and splice when false
I have two selects one for classes and another for teachers as follows,
<label for="">Select Class</label><br>
<select ng-model="currentClass" ng-options="class as class.name for class in classes" ng-change="listTeachers()">
<option value="">Select Class</option>
</select>
<label for="">Select Teacher</label><br>
<select ng-model="currentTeacher" ng-options="teacher as teacher.name for teacher in teachers" ng-change="showStudents()">
<option value="">Select Teacher</option>
</select>
My problem is, if choose class and then choose teacher it's fine, but after choosing teacher if again I choose another class then I want to set 2nd select a value as "select teacher", how to do it?
Also tell me, is there any way of setting default value instead of setting it through option tag?
in your controller on the listTeachers() function you need
to set the model on the value you desire, example:
vm.listTeachers = function() {
vm.currentTeacher = '';
... // rest of your code
}
so when ever you change your class it invokes listTeacher, and i will reset the value, hope this helps.
I've been dealing with this problem for a long time. I currently have a function called "add ()" that allows me to add items to an array that feeds a dropdown and text fields. Every time I add a new item to the array, I add it empty:
$scope.aAnimals.push({"animal": ""})
This causes a problem with the dropdown, since the value of "animal" is equal to ""
<Option style="display: none" value=""> Select an animal </option>
Then the item is not added. Both "animal" and the dropdown value of the first option are empty strings. If you add a value for "animal", other than "" here it would work and would be added to the dropdown.
What I can do? I want the generated text fields to be empty, and the dropdown adds the item.
<select class="form-control" ng-model='obj.animal' id='animal' name='animal'
ng-options="opt as opt.animal for opt in aAnimals track by opt.animal">
<option style="display:none" value="">Select an animal</option>
</select>
<div ng-repeat='item in aAnimals'>
<input type='text' value={{item.animal}} class='animal' />
</div>
$scope.obj = {}
$scope.aAnimals=[{ "animal": "cat"},{ "animal": "dog"}]
$scope.add=function(){
$scope.aAnimals.push({ "animal": ""})
}
http://plnkr.co/edit/PRDp3a1bDJKtRmGR9GMY?p=preview
Let me verify what you need.
When the user click on the Add button, a new empty text box will be create in the page and a new empty option will be create in the drop down. When the user change the value in the text box, the drop down option will change.
In this case your need to modify the code like this.
<select class="form-control" ng-model='obj.animal' id='animal' name='animal'
ng-options="opt as opt.animal for opt in aAnimals">
<option style="display:none" value="">Select an animal</option>
</select>
<div ng-repeat='item in aAnimals'>
<input type='text' class='animal' ng-model='item.animal' />
</div>
I removed track by opt.animal like Pankas said, and added ng-model='item.animal', also don't need value={{item.animal}} since we use AngularJS 2-way binding.
Your code is working perfectly, just remove display none in option
<option value="">Select an animal</option>
I seen you are using jquery in Save functionality. We have jqlite in built in angular. Please check below code for save.
var length = $scope.aAnimals.length;
$scope.aAnimals[length-1].animal =
angular.element(document).find('.animal').eq(length-1).val();
When a user logs in to my app, it loads the previous UI setup that they were using. To switch between interfaces there is a dropdown that lists all the options that specific user is authorized to use.
I would like the selected option in that list to reflect the previous UI when the page is loading but I'm having trouble coming up with how to set the selected <option>
Here is some example code:
//User object from DB
var user = {
username: admin,
previousUI: 'Build',
authorizedUI: [{title:'Default'}, {title:'Edit'}, {title:'Build'}]
}
html:
<form class="navbar-form">
<label>System: </label>
<select (change)="systemSelect($event.target.value)">
<option *ngFor="let system of user.authorizedUI" [value]="system.title">
{{system.title}}
</option>
</select>
</form>
In Angular2 how do I set the selected parameter on the option to reflect user.previousUI?
I tried adding this:
<option *ngFor="let system of user.authorizedUI" [value]="system.title" [selected]="system.title === user.previousUI">
But that didn't seem to do it.
One way would be
<select [ngModel]="user?.previousUI" (change)="systemSelect($event.target.value)">
Hey guys just been told that hide cannot be used cross browser for select element options.
So I am wondering how I can use disable for the following issue I am having.
This example is simplified, the actual code contains PHP loops and MySQL to display the options and content.
Okay so first of all I have these two select elements:
<select class="form-control select-box">
<option value="make-any">Make (Any)</option>
<option value="BMW">BMW</option>
<option value="Mercedes">Mercedes</option>
<option value="Volvo">Volvo</option>
</select>
<select class="form-control select-box-model">
<option value="make-any">Make (Any)</option>
<option value="C220">C220</option>
<option value="X1">X1</option>
<option value="X5">X5</option>
<option value="XC90">XC90</option>
</select>
I then have these list:
<div class="makes BMW X1">
<ul>
<li>BMW</li>
<li>X1</li>
</ul>
</div>
<div class="makes VOLVO XC90">
<ul>
<li>VOLVO</li>
<li>XC90</li>
</ul>
</div>
<div class="makes MERCEDES C220">
<ul>
<li>MERCEDES</li>
<li>C220</li>
</ul>
</div>
<div class="makes BMW X5">
<ul>
<li>BMW</li>
<li>X1</li>
</ul>
</div>
I am currently using this jQuery to hide the div with the class of 'makes' if the selected option doesn't match the div's class so for example 'BMW':
<script>
$(document).ready(function(){
$('.form-control').change(function(){
var make = $(this).val();
if(make != 'make-any'){
$('.makes').hide();
$('.'+make).show();
} else {
$('.makes').show();
}
});
});</script>
So as you can see I have a bit of a problem because the second select element with the class of "select-box-model" contains all of the models, I'd like to disable the options that aren't associated with the first select element option that has been selected.
For example the list containers contain the classes for the 'Make' and 'Model' of the each vehicle:
<div class="makes BMW X5">
So how can I disable the options that are not associated with that 'Make', for example if the user selects BMW for the first element I'd only like the 'Models' that are associated with the 'Make'.
Any examples would be great, thanks.
Well, I am not completely certain that I have understood your question.
But I am assuming that you mean that if you select a car brand from select one (form control) the available models should be enabled in select two select-box-model. Once selecting the model, the accurate div needs to be shown?
If that is what you're trying to do your markup is not the best structure to achieve that.
Never the less, I made an example using your mark up:
jQuery:
$('.select-box-model').prop('disabled',true);
$('.form-control').on('change',function(){
$('.select-box-model').prop('disabled',false);
if($(this).val() != 'make-any'){
$('.makes').hide();
//check if the models drop down is used
if($(this).hasClass('select-box-model')){
//get selected value
var value = $(this).val();
$('.'+ value).show();
return false;
}
//get selected value
var carBrand = $(this).val();
$('.select-box-model option').prop('disabled',true);
$('.'+ carBrand).find('li').each(function(){
if($.trim(carBrand) != $.trim($(this).text())){
$('.select-box-model option[value="'+ $(this).text() +'"]').attr("disabled", false);
}
});
}
});
Here's a fiddle of that: http://jsfiddle.net/z59v56ec/
A neater solution to achieve this is using ajax to populate the models of the car brand.
But if you really want to do it your way, then the following logic is easier.
Select one holds value of car brand
Select two holds value of car brand and the text is the model
Select one will enable the options in select two with the value of that car brand
On select a model in select two the accurate divs would be shown according to the option text.
On a sidenote, be careful with your references. VOLVO is not the same as Volvo.
Just in case I completely missed the point - sorry! :)
First, you are far better off creating multiple selects and toggling their display based upon your first select's selectedvalue. Then, you create multiple divs and toggle their display based on your second select's selectedvalue. That said, if you really want to attack this "dynamically", you're better off having two selects - and one unordered list - and clearing their contents and rewriting the html as you go:
<select class="form-control select-box" id="selectMake">
<option value="make-any">Make (Any)</option>
<option value="BMW">BMW</option>
<option value="Mercedes">Mercedes</option>
<option value="Volvo">Volvo</option>
</select>
<select class="form-control select-box-model" id="selectModel">
</select>
<ul id="ulCars">
</ul>
$("#selectMake").change(function(){
$("#selectModel").empty();
$("#ulCars").empty();
switch ($(this).val()){
case "BMW":
$("#selectModel").append("<option>X1</option>").val("X1");
$("#ulCars").append("<li>X1</li>");
break;
}
});
etc. etc., but you can easily clear lists and dropdowns - and then repopulate them. But like I said, I'd go with multiple divs and toggling their display.