creating a table using ng-repeat from JSON - angularjs

I have just started using Angular for my project. The task at hand, is I need to generate a table from JSON. I was able to do this by hardcoding everything, but the project changed in a way that now I am required to use JSON. I would like to use ng-repeat. My data structure is an array of objects with nested objects that represent the business and the hours. I am getting weird behavior and I'm wondering if it is my data structure causing it.
I created a fiddle. Any advice would be greatly appreciated.
My data structure looks like this:
var dept = {
sales : { startTime : "", endTime : "" },
service : { startTime : "", endTime : "" },
accounting : { startTime : "", endTime : "" },
parts : { startTime : "", endTime : "" },
bodyShop : { startTime : "", endTime : "" },
other : { startTime : "", endTime : "" },
};
The objects are nested inside an array and each index represents a day of the week. For example, index 1 would be Monday.
<tr ng-repeat="hours in businessHours">
<td>Monday</td>
<td>{{hours[0].startTime}}</td>
<td>{{hours[0].endTime}}</td>
<td>{{hours[0].startTime}}</td>
<td>{{hours[0].endTime}}</td>
<td>{{hours[0].startTime}}</td>
<td>{{hours[0].endTime}}</td>
</tr>
I created a fiddle to give a better picture
`http://jsfiddle.net/yu216x5w/4/`

You can try something like this:
var hours = [
{
"name" : "Monday",
"hours": {
"sales" : { startTime : "5", endTime : "6" },
"service" : { startTime : "2", endTime : "3" },
"accounting" : { startTime : "4", endTime : "6" },
"parts" : { startTime : "10", endTime : "11" },
"bodyShop" : { startTime : "3", endTime : "8" },
"other" : { startTime : "a", endTime : "b" }
}
},
{
"name" : "Tuesday",
"hours": {
"sales" : { startTime : "5", endTime : "6" },
"service" : { startTime : "2", endTime : "3" },
"accounting" : { startTime : "4", endTime : "6" },
"parts" : { startTime : "10", endTime : "11"},
"bodyShop" : { startTime : "3", endTime : "8" },
"other" : { startTime : "a", endTime : "b" }
}
}
];
var mockDataForThisTest = "json=" + encodeURI(JSON.stringify(hours));
var app = angular.module('myApp', []);
function businessHours($scope, $http) {
$scope.schedule = [];
$scope.loadHours = function() {
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: mockDataForThisTest
}).success(function(data, status) {
console.log(data);
$scope.schedule = data;
});
};
}
with:
<div ng-app="myApp">
<div ng-controller="businessHours">
<p> Click <a ng-click="loadHours()">here</a> to load data.</p>
<table>
<tr>
<th></th>
<th style="vertical-align:top" scope="col" colspan="2">Sales</th>
<th style="vertical-align:top" scope="col" colspan="2" >Service</th>
<th style="vertical-align:top" scope="col" colspan="2">Parts</th>
<th style="vertical-align:top" scope="col" colspan="2">Accounting</th>
<th style="vertical-align:top" scope="col" colspan="2">Body Shop</th>
<th style="vertical-align:top" scope="col" colspan="2" >Other</th>
</tr>
<tr ng-repeat="day in schedule">
<td>{{day.name}}</td>
<td>{{day.hours.sales.startTime}} - {{day.hours.sales.endTime}}</td>
<td>{{day.hours.service.startTime}} - {{day.hours.service.endTime}}</td>
<td>{{day.hours.accounting.startTime}} - {{day.hours.accounting.endTime}}</td>
<td>{{day.hours.parts.startTime}} - {{day.hours.parts.endTime}}</td>
<td>{{day.hours.bodyShop.startTime}} - {{day.hours.bodyShop.endTime}}</td>
<td>{{day.hours.other.startTime}} - {{day.hours.other.endTime}}</td>
</tr>
</table>
</div>
http://jsfiddle.net/yu216x5w/7/

Related

