why is ng-model not checking default radio button? - javascript

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.

Related

AngularJS use one object as a filter for another

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]
}
}
];

ng-options will not pre-select an option

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

How to create nested json object in Angularjs

i want to create nested json object in angularjs. my object is this:
{
"marketerId": 1,
"baskets": [
{
"customer": {
"phone": ""
},
"region": 1,
"orders": [
{
"bookId": 1,
"count": 5
},
{
"bookId": 2,
"count": 52
}
]
},
{
"customer": {
"phone": ""
},
"region": 1,
"orders": [
{
"bookId": 1,
"count": 12
},
{
"bookId": 2,
"count": 2
}
]
}
]
}
For create this object as dynamically i write this code.Assuming orders and items already have been initialized, the form is created. For example, the size of the items and orders 2.Is there a better way to build nested json objects?
<input ng-model="formData.marketerId" />
<div class="row" ng-repeat="item in items track by $index">
<input ng-model="formData.baskets[$index].customer.phone" />
<input ng-model="formData.baskets[$index].region" />
<div ng-repeat="order in orders track by $index">
<input type="text" ng-model=
"formData.baskets[$parent.$index].orders[$index].bookId">
<input type="text" ng-model=
"formData.baskets[$parent.$index].orders[$index].count">
</div>
</div>
You can do something like this:
$scope.data1 = [];
var firstObj = new Object();
firstObj.first = "value1";
firstObj.second = "value2";
$scope.encountersData.push(firstObj);
$scope.data2 = [];
var secondObj= new Object();
secondObj.third = "value3";
secondObj.fourth = "value4";
$scope.data2.push(secondObj);

Binding problems with complex data and autocomplete

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.

Angular Select. Add element and automatically select it

Look ex. jsfiddle example
HTML
<div ng-app="app" ng-controller="mCtrl">
<select size="20" ng-model="selectedType" ng-init="selectedType=types[0]"
ng-options="type.name for type in types">
</select>
<button ng-click="addElem()">add elem in array</button>
</div>
Controller
$scope.types = [ my Array of objects ];
$scope.addElem = function() {
element = {
"id": 999,
"name": "xxx"
};
$scope.types.push(element);
}
I want to add element in ng-options array, and automatically select it in select Box with model changing.
I tried
$scope.selectedType = $scope.types[$scope.types.lenght - 1]
, but it doesn't work.
You have misspelled length.
Here is solution which works:
app = angular.module('app', []);
app.controller('mCtrl', function($scope) {
$scope.types = [
{
"id": 0,
"name": "Zaj"
},
{
"id": 1,
"name": "Emoltra"
},
{
"id": 2,
"name": "Malathion"
},
{
"id": 3,
"name": "Pyramax"
},
{
"id": 4,
"name": "Boink"
},
{
"id": 5,
"name": "Savvy"
},
{
"id": 6,
"name": "Accruex"
},
{
"id": 7,
"name": "Zappix"
}
];
$scope.addElem = function() {
element = {
"id": 7,
"name": "Zappix"
};
$scope.types.push(element);
$scope.selectedType = $scope.types[$scope.types.length - 1];
}
})
DEMO
In your code, there is a typo you have misspelled length
$scope.selectedType = $scope.types[$scope.types.length- 1]
DEMO
OR
You can set it using $scope.selectedType = element
$scope.addElem = function () {
element = {
"id": $scope.types.length + 1,
"name": "Zappix" + $scope.types.length + 1
};
$scope.types.push(element);
$scope.selectedType = element;
}
DEMO

Categories

Resources