how to execute function on ng-repeater running - javascript

Hi I have problem with ng-repeater in angular I want to execute function to do calculation on run my problem now the function is not execute when I pass the Id https://jsfiddle.net/gkqL3zdp/1/
can someone help me ?
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="category in model.categories"> <span> Category: {{ category.name }} </span>
<div ng-click="getID(category.Id)">
</div>
</div>
debugger;
angular.module("app", [])
.controller('ctrl', ['$scope',
function ($scope) {
$scope.model = {
categories: [{
"Id": 1,
name: '1'
}, {
"Id": 2,
name: '2'
},{
"Id": 3,
name: '3'
},{
"Id": 4,
name: '4'
}]
}
$scope.getID = function(id){
id=+2
console.log(parentId)
return result;
}
}])

You can use ng-init for that.
On the same div use something like:
<div ng-repeat="repeatExpression">
<div ng-init="getId()"></div>
</diV>

your clickable divs were 0 height and your parentId and result variables were undefined. I fixed in https://jsfiddle.net/gkqL3zdp/1/
$scope.getID = function(id){
console.log(id)
return id;
}

Related

Nested ng-repeat angularjs

I have an value like that my problem is i don't know how much nested that dummy array object so how to use ng-repeat that print all dummy array object
demo: [{
id: 1,
dummy: [
{
id: 1,
dummy: [
{
id: 1,
dummy: [
{
id: 1
}
]
}
]
}
]
}]
try like this. as this answers: How to put ng-repeat inside ng-repeat for n number of times
and How can I make recursive templates in AngularJS when using nested objects?
var app = angular.module("app", []);
app.controller('mainCtrl', function($scope){
$scope.demo = [{
id: 1,
dummy: [
{
id: 1,
dummy: [
{
id: 1,
dummy: [
{
id: 1,
dummy: [
{
id: 1,
dummy:[]
}
]
}
]
}
]
}
]
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet"/>
<div ng-app="app" ng-controller="mainCtrl">
<script type="text/ng-template" id="dummy.html">
<ul>
<li ng-repeat="d in demo" >
<div >{{d.id}}</div>
<div ng-show="d.dummy.length" ng-include=" 'dummy.html' " onload="demo = d.dummy"></div>
</li>
</ul>
</script>
<div ng-include=" 'dummy.html'" ></div>
</div>

why isn't my angular options track by id working

I'm sure I must be doing this wrong, but:
I have an object that stores the id of an item. I also have an array of these items. I need to have a 'select' that represents the currently selected item, but that can also change the selected item.
I have set the 'select's model to the object.selectId.
The 'select' ng-options is "option.Text for option in options track by optionId"
Yet the model and 'select' options types don't match
How do I achieve what I need?
Here's a fiddle of what I am doing: https://jsfiddle.net/vb2xe1mc/5/
Code:
<script>
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
id: 1
};
$scope.options = [
{Text: "zero", Id: 0},
{Text: "one", Id: 1},
{Text: "two", Id: 2},
{Text: "three", Id: 3}
];
$scope.selectChange = function() {
alert($scope.item.id);
};
}]);
</script>
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item.id" ng-options="option.Text for option in options track by option.Id" ng-change='selectChange()'>
</select>
</div>
</div>
If you can, please let me know where I have gone wrong or correct the fiddle.
Thanks ^_^
Andy
Clarification:
The model item has id 1 already selected. I need the list to preselect the option with id 1 in this case. Also, When the option is selected it does not set the item.id to an int, rather it sets it to the entire option item. I need it to set the item.id to the option.Id
<select ng-model="item.id" ng-options="option.id as option.Text for option in options" ng-change='selectChange()'>
You want to select option.id, not option and track by is unnecessary.
Bind the select to ng-model="item", not ng-model="item.id".
Also decide on id vs. Id
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item" ng-options="option.Text for option in options track by option.Id" ng-change='selectChange()'>
</select>
</div>
</div>
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
Id: 1
};
$scope.options = [{
Text: "zero",
Id: 0
}, {
Text: "one",
Id: 1
}, {
Text: "two",
Id: 2
}, {
Text: "three",
Id: 3
}, ];
$scope.selectChange = function() {
console.log ($scope.item.Id)
alert($scope.item.Id);
};
}]);
See here for a fixed version: https://jsfiddle.net/ax3k418p/
https://jsfiddle.net/vb2xe1mc/10/
You need to bind item to ng-model, and inititally $scope.Id should be set to 1 not $scope.id = 1
Also check when you alert it should be alert($scope.item.Id);
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item" ng-options="option.Text for option in options" ng-change='selectChange()'>
</select>
</div>
</div>
JS:
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
Id: 1
};
$scope.options = [{
Text: "zero",
Id: 0
}, {
Text: "one",
Id: 1
}, {
Text: "two",
Id: 2
}, {
Text: "three",
Id: 3
}, ];
$scope.selectChange = function() {
alert($scope.item.Id);
};
}]);