ng-repeat with some conditions

I have a JSON which has the property prizes which in some cases is like this:
"prize" : {
"Firstyear" : {
"first" : 3000,
"second" : 2000,
"total" : 5000
},
"Secondyear" : {
"first" : 3000,
"second" : 2000,
"total" : 5000
},
"Thirdyear" : {
"first" : 3000,
"second" : 2000,
"total" : 5000
},
"total" : 15000
},
but in some cases, it's like this:
"prize" : {
"first" : 4000,
"second" : 3000,
"third" : 2000,
"total" : 9000
},
How do I ng-repeat over these?
You cannot do ng-repeat over Object unless you want to get the key and value of an object. I guess you need the following.
DEMO
var uniqcApp = angular.module('uniqueApp',[]);
uniqcApp.controller('testController', function ($scope){
$scope.data = {"prize" : {
"first" : 4000,
"second" : 3000,
"third" : 2000,
"total" : 9000
}};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="uniqueApp">
<div class="row" ng-controller="testController">
<table>
<tr ng-repeat="(key, value) in data.prize">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
</table>
</div>
</body>

AngularJS | how to orderBy with a multidimensional Object?

I want to get my ng-repeat to be ordered by rank, how would I write the expression?
<div ng-app="myApp" ng-controller="orderCtrl">
<ul>
<li ng-repeat="(key, value) in cars | orderBy: cars[key].rank ">
{{cars[key].longName}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('orderCtrl', function($scope) {
$scope.cars = {
"BTC" : {
"longName" : "Bitcoin",
"rank" : 1
},
"BCH" : {
"longName" : "Bitcoin Cash",
"rank" : 3
},
"ETH" : {
"longName" : "Ethereum",
"rank" : 2
},
"ETC" : {
"longName" : "Ethereum Classic",
"rank" : 15
},
"IOTA" : {
"longName" : "IOTA",
"rank" : 4
},
"XRP" : {
"longName" : "Ripple",
"rank" : 6
},
"XVG" : {
"longName" : "Verge",
"rank" : 5
}
};
});
</script>
Order by can only be applied to arrays and not objects. You must convert your object to an array or create your own filter : https://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/

Meteor: How to structure Mongo data from Google Sheets

The BSON data list contains very unneeded values as shown below. The problem am I having is returning an array subset from Mongo so that I could display it in a template using Meteor.
Mongo stores the data as such:
meteor:PRIMARY> db.ga_spreadsheet.find().pretty()
{
"_id" : "7YLifh9C6Gp8HPCTm",
"spreadsheet" : "NBATEST",
"header" : null,
"cells" : {
"1" : {
"1" : {
"row" : "1",
"col" : "1",
"value" : "name"
},
"2" : {
"row" : "1",
"col" : "2",
"value" : "position"
},
"3" : {
"row" : "1",
"col" : "3",
"value" : "salary"
& client/view.js does the pull request
GASpreadsheet = new Mongo.Collection('GASpreadsheet');
if (Meteor.isClient) {
Meteor.call("spreadsheet/fetch","1kdRtyhrvXN1aEf35NwtA8pzHfjc9-lNwV76CE_Zr_g");
spreadsheetData = GASpreadsheet.findOne({spreadsheet: 'NBATEST'})
Template.nba.helpers({
'player': function(){
var currentUserId = Meteor.userId();
return GASpreadsheet.find({ createdBy: currentUserId },
{ sort: {score: -1, name: 1} });
},
cellState: function(x, y) {
if(screenArray[x][y] === 1){
return 'live';
}
else {
return 'dead';
}
},
'selectedClass': function(){
var playerId = this._id;
var selectedPlayer = Session.get('selectedPlayer');
if(playerId == selectedPlayer){
return "selected"
}
},
'selectedPlayer': function(){
var selectedPlayer = Session.get('selectedPlayer');
return GASpreadsheet.findOne({ _id: selectedPlayer });
}
});
}
view/main.html
<template name="nba">
<div class="gridWrapper">
{{#each row in rows}}
<div class="row">
{{#let rowIndex=#index}}
{{#each cell in row}}
<div class="cell {{cellState rowIndex #index}}">{{this}}</div>
{{/each}}
{{/let}}
</div>
{{/each}}
</div>
</template>

Angular filters: search two categories of many

I've been trying to think of a way to search products by Name AND Producer, not just one of them. Looking through documentation, I found how to tie search filter to one kind, but not multiple (not all).
For example, if I have a list of persons with names, surnames and phone numbers, I'd like to be able to search through only name and surname in one input field. If I type in my search field, this model will look for a match in Name and Producer. How do I achieve this?
Thank you in advance!
My code above.
HTML:
<div>
<label>Search</label>
<input ng-model="query" type="text" placeholder="Search for name or producer" autofocus>
<label>
</div>
<table>
<tr>
<td>Name</td>
<td>Producer</td>
<td></td>
<td>Type</td>
<td>Packaging</td>
<td>Is it alcoholic?</td>
<td>Volume</td>
<td>Popularity</td>
<td>Country</td>
<td>Added</td>
<td>Price</td>
</tr>
<tr ng-repeat="item in products | filter:query | orderBy: drinkOrder:direction">
<td>{{item.name}}</td>
<td>{{item.producer}}</td>
<td><img ng-src="img/{{item.picture}}.jpg" alt="{{item.name}}" height="50px"></td>
<td>{{item.type}}</td>
<td>{{item.packaging}}</td>
<td>{{item.alko}}</td>
<td>{{item.volume}}</td>
<td>{{item.popularity}}</td>
<td>{{item.country}}</td>
<td>{{item.added}}</td>
<td>{{item.price}}</td>
</tr>
</table>
JS file app.js:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', ['$scope', '$http', function ($scope, $http) {
$http.get('/lynda/ithouse/js/data.json').success(function(data) {
$scope.products = data;
$scope.drinkOrder = 'popularity';
});
}]);
JSON file:
[
{
"name" : "Sample Beer",
"producer" : "Great Beer Producer",
"picture" : "two",
"type" : "beer",
"packaging" : "glass",
"alko" : "yes",
"volume" : "1",
"popularity" : "1",
"country" : "Latvia",
"added" : "2015-01-03",
"price" : "20,40"
},{
"name" : "Sample Cider",
"producer" : "Great Cider Producer",
"picture" : "one",
"type" : "cider",
"packaging" : "plastic",
"alko" : "yes",
"volume" : "2",
"popularity" : "3",
"country" : "Estonia",
"added" : "2015-01-03",
"price" : "20,40"
},{
"name" : "Best Wine",
"producer" : "Wine for You",
"picture" : "eight",
"type" : "wine",
"packaging" : "glass",
"alko" : "yes",
"volume" : "2",
"popularity" : "5",
"country" : "Lithuania",
"added" : "2015-01-03",
"price" : "20,40"
},{
"name" : "Another Beer",
"producer" : "Beer Land",
"picture" : "seven",
"type" : "beer",
"packaging" : "aluminium",
"alko" : "no",
"volume" : "4",
"popularity" : "2",
"country" : "Latvia",
"added" : "2015-05-03",
"price" : "21,40"
}
]
You can create your own custom filter like below
Filter
.filter('customFilter', function() {
return function(query) {
var out = [];
angular.forEach($scope.products, function(value, key) {
if (value['name'] == query || value['producer'] == query)
this.out.push(value)
})
return out;
}
});
Fiddle Here

Angular JS Order By Filter not working for dynamic predicates

I am creating a Grid Control in Angular JS. ( I don't want to use ng-grid, smart table, etc for some reason)
Plunkr URL : http://plnkr.co/edit/arkCZcfXTIsW7sFCxisn?p=preview
On top of the table generated, i have populated fields in the combobox so that user is allowed to search on specific columns
or as free search.
As I see From here :
https://docs.angularjs.org/api/ng/filter/filter
For free search, I have used the syntax as {$:Value} and for column based search, {ColName:Value} syntax
However, I am unable to get it to work when I bind the column names to combobox.
I do get static search to work Eg if I write {'Code':"1"}, this works. but if I take "Code" from a combobox, it doesnt work.
Need help on setting dynamic filter.
This one also does not seem to help.
angular filter with dynamic list of attributes to search
This is the HTML
<div ng-controller="MyGrid">
Search in Column
<select ng-model="FilterByColumn" >
<option value="$">All</option>
<option ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible" value="{{hdr.name}}" >
{{hdr.caption}}
</option>
</select>
Value : <input type="text" ng-model="searchKeyword" />
<br />
Remove Sort
<table>
<thead>
<tr>
<th ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{hdr.caption}}
</th>
</tr>
</thead>
<tbody>
<%--<tr ng-repeat="dataVal in data | filter: {FilterByColumn : searchKeyword} | orderBy:predicate:reverse "> **Does not work--%>**
<%--<tr ng-repeat="dataVal in data | filter: {$ : searchKeyword} | orderBy:predicate:reverse "> **This works--%>**
<tr ng-repeat="dataVal in data | filter: GetFilter (FilterByColumn, searchKeyword) | orderBy:predicate:reverse "> **<!-- Does not work -->**
<td ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{dataVal[hdr.name]}}
</td>
</tr>
</tbody>
</table>
<pre>Sorting predicate = {{predicate}}; reverse = {{reverse}} ; SearchBy = {{FilterByColumn}} ; Search Key : {{searchKeyword}} </pre>
</div>
This is the JS :
'use strict';
var MyApp = angular.module('MyApp', []);
MyApp.controller('MyGrid', function ($scope) {
$scope.predicate = 'Code';
$scope.reverse = false;
$scope.FilterByColumn = '$';
$scope.headers = [
{
"name": "Code",
"caption": "Code",
"isVisible": true,
"displayOrder": 12
},
{
"name": "DispName",
"caption": "My Name",
"isVisible": true,
"displayOrder": 1
},
{
"name": "Locked",
"caption": "Islocked",
"isVisible": true,
"displayOrder": 2
}
];
$scope.data =
[{
"Code": "1",
"DispName": "abdul",
"Locked": "0"
},
{
"Code": "2",
"DispName": "Hemant",
"Locked": "0"
},
{
"Code": "3",
"DispName": "Rahul",
"Locked": "0"
},
{
"Code": "4",
"DispName": "Sandy",
"Locked": "0"
},
{
"Code": "5 ",
"DispName": "Nihal",
"Locked": "0"
},
{
"Code": "6",
"DispName": "Sachin",
"Locked": "0"
},
{
"Code": "7",
"DispName": "abdul f",
"Locked": "0"
},
{
"Code": "8",
"DispName": "abdul g",
"Locked": "0"
},
{
"Code": "9",
"DispName": "abdul h ",
"Locked": "0"
},
{
"Code": "10",
"DispName": "abdul i",
"Locked": "0"
}
];
$scope.getValue = function (obj, PropName) {
return obj[PropName];
};
$scope.SetSort = function (objName) {
//alert(objName);
$scope.predicate = objName;
$scope.reverse = !$scope.reverse;
};
$scope.GetFilter = function (srchCol, Srchval) {
//alert(srchCol);
//alert(Srchval);
if (srchCol == "") {
return { $: Srchval };
}
else {
return { srchCol: Srchval };
}
};
});
That is because when you write { srchCol: Srchval } - srcCol is the property name and is not substituted with the value in variable srcCol, try this syntax instead:
$scope.GetFilter = function (srchCol, Srchval) {
if (srchCol == "") {
return { $: Srchval };
}
else {
filter = {};
filter[srchCol] = Srchval;
return filter;
}
};

Resources