I have an array of objects that looks like
$scope.pArray = [{id: 0, name: 'bob'}, {id: 1, name: 'jen'}];
In my select dropdown, Im using ng-options instead of ng-repeat like so:
<select id="province" name="item" ng-model="obj.name" required
ng-options="item.id as prov.name for item in pArray track by item.id"></select>
Now when I hit the submit button, the value of obj.name is an object instead of the integer (0 or 1). How can I change this so that instead of the object, I get the id?
You can try this,
<select ng-model="selected" ng-options="emp.name for emp in pArray ">
</select>
DEMO
var app = angular.module('todoApp', []);
app.controller("dobController", ["$scope",
function($scope) {
$scope.pArray = [{id: 0, name: 'bob'}, {id: 1, name: 'jen'}];
$scope.getselected = function(selected) {
alert(selected.id)
}
}
]);
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>To Do List</title>
<link href="skeleton.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="MainViewController.js"></script>
</head>
<body ng-controller="dobController">
<div class="col-md-20">
<div id="main">
<form class="form-horizontal" role="form">
<label class="control-label col-md-2">Filter List:</label>
<div class="col-md-5">
<select ng-model="selected" ng-options="emp.name for emp in pArray ">
</select>
</div>
<button type="button" class="btn btn-primary" ng-click="getselected(selected)">selected</button>
</form>
</div>
</div>
</body>
</html>
Referring to the the angular docs:
https://docs.angularjs.org/api/ng/directive/ngOptions
You should try:
ng-options="item as item.name for item in pArray track by item.id"
You should try changing the "item.id as" to "item as" since you are using track by item.id. Also, did you mean "item.name" and not "prov.name"
Anyway, that's just quick and hopefully helpful place to start.
Related
Our task giving is that try to load images to the shopping application pick2get by using ng-src and make it look attractive.
For which we had written below code -
In HTML file as -
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-route.min.js"></script>
<script src="index.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="topnav">
<i>Check out</i>
<i>Sign In</i>
<b><i>Pick2get</i></b>
</div>
<br />
<div class="search_drop_down">
<select id="month" class="select select-styled">
<option value="hide">-- Brand --</option>
<option ng-repeat="pdtBrand in products">{{pdtBrand.brand}}</option>
</select>
<select id="year" class="select select-styled">
<option value="hide">-- Price --</option>
<option value="low_price_to_high">Low Price to High</option>
<option value="hign_price_to_low">High Price to Low</option>
</select>
<input class="search" placeholder="Search" size="40" type="text">
</div>
<div class="product_box" ng-repeat="pdt in products">
<div class="single_1">
<div class="container">
<div class="discount">
<div class="discount_badge">{{pdt.discount}}</div>
<span class="discount_text">Discount</span>
</div><img ng-src={{pdt.image}}></div></div>
<div class="single_2">
<div class="prod_desc">
<span class="pdt_name">{{pdt.name}}</span>
<div class="pdt_details_2_col">
<span class="brand">Brand</span>
<span class="brand_name">{{pdt.brand}}</span>
</div>
<div class="pdt_details_2_col">
<span class="brand">Price</span>
<span class="brand_name">{{pdt.price}}</span>
</div>
</div>
</div>
<div class="single_3">
<div class="quantity_sec">
<label>Quantity</label>
<br>
<input placeholder="Quantity" type="number" ng-model="pdt.quantity">
</div>
</div>
<div class="single_4">
<input type="image" src="img/greyCart.png" alt="Submit" width="48" height="48"
ng-show="pdt.quantity<1?true:false" />
<input type="image" src="img/orangeCart.png" alt="Submit" width="48" height="48"
ng-hide="pdt.quantity<1?true:false" ng-click="addToCart();" />
</div>
</div>
</body>
</html>
In Index JS as
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.quantity=0;
//Add image property to the products and the image should have the url of images
var imgPath = 'img/cycle.jpg'
$scope.products = [
{
name : "Happy Cycle",
discount:"20%",
price: "2500",
brand : "Wheels",
addedToCart:false,
quantity:0
},
{
name : "Kids Shoes",
discount:"10%",
price: "1460",
brand : "Feel Good",
addedToCart:false,
quantity:0
},
{
name : "Polo Baby Care Dress",
discount:"20%",
price: "2500",
brand : "Super Hero",
addedToCart:false,
quantity:0
},
]
$scope.addToCart=function(){
alert('Product Added to Cart successfully')
return "success";
}
});
Getting error as -
Node.js (linux; U; rv:v8.15.1): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
1A[2KNode.js (linux; U; rv:v8.15.1) AngularJS Test Controller should exist product image FAILED
Expected undefined to equal 'img/cycle.jpg'.at UserContext.<anonymous (test/index_test.js:13:42)
Node.js (linux; U; rv:v8.15.1): Executed 1 of 1 (1 FAILED)
Please suggest where we went wrong
Product array doesnt have the image key .. it per the html code it should be part of the array
Please add this image file in the array like you have added price other fields..
I want to uncheck all checkboxes when press some button. I need to do this on AngularJS (no jQuery). My checkboxes don't have ng-model attribute. How I can uncheck them?
My HTML structure:
<li ng-repeat="channel in channelsList">
<div class="checkbox">
<label><input type="checkbox" value="" ng-click="isChecked(channel.id)">
<img src="images/checkbox-unchecked.png" alt="" class="unchecked">
<img src="images/checkbox.png" alt="" class="checked"><span>{{channel.name}}</span>
</label>
</div>
</li>
My channelsList is only an array of objects with 2 properties: id and name.
Thanks for helping!
Two ng-ifs
If you really want to avoid ng-model you could achieve the same effect with... notice the checked attribute
<li ng-repeat="channel in channelsList">
<div class="checkbox">
<label>
<input ng-if="isChecked(channel.id);" type="checkbox" checked ng-click="check(channel.id);">
<input ng-if="!isChecked(channel.id);" type="checkbox" ng-click="check(channel.id);">
<img src="images/checkbox-unchecked.png" alt="" class="unchecked">
<img src="images/checkbox.png" alt="" class="checked"><span>{{channel.name}}</span>
</label>
</div>
</li>
Bind checkbox ng-model to a _selected property.
Please note that I use _selected and not selected in case your API would in a near future return a selected property that would collide with this one.
index.html
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="SampleController">
<ul>
<li ng-repeat="channel in channelsList">
<input type="checkbox" ng-model="channel._selected" /> {{channel.name}} (id={{channel.id}})
</li>
</ul>
<button ng-click="uncheckAll()">Uncheck all</button>
</body>
</html>
script.js
angular.module('app', []);
angular.module('app').controller('SampleController', function ($scope) {
$scope.channelsList = [
{id: 'c1', name: 'CNN'},
{id: 'c2', name: 'BBC'},
{id: 'c3', name: 'Discovery Channel'}
];
$scope.uncheckAll = function() {
angular.forEach($scope.channelsList, function (channel) {
channel._selected = false;
});
};
});
Here is the plunker : http://plnkr.co/edit/VPOjKMUVyrMpPfT9jLz3
I don't know exactly what you need but supposing you have an array of ids telling the ids checked like this:
$scope.channelsList = [
{'id' : 1, 'name' : 'foo' },
{'id' : 2, 'name' : 'bar' },
{'id' : 3, 'name' : 'foo' }
];
var checked = [1, 3]
$scope.isChecked = function(id){
return checked.indexOf(id) >= 0;
};
You can put a button like:
<button ng-click="uncheckAll()">click</button>
And use it to clear your array:
$scope.uncheckAll = function(){
checked = [];
}
I have the following code :-
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body ng-app="app" ng-controller="ctrl" ng-init="init()">
<div class="container" style="width:400px">
<div class="panel panel-default">
<div class="panel-body">
<form>
<div class="form-group">
<label for="selectedBasket">Select basket :</label>
<select id="selectedBasket" class="form-control" ng-model="selectedBasket" ng-options="b.name for b in baskets">
</select>
</div>
<div ng-repeat="f in fruits" class="checkbox">
<label>
<input type="checkbox" value="" ng-checked="selectedBasket !== null && selectedBasket.items.indexOf(f) !== -1">
{{ f }}
</label>
</div>
</form>
</div>
</div>
</div>
<script>
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.init = function() {
$scope.baskets = [{'name': 'mary', 'items': ['apple', 'orange']}, {'name': 'jane', 'items': ['banana']}];
$scope.fruits = ['apple', 'banana', 'cherry', 'orange', 'watermelon'];
$scope.selectedBasket = null;
};
});
</script>
</body>
</html>
if I select Mary or Jane, I can correctly see the correct items in their basket checked. However if I manually check all the fruits and then look at Mary or Jane, it doesn't exclude the items that are not in their baskets. Why is ng-checked failing?
Bonus question, is it best practise to set selectedBasket to null and checking for null in a directive assuming I want nothing as a default value, is there a better way?
You've got no ng-model in your checkbox so your manual action isn't registered anywhere.
ng-checked is only used to make a 'slave' checkbox it can take no manual action.
My guess is you should use a ng-model initialized to your ng-check value instead of using a ng-checked.
If you want to keep your ng-checked what you can do is :
<input type="checkbox" ng-click="selectedBasket.items.push(f)" ng-checked="selectedBasket !== null && selectedBasket.items.indexOf(f) !== -1">
in fact it's still wrong... must be tired, use a toogle function in your ng-click which add or remove the item should be better...
Had the same problem with ng-check, tried everything but nothing worked. I wanted to control the number of checked Items when clicked to 2, so I used the $Event sent with ng-click and disable it.
Here is a sample code:
<input type="checkbox" ng-click="toggleCheck($event, product._id);"
ng-checked="isChecked(product._id)">
$scope.toggleCheck($event, productId){
if ( $scope.featuredProducts.indexOf(productId) === -1) {
if ($scope.featuredProducts.length < 2) {
$scope.featuredProducts.push(productId);
}else {
$event.preventDefault();
$event.stopPropagation();
}
} else {
$scope.featuredProducts.splice( $scope.featuredProducts.indexOf(productId), 1);
}
}
$scope.isChecked(productId){
return ($scope.featuredProducts.indexOf(productId) !== -1);
}
Following app shows three todo items at first and
after adding an new data, it shows updated lists for a moment and go back to the original state.
Could you tell me why does it go back to the initial state automatically?
link for Pluker
http://plnkr.co/edit/h6THusBe7AWFle5ixXzX?p=preview
==================================
<!DOCTYPE html>
<html ng-app="initExample">
<head>
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script src="https://code.angularjs.org/1.4.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body class="well" ng-controller="ExampleController">
<h1> AngularJS Todo List</h1>
<p> Total <strong> {{todolist.length}} </strong> / Remain <strong> {{countRemain()}} </strong> </p>
<ul>
<li ng-repeat="todo in todolist" class="checkbox"> <input ng-model="todo.done" type="checkbox"> {{todo.title}}</li>
</ul>
<form name="newItemForm" class="form-inline" action="">
<div class="form-group">
<label class="sr-only" for="newItemText" placeholder="Type new ToDo"></label>
<input type="text" class="form-control" ng-model="newTodo" name="newItemText" placeholder="Type new Todo">
</div>
<button type="submit" ng-click="addNewTodo(newTodo)" class="btn btn-default"> Add </button>
</form>
</body>
</html>
============================
// Code goes here
var mymodule=angular.module('initExample', []);
mymodule.controller('ExampleController',
['$scope', function($scope) {
$scope.todolist = [
{done: true, title:'AngularJS study'},
{done: false, title:'music listening'},
{done: false, title:'run'}
];
$scope.countRemain = function() {
var count = 0;
var list = $scope.todolist;
angular.forEach(list, function(val, key) {
if(!list[key].done) count++;
});
return count;
};
$scope.addNewTodo = function(newTodo) {
todolist.push({done: false, title: newTodo});
};
}
]
);
Remove the action attribute from the form or add "preventDefault" from the button click.
Fixed the plunkr:
<form name="newItemForm" class="form-inline">
http://plnkr.co/edit/KFpbbdlDPbnIPAW43EaG?p=preview
P.S. also fixed the addNewTodo Function:
$scope.addNewTodo = function(newTodo) {
$scope.todolist.push({done: false, title: newTodo});
};
You need to remove action attribute from form definition, otherwise browser will try to submit it, reloading the page:
<form name="newItemForm" class="form-inline">
<!-- ... -->
</form>
Demo: http://plnkr.co/edit/MwTmGqzdELzUbrY82kKg?p=preview
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.