ng-repeat get length of array and bind last value of array - angularjs

$scope.GetDetails={
Student:[
{"id":1,"Name":"Apple","Price":3500}
],
Student:[
{"id":2,"Name":"Samsung","Price":4000}
],
Student:[
{"id":3,"Name":"Nokia","Price":1500},
{"id":3,"Name":"Nokia","Price";7000}
]
}
Am binding data using ng-repeat
<div ng-repeat="As in GetDetails">
<div ng-repeat="A in As.Student">
<span>{{A.Name}}</span> - <span>{{A.Price}}</span>
</div>
</div>
Result is
Apple - 3500
Samsung - 4000
Nokia - 1500
Nokia - 7000
Here every thing Ok.But what i want mean , Nokia have two array ,so i have to get name from first array and price from 2nd array Like,
Nokia - 7000,
And Also i need the length of student array.

First, You should change your JSON to achieve your result.
Change JSON to below:
$scope.GetDetails=[
{Student:[{"id":1,"Name":"Apple","Price":3500}]},
{Student:[{"id":2,"Name":"Samsung","Price":4000}]},
{Student:[{"id":3,"Name":"Nokia","Price":1500},{"id":3,"Name":"Nokia","Price":7000}]}
]
Please run below code
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="As in GetDetails">
<div ng-repeat="A in As.Student" ng-if="$last">
<span>{{A.Name}}</span> - <span>{{A.Price}}</span>
</div>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.GetDetails=[
{Student:[{"id":1,"Name":"Apple","Price":3500}]},
{Student:[{"id":2,"Name":"Samsung","Price":4000}]},
{Student:[{"id":3,"Name":"Nokia","Price":1500},{"id":3,"Name":"Nokia","Price":7000}]}
]
});
</script>
</body>
</html>
I used ng-if="$last" to take the last value from array
Here is a working DEMO

If you want this only for Name: Nokia, then do it like;
<div ng-repeat="A in As.Student">
<span ng-if="A.Name!=='Nokia'">{{A.Name}}-{{A.Price}}</span>
<span ng-if="A.Name==='Nokia' && $last">{{A.Name}}-{{A.Price}}</span>
</div>
and it you want only last element from every array :
then:
<div ng-repeat="A in As.Student" ng-if="$last">
<span>{{A.Name}}</span> - <span>{{A.Price}}</span>
</div>

Related

ng-repeat orderBy with double digit number

I have names such as:
Name - Page 9
Name - Page 2
Name - Page 6
Name - Page 15
Name - Page 1
Name - Page 12
Name - Page 14
Name - Page 13
Name - Page 10
Name - Page 11
Currently I am doing:
<div ng-repeat="data in results | orderBy:'-name'">
{{ data.name }}
</div>
But it doesn't order it with the numbers taken into consideration.
Does anyone know how I can make sure it is ordered according to the numbers?
<!DOCTYPE html>
<html>
<head>
<script src="angular.js"></script>
</head>
<body data-ng-app="app">
<div data-ng-controller="testC">
<div ng-repeat="data in results | orderBy:['name']">-{{data.name}}</div>
</div>
</body>
</html>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('testC', ['$scope', function($scope) {
$scope.results = [{'name':'Page 21'},
{'name':'Page 12'},
{'name':'Page 10'},
{'name':'Page 01'},
{'name':'Page 30'},
{'name':'Page 15'},
{'name':'Page 05'}];
}]);
</script>
it is working for me ,please try once .
https://jsfiddle.net/shivtumca12/nqbLLr4x/
and also
https://jsfiddle.net/shivtumca12/LxLu8v70/
It should work as expected. Check this plunker that I created.
Plunker Code
Edit: To handle double digits you can write a custom sort function like this:
$scope.myValueFunction = function(value) {
var numpart = value.name.replace( /^\D+/g, '');
return -(numpart-1000);
}
What this does is extract the number part and make it a sortable number. You can remove the preceding -ve sign to get ascending order.
Then in your html, you can call this function like this:
<tr ng-repeat="friend in friends | orderBy:myValueFunction">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>

