Ng-Options for objects in an array - angularjs

Here I have a select, where I want to repeat the contacts on the supplier.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="AppCtrl">
Hello {{name}}
<div ng-repeat="supplier in suppliers">
{{supplier.name}}
<select ng-options="contact.id as contact.name for contact in supplier.contacts">
</select>
</div>
</div>
<script>
var app = angular.module('app',[]);
//app.directive('appDirective', function() {});
//app.factory('appService', function() {});
app.controller('AppCtrl', ['$scope', function($scope){
$scope.name = "dave";
$scope.suppliers = [
{id: 0, name: "dave", contacts : [
{id: 0, name: 'c1'},
{id: 1, name: 'c2'},
{id: 2, name: 'c3'},
{id: 3, name: 'c4'},
]},
{id: 1, name: "Steve", contacts : [
{id: 0, name: 'c1'},
{id: 1, name: 'c2'},
{id: 2, name: 'c3'},
{id: 3, name: 'c4'},
]}
]
}]);
</script>
Here I have the controller.
How come this doesn't seem to work?
http://jsfiddle.net/gnosticdave/091vpadb/1/

contacts is part of each supplier - so your array is actually supplier.contacts
select ng-options="contact.id as contact.name for contact in supplier.contacts"
^^^^^^^^^^^^^^^^^^^^
Also, ngOptions needs an ngModel
Demo: http://jsfiddle.net/091vpadb/3/

Change:
<select ng-options="contact.id as contact.name for contact in contacts">
to:
<select ng-options="contact.id as contact.name for contact in supplier.contacts">

Related

ng-click with a dynamic {{}} string

