I am using angular's ng-options to populate the html with the names of people. I want it to pre-select the value that I have set as the ng-model (registrantSelected). But for some reason, it won't do so.
I have looked up various different documentations for ng-options and looked at a bunch of other stack overflow posts about ng-options, but I can't seem to figure out what I am doing wrong.
Code can be found in this plunker or below:
Javascript:
angular.module('app', [])
.controller("MainController", ["$scope", function($scope) {
$scope.paidDuesCompanyPeople = [{
"FirstName": "Person",
"LastName": "One",
"MemberType": {
"IsMember": false,
"Name": "Non-member"
}
}, {
"FirstName": "Second",
"LastName": "Person",
"MemberType": {
"IsMember": true,
"Name": "Member"
}
}, {
"FirstName": "Three",
"LastName": "People",
"MemberType": {
"IsMember": false,
"Name": "Non-member"
}
}];
$scope.registrantSelected = {
"FirstName": "Person",
"LastName": "One",
"MemberType": {
"IsMember": false,
"Name": "Non-member"
}
};
}]);
HTML:
<div ng-app="app" ng-controller="MainController">
<div class="col-xs-12 col-sm-5">
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-6 control-label">Registration for</label>
<div class="col-sm-6">
<select class="form-control" ng-model="registrantSelected" ng-options="person.FirstName + ' ' + person.LastName for person in paidDuesCompanyPeople">
</select>
</div>
</div>
</form>
</div>
{{registrantSelected}}
</div>
Thank you for any help you can give!
You could do this thing by introducing track by in your ng-options but for having track by you should have unique property over there. I'd highly recommnd you to add Id property so that would make each record unique & you can track by the same. But for now just for demonstration you can track it by person.FirstName + person.Lastname(you will have track by person.Id when you add id)
<select class="form-control"
ng-model="registrantSelected"
ng-options="person.FirstName + ' ' + person.LastName for person in paidDuesCompanyPeople track by person.FirstName + person.Lastname ">
</select>
Demo Here
You should be able to set it in the controller, like so...
$scope.registrantSelected = $scope.paidDuesCompanyPeople[0];
Which makes your controller look like this (drop it in your plunkr)
Edit: I have added a plunkr as requested http://plnkr.co/edit/r8XAWqBheAATwc8zXGSY?p=preview
angular.module('app', [])
.controller("MainController", ["$scope", function($scope) {
$scope.paidDuesCompanyPeople = [{
"FirstName": "Person",
"LastName": "One",
"MemberType": {
"IsMember": false,
"Name": "Non-member"
}
},{
"FirstName": "Second",
"LastName": "Person",
"MemberType": {
"IsMember": true,
"Name": "Member"
}
},{
"FirstName": "Three",
"LastName": "People",
"MemberType": {
"IsMember": false,
"Name": "Non-member"
}
}];
$scope.registrantSelected = $scope.paidDuesCompanyPeople[0];
}]);
if you want to do it in the view,
<select ng-model="registrantSelected"
ng-options="person.FirstName + ' ' + person.LastName for person in paidDuesCompanyPeople"
ng-init="registrantSelected=paidDuesCompanyPeople[0]"></select>
change registrantSelected value to this:
$scope.registrantSelected = $scope.paidDuesCompanyPeople[0];
in javascript every two objects are the same only if both of them are referring to same object:
var x1 = { id : 1 };
var x2 = { id : 1 };
console.log(x1 == x2); // false
var y1 = { id : 1 };
var y2 = y1;
console.log(y1 == y2); // true
Related
I'm trying to filter my ng-repeat through a set of checkboxes which come from a different object. Object 1 holds my categories and object 2 holds all my articles.
The categores object will turn into checkboxes. These checkboxes should act as filter for the articles. An article can have mutliple categories.
$scope.categories:
[
{
"id": "1",
"title": "Blog"
},
{
"id": "2",
"title": "News"
}
]
$scope.articles:
[
{
"id": "1",
"title": "Whats going on",
"categories":{
"results" : [1,2,3]
}
},
{
"id": "2",
"title": "Trump!",
"categories":{
"results" : [3]
}
}
]
Checkboxes:
<div class="filter-pills" ng-repeat="cat in categories">
<input type="checkbox" ng-model="filter[cat.Id]" ng-checked="cat.checked"/>{{cat.Title}}
</div>
ng-repeat:
<div class="col-lg-3 col-md-4" ng-repeat="item in articlesFinal"></div>
I have tried different solutions like ng-change when i update my filter array and compare it to the object used in ng-repeat.
I can't seem to figure this one out. Any suggestions?
Try this
<div class="filter-pills" ng-repeat="cat in categories">
<input type="checkbox" ng-model="cat.checked"/>{{cat.title}}
</div>
<div class="col-lg-3 col-md-4" ng-repeat="item in articles | filter: catFilter">{{item.title}}</div>
and in controller
$scope.catFilter = function (article) {
var checkedCats = vm.categories.filter(function (cat) {
return cat.checked;
});
// no filter, show all
if(checkedCats.length == 0) return true;
for(var i = 0; i < checkedCats.length; i++){
var id = checkedCats[i].id;
if(article.categories.results.indexOf(id) >= 0){
return true;
}
}
// no match, then false
return false
};
Also notice that category id should be integer, not string
$scope.categories = [
{
"id": 1, // integer
"title": "Blog"
},
{
"id": 2,
"title": "News"
}
];
$scope.articles = [
{
"id": "1",
"title": "Whats going on",
"categories":{
"results" : [1,2,3] // integer
}
},
{
"id": "2",
"title": "Trump!",
"categories":{
"results" : [3]
}
}
];
Below is the fiddle i am working:
http://jsfiddle.net/3c0dxf4d/
The ng-model has an object and the ng-value maps to object, why is my default value {"id":1,"name":"Bill"}
not getting selected by default.
Check out this fiddle http://jsfiddle.net/roz98eda/
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
$scope.customers = [{
"id": 1,
"name": "Bill"
}, {
"id": 2,
"name": "Bob"
}, {
"id": 3,
"name": "Biff"
}];
$scope.customer = {};
$scope.currentCustomer = {
"id": 1
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
<table>
<tr ng-repeat="theCustomer in customers">
<td>
<input type="radio" ng-model="$parent.currentCustomer.id" ng-value="theCustomer.id">{{theCustomer.name}}</td>
</tr>
</table>
<br>
<div>{{currentCustomer}}</div>
</div>
</div>
Because you've put the initial value to
$scope.currentCustomer = {
"id": 1,
"name": "Bill"
};
Just remove or change it.
Please check following code please.
app.controller("ctrl", function ($scope) {
$scope.customers = [{
"id": 1,
"name": "Bill"
}, {
"id": 2,
"name": "Bob"
}, {
"id": 3,
"name": "Biff"
}];
$scope.customer = {};
*$scope.currentCustomer = {
"id": 1,
"name": "Bill"
};*
})
Change
<input type="radio" ng-model="$parent.currentCustomer" name="foo" ng-value="theCustomer" id="{{theCustomer.id}}">
To
<input type="radio" ng-model="$parent.currentCustomer.id" name="foo" ng-value="theCustomer.id" id="{{theCustomer.id}}">{{theCustomer.name}}</td>
From ng-value docs
It is mainly used on input[radio] and option elements, so that when
the element is selected, the ngModel of that element (or its select
parent element) is set to the bound value.
I am using toggle class for highlighting table cells.
<style>
table td.highlighted {
background-color: #999;
}
</style>
<script>
$(function () {
var isMouseDown = false;
$("#productTable td")
.mousedown(function () {
isMouseDown = true;
debugger;
$(this).toggleClass("highlighted");
return false; // prevent text selection
});
$(document)
.mouseup(function () {
debugger;
isMouseDown = false;
});
});
</script>
And my table is like this:
<div class="container">
<div class="row">
<form>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-search"></i>
</div>
<input type="text" class="form-control" placeholder="Aramak İstediğiniz Ürün Alanını Giriniz" ng-model="src_product">
</div>
</div>
</form>
</div>
<div class="row">
<div class="col-md-10">
<br />
<table ng-table="usersTable" id="productTable" class="table table-striped">
<tr>
<th ng-repeat="column in cols">{{column}}</th>
<th> Adet</th>
</tr>
<tr ng-repeat="row in data | filter: src_product">
<td id="productProperties" ng-model="productProperties" ng-repeat="column in cols ">{{row[column]}}</td>
<td><input type="text" style="width: 100%; height: 30px !important" name=" adet" value="0"></td>
</tr>
</table>
</div>
</div>
</div>
this is my controller:
myApp.controller('productController', ['$rootScope', '$scope', 'SharedDataService', "productFactory", "$log", "$filter", 'ngTableParams', function ($rootScope, $scope, SharedDataService, productFactory, $log, $filter, ngTableParams) {
$scope.users = [{"id":1,"first_name":"Philip","last_name":"Kim","email":"pkim0#mediafire.com","country":"Indonesia","ip_address":"29.107.35.8"},
{"id":2,"first_name":"Judith","last_name":"Austin","email":"jaustin1#mapquest.com","country":"China","ip_address":"173.65.94.30"},
{"id":3,"first_name":"Julie","last_name":"Wells","email":"jwells2#illinois.edu","country":"Finland","ip_address":"9.100.80.145"},
{"id":4,"first_name":"Gloria","last_name":"Greene","email":"ggreene3#blogs.com","country":"Indonesia","ip_address":"69.115.85.157"},
{"id":50,"first_name":"Andrea","last_name":"Greene","email":"agreene4#fda.gov","country":"Russia","ip_address":"128.72.13.52"},{"id":1,"first_name":"Philip","last_name":"Kim","email":"pkim0#mediafire.com","country":"Indonesia","ip_address":"29.107.35.8"},
{"id":2,"first_name":"Judith","last_name":"Austin","email":"jaustin1#mapquest.com","country":"China","ip_address":"173.65.94.30"},
{"id":3,"first_name":"Julie","last_name":"Wells","email":"jwells2#illinois.edu","country":"Finland","ip_address":"9.100.80.145"},
{"id":4,"first_name":"Gloria","last_name":"Greene","email":"ggreene3#blogs.com","country":"Indonesia","ip_address":"69.115.85.157"},
{ "id": 50, "first_name": "Andrea", "last_name": "Greene", "email": "agreene4#fda.gov", "country": "Russia", "ip_address": "128.72.13.52" },
{ "id": 1, "first_name": "Philip", "last_name": "Kim", "email": "pkim0#mediafire.com", "country": "Indonesia", "ip_address": "29.107.35.8" },
{ "id": 2, "first_name": "Judith", "last_name": "Austin", "email": "jaustin1#mapquest.com", "country": "China", "ip_address": "173.65.94.30" },
{ "id": 3, "first_name": "Julie", "last_name": "Wells", "email": "jwells2#illinois.edu", "country": "Finland", "ip_address": "9.100.80.145" },
{ "id": 4, "first_name": "Gloria", "last_name": "Greene", "email": "ggreene3#blogs.com", "country": "Indonesia", "ip_address": "69.115.85.157" },
{ "id": 50, "first_name": "Andrea", "last_name": "Greene", "email": "agreene4#fda.gov", "country": "Russia", "ip_address": "128.72.13.52" }];
$scope.usersTable = new ngTableParams({
page: 1,
count: 10
}, {
total: $scope.users.length,
getData: function ($defer, params) {
$scope.data = params.sorting() ? $filter('orderBy')($scope.users, params.orderBy()) : $scope.users;
$scope.data = params.filter() ? $filter('filter')($scope.data, params.filter()) : $scope.data;
$scope.data = $scope.data.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.data);
}
});
$scope.cols = Object.keys($scope.users[0]);
$scope.idSelectedVote = null;
$scope.setSelected = function (idSelectedVote) {
debugger;
$scope.idSelectedVote = idSelectedVote;
};
$scope.src_product = '';
}]);
My table is looking like this:
Here is the my question. when i search a word or go second page of table highlighted cells are turn back non highligted and it doesnt let me select a cell. How can i do stable cells and take highlighted cells values ?
On page change or search, the table is redrawn so your class change is lost. If you assign the class based on a model value, you could instead change the model value and get the class modified, and this would be persisted across redraws. You can use ng-class attribute to make the class name used for the td dependant on a model value. For example:
<td ng-class="{'highlighted':row[column].isSelected}" ng-click="selectCell(row[column])"></td>
Then, inside your controller, you can create a function:
$scope.selectCell = function(cell) {
typeof cell.isSelected === "undefined" ? cell.isSelected = true : cell.isSelected = false;
}
ngClass
ngClick
HTML Code
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script>
document.write("<base href=\"" + document.location + "\" />");
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<h1> NG options</h1>
<form name="addUser">
Application:
<select ng-model="filterAddUser.application" ng-init ="filterAddUser.application = 'STACK'" title="" ng-options="value as value for (key , value) in applicationStatus">
</select>
Roles:
<select ng-model="filterAddUser.role" title="" ng-init ="filterAddUser.role = 'R'" ng-options="role.value as role.param for role in roleStatus">
</select>
<button ng-click="addToCart()">AddItem</button>
<div class="addCart">
<ul ng-repeat="item in items">
<li><b>Application:</b> {{item.application}}</li>
<li><b>Role:</b> {{item.role}}</li>
<li class="actionOptions">
<button ng-click="toggleSelected($index)">removeItem</button>
</li>
</ul>
</div>
</form>
</body>
</html>
Javascript Code
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [];
$scope.applicationStatus = {
"TEST App": "TEST",
"ABC App": "ABC",
"TRY App": "TRY",
"SIR App": "SIR",
"LOPR App": "LOPR",
"STACK App": "STACK"
};
$scope.roleStatus = [{
"param": "Read",
"value": "R"
}, {
"param": "Write",
"value": "W"
}, {
"param": "Admin",
"value": "A"
}, {
"param": "Super Approver",
"value": "SA"
}, {
"param": "Supervisor",
"value": "S"
}];
$scope.addToCart = function() {
$scope.items.push({
application: $scope.filterAddUser.application,
role: $scope.filterAddUser.role
});
// Clear input fields after push
$scope.filterAddUser['application'] = "";
$scope.filterAddUser['role'] = "";
}
$scope.toggleSelected = function(index) {
$scope.items.splice(index, 1);
};
});
All that i am trying to do is when i add the application to the cart that application needs to be removed from the dropdwon and also when i click on the remove item that needs to be pushed back to the cart i have included a plunker as well http://plnkr.co/edit/kSsetX?p=preview
need help on the same.
Updated your plunkr: http://plnkr.co/edit/QQobh7Jx76r7lDzw7TzV
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [];
var deletedApplication = [];
$scope.applicationStatus = {
"TEST App": "TEST",
"ABC App": "ABC",
"TRY App": "TRY",
"SIR App": "SIR",
"LOPR App": "LOPR",
"STACK App": "STACK"
};
$scope.roleStatus = [{
"param": "Read",
"value": "R"
}, {
"param": "Write",
"value": "W"
}, {
"param": "Admin",
"value": "A"
}, {
"param": "Super Approver",
"value": "SA"
}, {
"param": "Supervisor",
"value": "S"
}];
$scope.filterAddUser = {
application: $scope.applicationStatus[0],
role: $scope.roleStatus[0]
};
$scope.addToCart = function() {
deletedApplication.push([
$scope.filterAddUser.application, $scope.applicationStatus[$scope.filterAddUser.application]
]);
delete $scope.applicationStatus[$scope.filterAddUser.application];
$scope.items.push({
application: $scope.filterAddUser.application,
role: $scope.filterAddUser.role
});
// Clear input fields after push
$scope.filterAddUser['application'] = $scope.applicationStatus[0];
$scope.filterAddUser['role'] = $scope.roleStatus[0];
}
$scope.toggleSelected = function(index) {
var addApp = deletedApplication.filter(function(deletedApp){
return deletedApp[0] === $scope.items[index].application;
})[0];
$scope.applicationStatus[addApp[0]] = addApp[1];
console.log($scope.applicationStatus);
$scope.items.splice(index, 1);
};
});
I'm using Knockout JS 3.2 and I'd like to use it with autocomplete dropdown. I'm not able to get around two problems.
I simplified the data and code so this runs stand-alone:
<script type="text/javascript">
var data = [
{ "User": { "Id": 1, "DisplayName": "john a" }, "Roles": [{ "Id": 1, "Name": "admins" }, { "Id": 2, "Name": "users" }] },
{ "User": { "Id": 2, "DisplayName": "john b" }, "Roles": [] },
{ "User": { "Id": 3, "DisplayName": "john c" }, "Roles": [{ "Id": 1, "Name": "admins" }] },
{ "User": { "Id": 4, "DisplayName": "john d" }, "Roles": [] },
{ "User": { "Id": 5, "DisplayName": "john e" }, "Roles": [{ "Id": 2, "Name": "users" }] }
];
$(function () {
$("#searchTerm").autocomplete({
source: data,
minLength: 1,
select: function (event, ui) {
if (ui.item) {
var viewModel = ko.mapping.fromJS(ui.item);
ko.cleanNode($("#userDetails")[0]);
ko.applyBindings(viewModel, $("#userDetails")[0]);
}
}
})
.autocomplete("instance")._renderItem = function (ul, item) {
return $("<li>")
.append("<a>" + item.User.DisplayName + "</a>")
.appendTo(ul);
};
});
</script>
<div>Select User: <input id="searchTerm" name="searchTerm" type="text" /></div>
<div id="userDetails">
<div>User: <span data-bind="text: User.DisplayName"></span></div>
<div data-bind="foreach: Roles, visible: Roles().length > 0">
<div><span data-bind="text: Name"></span></div>
</div>
</div>
Problems:
I'd like to show the userDetails div only when it's bound -- hide it on page load. I tried setting style="display:none" and then data-bind="if:User" or data-bind="if:User.Id". Setting display attribute hides the element on load, but it doesn't change on bind.
Roles element binding doesn't work right. On first time that user is selected, the roles show, but they fail to show after changing the user selection.
Instead of always rebinding you need to have a proper view model with a selectedUser property and just update that one in the automcomplete handler.
var viewModel = {
selectedUser: ko.observable()
}
ko.applyBindings(viewModel, $("#userDetails")[0]);
$(function () {
$("#searchTerm").autocomplete({
source: data,
minLength: 1,
select: function (event, ui) {
if (ui.item) {
var user = ko.mapping.fromJS(ui.item);
viewModel.selectedUser(user);
}
}
})
.autocomplete("instance")._renderItem = function (ul, item) {
return $("<li>")
.append("<a>" + item.User.DisplayName + "</a>")
.appendTo(ul);
};
});
With this approach you can use the with binding and it will also solve both of your problems:
<div id="userDetails" data-bind="with: selectedUser">
<div>User: <span data-bind="text: User.DisplayName"></span></div>
<div data-bind="foreach: Roles, visible: Roles().length > 0">
<div><span data-bind="text: Name"></span></div>
</div>
</div>
Demo JSFiddle.