How to display the answer direction for a questionarie based on Direction

We are creating a quiz using angularjs.
We want to show the radiobutton list direction vertically or horizontally.
If it is horizontally we want do show in 2 columns.
Help me to show horizontally or vertically
Have provided the code in
var app = angular.module("quizApp", []);
app.controller("quizCtrl", function ($scope) {
$scope.questions = [
{
question: "Which is the largest country in the world by population?",
options: ["India", "USA", "China", "Russia"],
answer: 2,
direction:0
},
{
question: "When did the second world war end?",
options: ["1945", "1939", "1944", "1942"],
answer: 0,
direction: 1
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<body>
<div ng-app="quizApp" ng-controller="quizCtrl">
<div data-ng-repeat="quiz in questions track by $index" data-ng-init="quizIndex = $index" layout="column">
<div layout="row">
<span data-ng-bind="quiz.question"></span>
</div>
<div layout="row" data-ng-repeat="option in quiz.options track by $index" data-ng-init="optionIndex = $index">
<input type="radio" data-ng-value="{{option}}" style="margin-right: 5px;"
name="Options_{{quizIndex}}_Response_{{optionIndex}}" />
<span id="spnAnswer_{{quizIndex}}_{{optionIndex}}" data-ng-bind="option" />
</div>
</div>
</div>
</body>
You can use ng-class in the div of your repeater to show horizontal or vertical way.
Your HTML template might be look like following:
<div ng-class="'class-for-horizontal-display': !showVertical, 'class-for-vertical-display': showVertical" data-ng-repeat="quiz in questions track by $index" data-ng-init="quizIndex = $index" layout="column">
</div>
and in your controller you should have a $scope variable "showVertical" like:
$scope.showVertical = false

Initialise a select in AngularJs

I have a select that should track a myCoef as a float value(not an object, but a float value).
I have the following code (CodePen HERE):
function theController($scope) {
$scope.coefs = [
{name:'mm', val:1/1000},
{name:'cm', val:1/100},
{name:'m', val:1}
];
$scope.myCoef = 1/100;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<body ng-app>
<div ng-controller="theController">
<select ng-model="myCoef"
ng-options="coef.name for coef in coefs track by coef.val">
</select>{{myCoef}}
</div>
</body>
How do I correctly initialise my select, in order to keep a float value in myCoef?
Use As syntax and remove track by.
PS : If someone knows why i have to remove track by he can edit my answer because i don't really know why.
function theController($scope) {
$scope.coefs = [
{name:'mm', val:1/1000},
{name:'cm', val:1/100},
{name:'m', val:1}
];
$scope.myCoef = 1/100;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<body ng-app>
<div ng-controller="theController">
<select ng-model="myCoef"
ng-options="coef.val as coef.name for coef in coefs">
</select>{{myCoef}}
</div>
</body>
A little strange syntax. Following the Walfrat answer, examples how to init by val, or by name the initial value (without passing via $scope.myCoef = $scope.coefs[1] syntax)
function theController($scope) {
$scope.coefs = [
{name:'mm', val:1/1000},
{name:'cm', val:1/100},
{name: 'm', val:1}
];
$scope.myCoefVal = 1/1000;
$scope.myCoefName = 'cm';
}
<body ng-app>
<div ng-controller="theController">
Init by value - myCoefVal=1/100 <br>
<select ng-model="myCoefVal"
ng-options="coef.val as coef.name for coef in coefs">
</select><br>
now myCoefVal={{myCoefVal}}
<br/><br/>
Init by name - myCoefName='cm'<br>
<select ng-model="myCoefName"
ng-options="coef.name as coef.name for coef in coefs">
</select><br>
now myCoefName='{{myCoefName}}'
</div>
</body>

Creating parent div inside ng-repeat

I have 25 items from JSON string. Each item comes with a key called "InRowPlcement" and the value is assigned as "0" or "1" or "2" so on.
{"ItemID":"516","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"514","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"546","ItemName":"Underworld Lives","InRowPlcement":0},
{"ItemID":"527","ItemName":"In a holiday beach","InRowPlcement":1},
{"ItemID":"542","ItemName":"Underworld Lives","InRowPlcement":1},
{"ItemID":"525","ItemName":"Lake somewhere","InRowPlcement":1},
{"ItemID":"540","ItemName":"Coral Structure at Andaman","InRowPlcement":1},
{"ItemID":"569","ItemName":"Ice Rock, Ireland","InRowPlcement":2}
The intention is, placed the "0" "InRowPlacement" items in the first row, "1" in the second row, "2" in the third row and so on. The number of items may vary in each row. It may possible from 1 to 5 in a single row.
I started the ng-repeat
<div class="ROW" ng-repeat="item in items">
<div class="COLUMN">{{item.ItemName}}<div>
</div>
I need the result should be like
<div class="ROW">
<div class="COLUMN">Newzeland Lake Tysonno<div>
<div class="COLUMN">Newzeland Lake Tysonno<div>
<div class="COLUMN">Underworld Lives<div>
</div>
<div class="ROW">
<div class="COLUMN">In a holiday beach<div>
<div class="COLUMN">Underworld Lives<div>
<div class="COLUMN">Lake somewhere<div>
<div class="COLUMN">Coral Structure at Andaman<div>
</div>
Thanks in advance for your help.
SOLUTION UPDATE:
Based on the logic provided by #vp_arth, here is the actual code, which works for me
var view_rows = {};
angular.forEach(response.data, function(InRowPlcement,index){
if (!view_rows[response.data[index].InRowPlcement]) view_rows[response.data[index].InRowPlcement] = [];
view_rows[response.data[index].InRowPlcement].push(response.data[index]);
});
groups = view_rows;
This can be done with bunch of filters, but much better just prepare your data structure for view layer in the controller.
In your controller:
let data = [
{"ItemID":"516","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"514","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"546","ItemName":"Underworld Lives","InRowPlcement":0},
{"ItemID":"527","ItemName":"In a holiday beach","InRowPlcement":1},
{"ItemID":"542","ItemName":"Underworld Lives","InRowPlcement":1},
{"ItemID":"525","ItemName":"Lake somewhere","InRowPlcement":1},
{"ItemID":"540","ItemName":"Coral Structure at Andaman","InRowPlcement":1},
{"ItemID":"569","ItemName":"Ice Rock, Ireland","InRowPlcement":2}
];
let view_rows = {};
data.forEach(row => {
if (!view_rows[row.InRowPlcment]) view_rows[row.InRowPlcment] = [];
view_rows[row.InRowPlcment].push(row);
});
$scope.groups = view_rows;
Then, in view:
<div class="ROW" ng-repeat="(i, rows) in groups">
<div class="COLUMN" ng-repeat="row in rows">{{row.ItemName}}<div>
</div>
You could add the expression in DOM using ng-if to breakdown the items.
<div class="ROW" ng-repeat="item in items">
<div ng-if ="item.InRowPlcement == 0">
<div class="COLUMN">{{item.ItemName}}<div>
</div>
<div ng-if ="item.InRowPlcement == 1">
<div class="COLUMN">{{item.ItemName}}<div>
</div>
<div ng-if ="item.InRowPlcement == 2">
<div class="COLUMN">{{item.ItemName}}<div>
</div>
</div>
Working Plunker: https://plnkr.co/edit/vFR6NUIu6Uyl8XSOTiax?p=preview
I have written the below code as per your requirement and believe that it would work as per your requirement.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.8/angular-filter.js"></script>
<script>
var mainModule = angular.module('mainModule', ['angular.filter']);
mainModule.controller('mainCntrl', function($scope) {
$scope.items = [
{"ItemID":"516","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"514","ItemName":"Newzeland Lake Tysonno","InRowPlcement":0},
{"ItemID":"546","ItemName":"Underworld Lives","InRowPlcement":0},
{"ItemID":"527","ItemName":"In a holiday beach","InRowPlcement":1},
{"ItemID":"542","ItemName":"Underworld Lives","InRowPlcement":1},
{"ItemID":"525","ItemName":"Lake somewhere","InRowPlcement":1},
{"ItemID":"540","ItemName":"Coral Structure at Andaman","InRowPlcement":1},
{"ItemID":"569","ItemName":"Ice Rock, Ireland","InRowPlcement":2}
];
});
</script>
</head>
<body ng-app="mainModule">
<div ng-controller="mainCntrl">
<ul ng-repeat="(key, value) in items | groupBy: 'InRowPlcement'">
<div class="ROW">
<div class="COLUMN" ng-repeat="item in value">
{{ item.ItemName }}
</li>
</div>
</ul>
</div>
</body>
</html>

Can I get the value from the key from ng-repeat x in xx | unique x.key

I have a collection of items that represent a grouping by one property. I want to create a list of items grouped by the value of this property and in each list present the value of this group once and then all the items that belong to the group.
Something like the following
<div ng-repeat="items in itemcollection | unique: 'groupkey'">
<h3>{{items.groupkey}}</h3>
<div ng-repeat="item in items">
<label>{{item.name}}</label>
</div>
</div>
So if I have a itemscollection like the following:
{{ groupkey: 1; name: 'Ada'}, { groupkey: 1; name: 'Beda'}, {groupkey: 2; name: 'Ceda'}}
So after the generation of divs and labels the result should be
<div>
<h3>1</h3>
<div><label>Ada</label></div>
<div><label>Beda</label></div>
</div>
<div>
<h3>2</h3>
<div><label>Ceda</label></div>
</div>
Is it possible to create this or do I need to handle the creating of the elements to better construct the data to make this happen?
This filter does what you want : https://github.com/a8m/angular-filter#groupby
Yes. Its possible by the combination of orderBy and filter function in angularJS. The following code will work :
var app = angular.module("myApp", []);
app.controller("lists", function($scope) {
$scope.list = [{
groupkey: 1,
name: 'Ada'
}, {
groupkey: 1,
name: 'Beda'
}, {
groupkey: 2,
name: 'Ceda'
}];
});
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
</head>
<body>
<div ng-controller="lists">
<div ng-repeat="items in list | orderBy:'groupkey'">
<h3>{{items.groupkey}}</h3>
<label>{{items.name}}</label>
</div>
</div>
</body>
</html>
Hope it works for you :)
Not tested but something like this I guess should work
<div ng-repeat="items in itemcollection | unique: 'groupkey'">
<h3>{{items.groupkey}}</h3>
<div ng-repeat="item in items | filter:{'groupkey': items.groupkey}:true">
<label>{{item.name}}</label>
</div>
</div>
If you make sure the itemcollection is sorted by groupkey you may display the groupkey header only when the groupkey differs from the previous groupkey. Then you achieve to only show the groupkey header once per group. Here is an example:
angular.module('myapp',[]).controller("thectrl", function($scope) {
$scope.itemcollection = [{ groupkey: 1, name: 'Ada'},
{ groupkey: 1, name: 'Beda'},
{groupkey: 2, name: 'Ceda'},
{groupkey: 2, name: 'D'}];
$scope.itemcollection.sort(function(a,b) { return a.groupkey-b.groupkey;});
});
The HTML:
<div ng-app="myapp" ng-controller="thectrl">
<div ng-repeat="item in itemcollection track by $index" >
<h3 ng-if="$index===0 || itemcollection[$index-1].groupkey!==item.groupkey">{{item.groupkey}}</h3>
<label>{{item.name}}</label>
</div>
</div>
And a working fiddle here:
https://jsfiddle.net/vuksyeyh/

Resources