ANGULARJS ng-repeat - iterating with objects['propertyname']

how do you ng-repeat object with property names such as
$scope.myobjects = [
{
'property1': {
id: 0,
name: 'somebody'
}
},
{
'property2': {
id: 1,
name: 'someguy'
}
}];
As the keys of the object is not same, you can't just iterate it. May be you can do it in this way:
DEMO
<div ng-repeat="object in myobjects">{{getValue(object,'id') }}
{{getValue(object,'name')}}
</div>
In your controller:
$scope.getValue = function(value,field) {
var key = Object.keys(value).filter(function(val)
{
return val != "$$hashKey"
})[0];
return value[key][field];
}
You have to add a nested ng-repeat too like below if you want to take property names of objects (second one is looping into the objects):
<div ng-repeat="(index, object) in myobjects">
<div ng-repeat="(key, value) in object">
<strong>key: </strong> {{ key }}, <strong>value: </strong>{{ value }}
<strong>value.id: </strong> {{ value.id }}, <strong>value.name: </strong>{{ value.name }}
</div>
</div>
This prints:
key: property1, value: {"id":0,"name":"somebody"} value.id: 0, value.name: somebody
key: property2, value: {"id":1,"name":"someguy"} value.id: 1, value.name: someguy
Demo: http://embed.plnkr.co/SIMjaXMZPzbHLOCYRU8T/preview
ng-repeat with obj prop
<div ng-app="demo" ng-controller="abc">
<div ng-repeat="(key, value) in myobjects">
<div ng-repeat="objProp in value">{{objProp.name}}</div>
</div>
</div>
var app = angular.module('demo', []);
app.controller('abc', function ($scope) {
$scope.myobjects = [{
'property1': {
id: 0,
name: 'somebody'
}
}, {
'property2': {
id: 1,
name: 'someguy'
}
}];
})
here is working jsfiddle

orderBy in inner loop on nested ng-repeat

