How to dynamically add multiple select elements in Angular - angularjs

I have a select element and would like to allow the user to click an add button add additional select elements so that the user can continue to select additional items.
When I use the code below, the dropdown does not display and no additional select elements are added when I click the "Add" button.
Any suggestions on how to do this correctly?
Clarification: I want to add new dropdowns that always include the same items. So I want to add new select elements, not new items within a select element.
HTML:
<select ng-repeat="class in project.classes" class="form-control" id="class" name="class"
ng-model="editProject.project.class" ng-options="classid.class group by classid.code for classid in editProject.classids track by classid.class">
<option value="">--Select Class--</option>
</select>
<button ng-click="editProject.project.class.push({})">Add</button>
Controller:
var editProject = this;
editProject.project.class = [];
editProject.classids = [
{code: '1', class: 'Chemicals'},
{code: '2', class: 'Paints'},
// . . .
];

I create this for you, I hope this helps you.
<!DOCTYPE html>
<html ng-app="dynamicallySelect" ng-controller="ExampleController">
<head>
<title>My ParseApp site</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular.js"></script>
</head>
<body>
<div ng-repeat="select in selects">
<select name="{{select.name}}" ng-model="select.model" multiple>
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
<option value="option-3">Option 3</option>
</select>
multipleSelect[{{$index}}] = {{select.model}}
</div>
<button ng-click="addMultipleSelect()">add select</button>
<script>
angular.module('dynamicallySelect', [])
.controller('ExampleController', ['$scope',
function($scope) {
$scope.selects = [];
$scope.data = {
singleSelect: null,
multipleSelect: [],
option1: 'option-1'
};
$scope.addMultipleSelect = function() {
var newSelect = {
name: "multipleSelect",
model: "multipleSelectModel"
}
$scope.selects.push(newSelect);
}
$scope.forceUnknownOption = function() {
$scope.data.singleSelect = 'nonsense';
};
}
]);
</script>
</body>
</html>

Inside the <div> where you are using for multi select you can use ui-select2="multi" ng-model="editProject.project.class", then you can write the select model value what you want in your drop down inside that <div>.This will mostly workout.

Your directive is set up incorrectly.
<select ng-model="editProject.project.class">
<option ng-repeat="class in project.classes" value="{{class.code}}">{{option.class}}</option>
</select>
<button ng-click="project.classes.push({class: 'New Class'})">Add Select</button>

Related

Angular: Drop down won't populate