I have a HTML table that has the id set with a databind inside of a ng-repeat
<div class="project" ng-repeat="project in data.projects">
<h2>
{{projectState.name}}
</h2>
<table class="table" id="{{project.name + selectedType}}">
...
</table>
...
</div>
This properly sets the id as expected, but I need to use this id in a ng-click call.
<button ng-click="export({{project.name + selectedType}})">
...
</button>
This produces the error when the page loads
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 16 of the expression [export({{project.name + selectedType}})] starting at [{project.name + selectedType}})].
How do I properly reference the databound id of {{project.name + selectedType}} in a ng-click?
Pass project.name and selectedType as 2 arguments to export method :
<button ng-click="export(project.name,selectedType)">
...
</button>
and inside export method concatenate them:
$scope.export = function(name, type){
var val = name + type;
// ...
}
or just remove {{ }} from export
You don't need to give an expression inside of export(). This should be resolved using
export(project.name,selectedType)
angular.module('myApp',[])
.controller('myCtlrl',function($scope){
$scope.projects=[
{ id: 1, name: 'John', address: 'Highway 71'},
{ id: 2, name: 'Peter', address: 'Lowstreet 4'},
{ id: 3, name: 'Amy', address: 'Apple st 652'},
{ id: 4, name: 'Hannah', address: 'Mountain 21'},
{ id: 5, name: 'Michael', address: 'Valley 345'},
{ id: 6, name: 'Sandy', address: 'Ocean blvd 2'},
{ id: 7, name: 'Betty', address: 'Green Grass 1'},
{ id: 8, name: 'Richard', address: 'Sky st 331'},
{ id: 9, name: 'Susan', address: 'One way 98'},
{ id: 10, name: 'Vicky', address: 'Yellow Garden 2'},
{ id: 11, name: 'Ben', address: 'Park Lane 38'},
{ id: 12, name: 'William', address: 'Central st 954'},
{ id: 13, name: 'Chuck', address: 'Main Road 989'},
{ id: 14, name: 'Viola', address: 'Sideway 1633'}
];
$scope.export=function(id){
alert(id);
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtlrl">
<div class="project">
<table class="table" id="{{project.name + address}}" border=1>
<tr><th>ExportButton</th><th>Id</th><th>Name</th><th>Address</th></tr>
<tr ng-repeat="project in projects">
<td><button ng-click="export(project.name+project.address)">Export</button></td>
<td>{{project.id}}</td>
<td>{{project.name}}</td>
<td>{{project.address}}</td>
</tr>
</table>
</div>
</div>
When you are using ng-click, it means you are already in angular scope so you don't need to use {{}} to call a function or evaluate the expression

AngularJS second dropdown does not update when first dropdown changes

I'm creating a search page where the user can search for data using pre-selected search criteria listed in the first drop-down. In the example below those criteria are 'First Name', 'Country' and 'Nationality'.
When the user selects Country or Nationality, a second drop-down appears to select one of the countries/nationalities. To fill this drop-down i use ng-options with a variable inside that points to a string defined in the controller.
But when one of those two options is selected and you want to switch to the other, the second drop-down does not get updated. The value inside ngOptions does get updated in the HTML, just the data inside the dropdown isn't.
When you select 'First Name' in between there is no issue. Does anyone know what I can use so the values inside the second dropdown gets updated?
Below is my code and a working plunker: http://plnkr.co/edit/LYpOdoLpgiMeHxlGzmub?p=preview
var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope) {
var vm = this;
vm.search = {id:0, criteria: {}, value: ''};
vm.referenceData = {
countries: [
{COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
{COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
{COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
{COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},
],
nationalities: [
{NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
{NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
{NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
{NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},
]
};
vm.criteriaList = [
{ name: 'First Name', key: 'FIRST_NAME'},
{ name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
{ name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
];
});
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="SomeController as ctrl">
<p>Criteria:</p>
<select ng-model="search.criteria" ng-change="search.value = ''" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
<option value="">- Select Criteria -</option>
</select>
<p>Value:</p>
<!-- TEXT INPUT -->
<input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
<!-- DROPDOWN INPUT -->
<select ng-model="search.value" ng-if="search.criteria.options" ng-options="{{search.criteria.options}}"></select>
</html>
This is an easy fix you just need a variable that can if out the second dropdown everytime you switch. The dom needs something to force it to refresh since there isnt a scope.$apply happening.
Plunker Working
Try this:
var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope, $timeout) {
var vm = this;
vm.somVal = false; ///ADD THIS
vm.search = {id:0, criteria: {}, value: ''};
vm.triggerSomeVal = function(){ ///ADD THIS
vm.someVal = true;
$timeout(function(){vm.someVal = false}, 100)
};
vm.referenceData = {
countries: [
{COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
{COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
{COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
{COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},
],
nationalities: [
{NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
{NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
{NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
{NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},
]
};
vm.criteriaList = [
{ name: 'First Name', key: 'FIRST_NAME'},
{ name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
{ name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
];
});
<p>Criteria:</p>
<select ng-model="search.criteria" ng-change="search.value = ''; ctrl.triggerSomeVal()" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
<option value="">- Select Criteria -</option>
</select>
<p>Value:</p>
<!-- TEXT INPUT -->
<input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
<!-- DROPDOWN INPUT ADD !someVal-->
<select ng-model="search.value" ng-if="search.criteria.options && !ctrl.someVal" ng-options="{{search.criteria.options}}"></select>

Preselected values for angular-schema-form

Does angular-schema-form have a method to show preselected values?
When the titleMap on the select will set an integer, preselected values will show. But if it will set an object, I found no way of showing the correct name.
Is there anything to tie the object to, like with ng-options where you can set an attribute to compare them with the "track by" clause?
ng-options="option as option.name for option in array track by option.id"
In my example code, cats1 will set an object, cats2 will set an integer.
HTML:
<body>
<div ng-controller="MainCtrl">
<div class="login-container">
<form name="myForm"
sf-schema="schema"
sf-form="form"
sf-model="model">
</form>
</div>
</div>
</body>
Controller:
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.form = [
{
key: 'cats1',
type: 'select',
titleMap: [
{value: {id: 0, name: "Leopard"}, name: "Leopard"},
{value: {id: 1, name: "Tiger"}, name: "Tiger"}
]
},
{
key: 'cats2',
type: 'select',
titleMap: [
{value: 0, name: "Leopard"},
{value: 1, name: "Tiger"}
]
}
];
$scope.schema = {
"type": "object",
"properties": {
"cats1": {
"title": "Cats",
"type": "object"
},
"cats2": {
"title": "Cats",
"type": "number"
}
}
};
$scope.model = {cats1: {id: 1, name: "Tiger"}, cats2: 1};
}]);
Here is a plunkr:
https://plnkr.co/edit/0hK5Hrc9GXklfRwa6fjE?p=preview

angularjs-dropdown-multiselect angularjs

I have a dropdown-multiselect. This directive uses Bootstrap's Dropdown with the power of AngularJS directives and binding. I new to angularjs.
<li id="bedsLists">
<div ng-dropdown-multiselect=""
options="beds"
selected-model="selectedBeds"
checkboxes="true"
events="{onItemSelect: onItemSelect, onItemDeselect: onItemDeselect}"
extra-settings="{showCheckAll: false, showUncheckAll: false, dynamicTitle: false, externalIdProp: 'Value', displayProp: 'Name', idProp: 'Value'}"
translation-texts="{buttonDefaultText: 'Beds'}">
</div>
</li>
From stateParams, required value is fetched, for example "1". How to make the first checkbox selected?
Try this
In your Controller
var myApp = angular.module('exampleApp',['angularjs-dropdown-multiselect']);
myApp.controller('appController', ['$scope', function($scope) {
$scope.selectedBeds = [{id: 1, label: "David"}]; // add the 1st data of your
$scope.beds = [
{id: 1, label: "David"},
{id: 2, label: "Jhon"},
{id: 3, label: "Lisa"},
{id: 4, label: "Nicole"},
{id: 5, label: "Danny"}];
}]);

How to pass list to angular array

I am a new to angular... I have an object list that I would like to pass to angular and use the ng-repeat function.
Using NameList that was passed from my controller, I would like to display a list of id-names-states. Before, I did the following...
<ul>
#foreach (var item in Model.NameList) {
<li>item.id - item.names - item.states</li> }
</ul>
the list would be something like...
id: '1', name: 'John Doe', city: 'Phoenix'
id: '2', name: 'Tony Hope', city: 'Queens'
id: '3', name: 'Jane Doe', city: 'Frederick'
id: '4', name: 'John Smith', city: 'Miami'
id: '5', name: 'Tom Ford', city: 'Atlanta'
After realizing angulars capabilities I would like to set up the list, with the ability to have the user filter based on names
So my question is, How do I pass the NameList object to get populated with angular, or can I just populate the object and tie the list to angular somehow?
This is what I have so far
<div id="angularWrapper" data-ng-app="" data-ng-controller ="SimpleController">
<div>Name:
<input type="text" data-ng-model="name" />
</div>
#*I would like to pass Model.NameList to customers*#
<div data-ng-model="#Model.NameList"></div>
<br />
<ul>
<li data-ng-repeat="cust in customers | filter:name">{{cust.id + - + cust.name + - + cust.state}}</li>
</ul>
</div>
In your controller:
$scope.customers = [
{ id: '1', name: 'John Doe', city: 'Phoenix' },
{ id: '2', name: 'Tony Hope', city: 'Queens' },
{ id: '3', name: 'Jane Doe', city: 'Frederick' },
{ id: '4', name: 'John Smith', city: 'Miami' },
{ id: '5', name: 'Tom Ford', city: 'Atlanta' }
];
I think you're confused about how AngularJS binding works, you should read the guide on Data Binding: http://docs.angularjs.org/guide/databinding
In the meantime here's a simple JSFiddle I think does what you're looking for: http://jsfiddle.net/mikeeconroy/75WPW/1/
<div ng-controller="myCtrl">
Name: <input type="text" ng-model="name" />
<ul>
<li ng-repeat="cust in customers | filter:name">{{cust.id}} - {{cust.name}} - {{cust.city}}</li>
</ul>
</div>
And the controller:
angular.module('myApp',[])
.controller('myCtrl', ['$scope','mySrv',function ($scope,mySrv) {
$scope.name = '';
$scope.customers = [];
$scope.customers = mySrv.getCustomers();
}])
// fake service, substitute with your server call ($http)
.factory('mySrv',function(){
var customers = [
{id: '1', name: 'John Doe', city: 'Phoenix'},
{id: '2', name: 'Tony Hope', city: 'Queens'},
{id: '3', name: 'Jane Doe', city: 'Frederick'},
{id: '4', name: 'John Smith', city: 'Miami'},
{id: '5', name: 'Tom Ford', city: 'Atlanta'}
];
return {
getCustomers : function(){
return customers;
}
};
});
You could also set $scope.customers by using the resolve function of your route.
I came up with a solution that may have a possible alternative...
<div id="angularWrapper" data-ng-app="demoApp" data-ng-controller="SimpleController">
<div>
Name:
<input type="text" data-ng-model="name" />
</div>
<div>
<ul>
<li data-ng-repeat="eg in List | filter: name">{{ eg.Name }}</li>
</ul>
</div>
<br />
<script>
$(function () {
var scope = angular.element('#angularWrapper').scope();
#foreach (var npo in Model.NameList)
{
#: scope.AddList({ Name: '#eg.Name' });
}
scope.$apply();
});
</script>
</div>
.js file
function getList() {
var self = this;
self.Name = "";
}
var demoApp = angular.module('demoApp', []);
demoApp.controller('SimpleController', SimpleController); //could just load the function($scope) from simplecontroller..
function SimpleController($scope) {
$scope.List = [];
$scope.AddList = function (data) {
var eg = new getList();
eg.Name = data.Name;
$scope.List.push(eg);
}
}

Resources