I want to filter websites that are in the filtered categories and display them in order of their rank.The code snippet is:
<div ng-repeat="category in categories | filter:{will return more than one category}">
<div ng-repeat="website in websites | orderBy:'rank'| filter:{ parent_id : category.id }:true">
{{website.title}},{{website.rank}}
</div>
</div>
But in the nested loop, since orderby is in inner loop, it works for each iteration of outer loop but the overall result is not sorted according to rank. Say there are three categories and filter gives cat1 &cat2. If websites with rank 6,2,5 are is cat1 and 9,1 in cat2 then the result will be 2,5,6,1,9.I want the result to be 1,2,5,6,9.How should I do that ?
Should I pass the category in some function and write the js code to get the array of filtered website and then sort them and return them to template or is there any other better way to do that in template itself?
I think what you want to do, can not be done as is. Anyway you could use a custom filter.
New Answer
This approach gives you a category selection mechanism as another example of how you could use this custom filter.
angular.module('app',[])
// categories
.value('categories', [ { id: 0, title:"first" }, { id: 1, title:"second" }, { id: 2, title:"third" } ])
// websites
.value('websites', [ { rank: 3, parent_id: 2, title: "Alice" },
{ rank: 1, parent_id: 1, title: "Bob" },
{ rank: 9, parent_id: 1, title: "Carol" },
{ rank: 2, parent_id: 0, title: "David" },
{ rank: 4, parent_id: 0, title: "Emma" },
{ rank: 5, parent_id: 0, title: "Foo" } ])
// controller,
.controller('ctrl', ['$scope', 'categories', 'websites', function($scope, categories, websites) {
// categories injected
$scope.categories = categories;
// websites injected
$scope.websites = websites;
// categories selection helper, useful for preselection
$scope.selection = { 0: true, 1:false } // 2: false (implicit)
}])
// categories filter, categories injected.
.filter('bycat', ['categories', function(categories) {
// websites is the result of orderBy :'rank', selection helper passed as paramenter.
return function(websites, selection) {
// just an Array.prototype.filter
return websites.filter(function(website) {
// for each category
for(var i=0; i < categories.length; i++) {
var cat = categories[i];
// if category is selected and website belongs to category
if (selection[cat.id] && cat.id == website.parent_id) {
// include this website
return true;
}
}
// exclude this website
return false;
});
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<span ng-repeat="category in categories">
<label class="checkbox" for="{{category.id}}">
<input type="checkbox" ng-model="selection[category.id]" name="group" id="{{category.id}}" />
{{category.title}}
</label>
</span>
<div ng-repeat="website in websites | orderBy:'rank'| bycat: selection">
<p>Rank:{{website.rank}} - {{website.title}} ({{categories[website.parent_id].title}})</p>
</div>
</div>
Old Ansewer
Se code comments.
angular.module('app',[])
// categories will be injected in custom filter.
.value('categories', [ { id: 1, title:"first" }, { id: 2, title:"second" } ])
.controller('ctrl', function($scope) {
// sample websites
$scope.websites = [ { rank: 1, parent_id: 2, title: "Site w/rank 1" },
{ rank: 9, parent_id: 2, title: "Site w/rank 9" },
{ rank: 2, parent_id: 1, title: "Site w/rank 2" },
{ rank: 4, parent_id: 1, title: "Site w/rank 4" },
{ rank: 5, parent_id: 1, title: "Site w/rank 5" } ];
})
// custom filter, categories injected.
.filter('bycat', ['categories', function(categories) {
// websites is the result of orderBy :'rank'
return function(websites, catText) {
// just an Array.prototype.filter
return websites.filter(function(website) {
// if no filter, show all.
if (!catText) return true;
for(var i=0; i < categories.length; i++) {
var cat = categories[i];
// if matches cat.title and id == parent_id, gotcha!
if (cat.title.indexOf(catText) != -1 && cat.id == website.parent_id) {
return true;
}
}
// else were
return false;
});
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<input type="text" ng-model="filterText">
<p>Try "first" and "second"</p>
<div ng-repeat="website in websites | orderBy:'rank'| bycat: filterText ">
{{website.title}},{{website.rank}}
</div>
</div>

How to set a default ngOptions value, when options are objects, and default is an integer ID

I'm working with ngOptions to display a select element, and want to connect the model to the value that's set as the value in ngOptions.
var app = angular.module('test', []);
app.controller('TestCtrl', ['$scope',
function ($scope) {
//Use random to simulate different data from an API
$scope.default = Math.floor(Math.random()*3);
$scope.options = [
{
id: 0,
name: "Option 1"
},
{
id: 1,
name: "Option 2"
},
{
id: 2,
name: "Option 3"
}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="TestCtrl">
<select ng-model="default" ng-options="val.name for val in options track by val.id">
</select>
<pre>Default should be ID {{default}}, or Option {{default+1}}
</div>
</div>
I've tried using track by, select as, and I've found two solutions that work, but are not ideal.
Ideally, I'd be able to set default
Solution 1:
// Loop through entire array of objects
$scope.options.forEach(function (v, k) {
// Compare ID to what the default should be
if (v.id === $scope.default) {
// Set object to default
$scope.default = v;
return true;
}
});
Solution 2:
JS
$scope.options = {
"Option 1": 0,
"Option 2": 1,
"Option 3": 2
};
HTML
<select ng-model="default" ng-options="value as key for (key, val) in options">
The thing that's tough about this solution is it only works if the object has no more than two values, since a key cannot be an object.
Is there any way to have Angular set a default by key, without having to include the entire object?
try it like this
<select ng-options="item.id as item.name for item in options" ng-model="selected"></select>
then in controller
$scope.selected = 1;
similar plunkr example
var app = angular.module('test', []);
app.controller('TestCtrl', ['$scope',
function ($scope) {
//Use random to simulate different data from an API
$scope.options = [
{
id: 0,
name: "Option 1"
},
{
id: 1,
name: "Option 2"
},
{
id: 2,
name: "Option 3"
}
];
$scope.default = $scope.options[Math.floor(Math.random()*3)];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="TestCtrl">
<select ng-model="default" ng-options="val.name for val in options">
</select>
<pre>Default should be ID {{default.id}}, or Option {{default.id+1}}
</div>
</div>

Categories

Resources