I have the following code in the main page of my angular app that refuses to populate:
<div ng-app="MyApp" ng-controller="MyController">
<select
class="form-control"
ng-model="selected"
ng-options="x.value for x.display in options"
>
</select>
</div>
<script>
var app = angular.module("MyApp", []);
app.controller("MyController", function($scope) {
$scope.options = [
{ value: "ADVISORY", display: "Advisory Conflict Check" },
{ value: "OTHER", display: "Other Conflict Check" }
];
$scope.selected = $scope.options[0];
});
</script>
Can you tell me where I'm going wrong? I'm new to Angular.
EDIT:
I now know the difference between angular and angular.js. :)
I got my code working with this HTML:
<select class="form-control" [(ngModel)]="conflictType" (ngModelChange)="updateConflictType($event)">
<option *ngFor="let option of conflictTypes"
[value]="option.Value">{{option.Display}}</option>
</select>
I was able to move my data to my "code-behind" for lack of a better term.
Looks like you're using AngularJS and have wrongly tagged the question with angular. Or at least that's what's evident from your syntax which is in AngularJS.
Keeping that in mind here's an answer that will help you achieve this both in AngularJS as well as in Angular:
In AngularJS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
</head>
<body>
<div ng-app="MyApp" ng-controller="MyController">
<select class="form-control" ng-model="selected" ng-options="x.value as x.display for x in options">
</select>
</div>
<script>
var app = angular.module("MyApp", []);
app.controller("MyController", function($scope) {
$scope.options = [{
value: "ADVISORY",
display: "Advisory Conflict Check"
},
{
value: "OTHER",
display: "Other Conflict Check"
}
];
$scope.selected = $scope.options[0];
});
</script>
</body>
</html>
There's an issue with your ng-options syntax. ng-options="x.value for x.display in options" should have been ng-options="x.value for x in options" or ng-options="x.value as x.display for x in options"
In Angular:
You can use the *ngFor syntax to repeat through the options you want to provide as select options. Here's how you Component Class would look like in that case:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
selected = 'ADVISORY';
options = [{
value: "ADVISORY",
display: "Advisory Conflict Check"
},
{
value: "OTHER",
display: "Other Conflict Check"
}
];
}
And in your Template:
<select [(ngModel)]="selected">
<option value="null" disabled>Select an option</option>
<option
*ngFor="let option of options"
[value]="option.value">
{{ option.display }}
</option>
</select>
Here's a Working Sample StackBlitz for your ref.
It should be ng-options="x.value as x.display for x in options" if you want the NgModel selected to contain the selected x.value. If you want the NgModel selected to contain the complete selected object then use ng-options="x as x.display for x in options"
Here's a working example
var app = angular.module("MyApp", []);
app.controller("MyController", function($scope) {
$scope.options = [
{ value: "ADVISORY", display: "Advisory Conflict Check" },
{ value: "OTHER", display: "Other Conflict Check" }
];
$scope.selected = $scope.options[0].value;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyController">
<select
class="form-control"
ng-model="selected"
ng-options="x.value as x.display for x in options">
</select>
</div>

Show filtered data with angular

I'm a very begginer in AngularJS(1.6) and I need to filter some results from a selected option.
I have to filter cities from states, and until there i'm doing fine. But then I need to filter and show the stores in this city on a list. Does anyone knows how to do It?
My code:
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
</head>
<body data-ng-controller="testController">
<select id="state" ng-model="stateSrc" ng-options="state for (state, city) in states" ng-change="GetSelectedState()">
<option value=''>State</option>
</select>
<select id="city" ng-model="citySrc" ng-options="city for (city,store) in stateSrc" ng-change="GetSelectedCity()" ng-disabled="!stateSrc">
<option value=''>City</option>
</select>
<select id="city" ng-model="store" ng-options="store for store in citySrc" ng-disabled="!stateSrc || !citySrc">
<option value=''>Store</option>
</select>
<script>
angular
.module('myApp', [])
.run(function($rootScope) {
$rootScope.title = 'myTest Page';
})
.controller('testController', ['$scope', function($scope) {
$scope.states = {
'STATE_1': {
'City_1': ['Store_1', 'Store_2'],
'City_2': ['Store_3', 'Store_4']
},
'STATE-2': {
'City_3': ['Store_1', 'Store_2'],
'City_4': ['Store_3', 'Store_4']
}
};
$scope.GetSelectedState = function() {
$scope.strState = $scope.stateSrc;
};
$scope.GetSelectedCity = function() {
$scope.strCity = $scope.citySrc;
};
}
])
</script>
</body>
</html>
Thank's a lot!
It would be really helpful if you posted what your data source looks like. Assuming citySrc has objects containing arrays of stores, I would set a selectedCity in your controller when you call GetSelectedCity(), and then:
<ul>
<li ng-repeat="store in selectedCity.store">{{store}}</li>
</ul>
This will create list items for each store in your selectedCity object.

How to write an attribute value along with ngModel

How to put some additional value with ngModel
If I have an html
<select ng-model="forms.options" data-custom-select="">
<option value="value1" data-special-value="reference1">Value 1</option>
<option value="value2" data-special-value="reference2">Value 2</option>
<option value="value3" data-special-value="reference3">Value 3</option>
</select>
and a custom directive "customSelect" with requires ngModel
I'm expecting a value on ngModel
{value:<Selected Value>,reference:<data-special-value>}
Is this really possible?
You can add the object directly into ng-options and get your result in the selected modal.
using ng-options:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="selectedName" ng-options="option.value for option in options" ng-change="selected(option.reference)">
</select><br>
Selected Value: {{selectedName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.options = [
{ value: 'value1', reference: 'reference1' },
{ value: 'value2', reference: 'reference2' },
{ value: 'value3', reference: 'reference3' },
]
});
</script>
<p>Select a value from dropdown.</p>
</body>
</html>
Please run the above snippet
HERE IS A WORKING DEMO

ng-options filter based on text input value

I have a select drop down in Angular based HTML like below. The requirement is to filter the drop down values based on the text the user enter in a text input box. The drop down value in this select is op
How do I add the filter.
<select class="form-control" size="12" data-ng-model="selItem.SelectedItems"
ng-options="option as displaycodeandlabel(option,selItem.isCodeonLabel)disable when option.disabled==true for option in ::a.sData"></select>
Not sure about your data structure, but generally you can just use the native filter.
Here's a working demo:
(function() {
angular
.module('app', [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope'];
function MainCtrl($scope) {
$scope.a = {};
$scope.a.sData = [
{
"vm":"0000",
"dm":"U.S. city average",
"disabled":false
},
{
"vm":"0100",
"dm":"Northeast urban",
"disabled":false
},
{
"vm":"0200",
"dm":"Midwest urban",
"disabled":false
}
];
$scope.displayCodeandLabel = function(item, displayCode) {
return displayCode ? item.vm + " " + item.dm : item.dm;
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body ng-controller="MainCtrl">
<div class="col-md-12">
<label for="search">Search</label>
<input type="text" id="search" class="form-control" placeholder="Search" ng-model="search">
<hr>
<select class="form-control" size="12" data-ng-model="selItem.SelectedItems" ng-options="option as displayCodeandLabel(option, selItem.isCodeonLabel)
disable when option.disabled == true for option in a.sData | filter: search"></select>
</div>
</body>
</html>

Get value when selected ng-option changes

I have in my .html page a dropdown list,
Dropdown:
<select ng-model="blisterPackTemplateSelected" data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
<option value="">Select Account</option>
</select>
I want to execute an action when the user select a value. So In my controller I did:
Controller:
$scope.$watch('blisterPackTemplateSelected', function() {
alert('changed');
console.log($scope.blisterPackTemplateSelected);
});
But the changing the value in the dropdownlist doesn't trigger the code : $scope.$watch('blisterPackTemplateSelected', function()
As a result I tried another method with a : ng_change = 'changedValue()' on the select tag
and
Function:
$scope.changedValue = function() {
console.log($scope.blisterPackTemplateSelected);
}
But the blisterPackTemplateSelected is stored into a child scope. I read that the parent can't get access to the child scope.
What is the correct/best way to execute something when a selected value in a dropdown list changes? If it's method 1, what am I doing wrong with my code?
as Artyom said you need to use ngChange and pass ngModel object as argument to your ngChange function
Example:
<div ng-app="App" >
<div ng-controller="ctrl">
<select ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)"
data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
<option value="">Select Account</option>
</select>
{{itemList}}
</div>
</div>
js:
function ctrl($scope) {
$scope.itemList = [];
$scope.blisterPackTemplates = [{id:1,name:"a"},{id:2,name:"b"},{id:3,name:"c"}];
$scope.changedValue = function(item) {
$scope.itemList.push(item.name);
}
}
Live example: http://jsfiddle.net/choroshin/9w5XT/4/
I may be late for this but I had somewhat the same problem.
I needed to pass both the id and the name into my model but all the orthodox solutions had me make code on the controller to handle the change.
I macgyvered my way out of it using a filter.
<select
ng-model="selected_id"
ng-options="o.id as o.name for o in options"
ng-change="selected_name=(options|filter:{id:selected_id})[0].name">
</select>
<script>
angular.module("app",[])
.controller("ctrl",['$scope',function($scope){
$scope.options = [
{id:1, name:'Starbuck'},
{id:2, name:'Appolo'},
{id:3, name:'Saul Tigh'},
{id:4, name:'Adama'}
]
}])
</script>
The "trick" is here:
ng-change="selected_name=(options|filter:{id:selected_id})[0].name"
I'm using the built-in filter to retrieve the correct name for the id
Here's a plunkr with a working demo.
Please, use for it ngChange directive.
For example:
<select ng-model="blisterPackTemplateSelected"
ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates"
ng-change="changeValue(blisterPackTemplateSelected)"/>
And pass your new model value in controller as a parameter:
ng-change="changeValue(blisterPackTemplateSelected)"
Best practise is to create an object (always use a . in ng-model)
In your controller:
var myObj: {
ngModelValue: null
};
and in your template:
<select
ng-model="myObj.ngModelValue"
ng-options="o.id as o.name for o in options">
</select>
Now you can just watch
myObj.ngModelValue
or you can use the ng-change directive like so:
<select
ng-model="myObj.ngModelValue"
ng-options="o.id as o.name for o in options"
ng-change="myChangeCallback()">
</select>
The egghead.io video "The Dot" has a really good overview, as does this very popular stack overflow question: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
You can pass the ng-model value through the ng-change function as a parameter:
<select
ng-model="blisterPackTemplateSelected"
data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates"
ng-change="changedValue(blisterPackTemplateSelected)">
<option value="">Select Account</option>
</select>
It's a bit difficult to know your scenario without seeing it, but this should work.
You can do something like this
<html ng-app="App" >
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
angular.module("App",[])
.controller("ctrl",['$scope',function($scope){
$scope.changedValue = function(item){
alert(item);
}
}]);
</script>
<div >
<div ng-controller="ctrl">
<select ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)" >
<option value="">Select Account</option>
<option value="Add">Add</option>
</select>
</div>
</div>
</html>
instead of add option you should use data-ng-options.I have used Add option for testing purpose
I am late here but I resolved same kind of problem in this way that is simple and easy.
<select ng-model="blisterPackTemplateSelected" ng-change="selectedBlisterPack(blisterPackTemplateSelected)">
<option value="">Select Account</option>
<option ng-repeat="blisterPacks in blisterPackTemplates" value="{{blisterPacks.id}}">{{blisterPacks.name}}</option>
and the function for ng-change is as follows;
$scope.selectedBlisterPack= function (value) {
console.log($scope.blisterPackTemplateSelected);
};
You will get selected option's value and text from list/array by using filter.
editobj.FlagName=(EmployeeStatus|filter:{Value:editobj.Flag})[0].KeyName
<select name="statusSelect"
id="statusSelect"
class="form-control"
ng-model="editobj.Flag"
ng-options="option.Value as option.KeyName for option in EmployeeStatus"
ng-change="editobj.FlagName=(EmployeeStatus|filter:{Value:editobj.Flag})[0].KeyName">
</select>
I had the same issue and found a unique solution. This is not best practice, but it may prove simple/helpful for someone. Just use jquery on the id or class or your select tag and you then have access to both the text and the value in the change function. In my case I'm passing in option values via sails/ejs:
<select id="projectSelector" class="form-control" ng-model="ticket.project.id" ng-change="projectChange(ticket)">
<% _.each(projects, function(project) { %>
<option value="<%= project.id %>"><%= project.title %></option>
<% }) %>
</select>
Then in my Angular controller my ng-change function looks like this:
$scope.projectChange = function($scope) {
$scope.project.title=$("#projectSelector option:selected").text();
};
I have tried some solutions,but here is basic production snippet. Please, pay attention to console output during quality assurance of this snippet.
Mark Up :
<!DOCTYPE html>
<html ng-app="appUp">
<head>
<title>
Angular Select snippet
</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
</head>
<body ng-controller="upController">
<div class="container">
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-3">
<div class="form-group">
<select name="slct" id="slct" class="form-control" ng-model="selBrand" ng-change="Changer(selBrand)" ng-options="brand as brand.name for brand in stock">
<option value="">
Select Brand
</option>
</select>
</div>
<div class="form-group">
<input type="hidden" name="delimiter" value=":" ng-model="delimiter" />
<input type="hidden" name="currency" value="$" ng-model="currency" />
<span>
{{selBrand.name}}{{delimiter}}{{selBrand.price}}{{currency}}
</span>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js">
</script>
<script src="js/ui-bootstrap-tpls-2.5.0.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Code:
var c = console;
var d = document;
var app = angular.module('appUp',[]).controller('upController',function($scope){
$scope.stock = [{
name:"Adidas",
price:420
},
{
name:"Nike",
price:327
},
{
name:"Clark",
price:725
}
];//data
$scope.Changer = function(){
if($scope.selBrand){
c.log("brand:"+$scope.selBrand.name+",price:"+$scope.selBrand.price);
$scope.currency = "$";
$scope.delimiter = ":";
}
else{
$scope.currency = "";
$scope.delimiter = "";
c.clear();
}
}; // onchange handler
});
Explanation:
important point here is null check of the changed value, i.e. if value is 'undefined' or 'null' we should to handle this situation.

Resources