Generating table from json in AngularJS - javascript

I'm trying to generate HTML table from json in AngularJS.
I receive JSON in format like this:
My Service for getting the data looks like this :
customAPI.getUsers = function() {
return $http({
method: 'JSONP',
url: 'http://arka.foi.hr/WebDiP/2013_projekti/WebDiP2013_069/api/admin/users.php'
});
};
and controller for that code looks like this
controller('usersController', function($scope, customAPIservice) {
$scope.filterName = null;
$scope.usersList = [];
/*Search*/
$scope.searchFilter = function(user) {
var keyword = new RegExp($scope.filterName, 'i');
return !$scope.filterName || keyword.test(user.korisnici.korisnik_ime) || keyword.test(user.korisnici.korisnik_prezime);
};
customAPIservice.getUsers().success(function(response) {
$scope.usersList = response.korisnici;
});
});
and my view looks like this :
<input type="text" ng-model="nameFilter" placeholder="Trazi..."/>
<h2 >Korisnici</h2>
<table>
<thead>
<tr>
<th colspan="6">Korisnici sustava</th>
</tr>
<th>Surname</th>
</thead>
<tbody>
<tr ng-repeat="user in usersList| filter: searchFilter">
<td>{{$index + 1}}</td>
<td>{{user.korisnik.korisnik_prezime}}</td>
<td>{{user.korisnik.korisnik_username}}</td>
</tr>
<tr ng-show="usersList == ''">
<td colspan="5">
<img src="img/ajax-loader.gif" />
</td>
</tr>
</tbody>
</table>
I think I messed up somewhere with binding the data with the view but I' still pretty new with angular so I can't find what is wrong. Also I've looked up over internet and couldn't find anything.Please help.

You are not correctly access the properties in your data. Use:
/*Search*/
$scope.searchFilter = function(user) {
var keyword = new RegExp($scope.filterName, 'i');
return !$scope.filterName || keyword.test(user.korisnik.korisnik_ime) || keyword.test(user.korisnik.korisnik_prezime);
};

Related

Knockout.js get property of an object for location.href

i recently discover Knockout and i'm struggling for getting properties of an object in a foreach:
Here is my code :
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Created By</th>
</tr>
</thead>
<tbody data-bind="foreach: assets">
<tr class="assets" data-bind="click: $parent.detailPage">
<td>
<span data-bind="text: FileName"></span>
</td>
<td>
<span data-bind="text: CreatedBy"></span>
</td>
</tr>
</tbody>
and my script :
<script>
function ViewModel(assets) {
var self = this;
self.assets = assets;
self.detailPage = function (asset) {
location.href = '#Url.Action("Details", "Assets")/' + asset.Id;
};
};
var jsonModel = new ViewModel(#Html.Raw(Json.Encode(Model)));
var viewModel = ko.mapping.fromJS(jsonModel);
ko.applyBindings(viewModel);
In my assets, i have an id and i would like to open my view using the id of the object i click on.
But when i execute that, the url become : http://localhost:62677/Assets/Details/[object Object]
Any idee for doing this properly ?
Thanks !
Assuming that asset.Id is a knockout observable, try this
self.detailPage = function (asset) {
location.href = '#Url.Action("Details", "Assets")/' + asset.Id();
};
Looks like asset.Id is an object.
Try to investigate why it is object and not some number or string.

How to use Jquery Datatable with AngularJs to export table

I am working on angular website where I need to export table's data to pdf.
I want to use jQuery datatables for it as it alse add some more features like paging,searching and sorting, but getting this error "Error: [$injector:unpr]" on browser's console, even I am not sure using ng-table will make it to datatable or not.
I have also tried using jquery plugin pdfmake but it only make signle page pdf and failed if table have larger data.
Please help and TIA.
Html :-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ng-table/1.0.0/ng-table.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/1.0.0/ng-table.min.js"></script>
<table id="myYealyGrid" ng-class="myYealyGridClass" class="table table-responsive gridtable" ng-table="yearly_Table">
<thead>
<tr>
<th>Customer Name</th>
<th>Year</th>
<th>Total Amount($)</th>
</tr>
</thead>
<tbody>
<tr ng-show="YearlyReport.length !=0" ng-repeat="reportrow in YearlyReport" ng-init="setTotal(reportrow)">
<td>{{reportrow.CustomerName}}</td>
<td>{{reportrow.Month}}</td>
<td>{{reportrow.TotalAmount}}</td>
</tr>
<tr ng-show="YearlyReport.length ==0">
<td><small class="nodata">No data found.</small></td>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr ng-show="YearlyReport.length !=0" class="bg-warning">
<td class="td-font-bold-custm">Total</td>
<td></td>
<td class="td-font-bold-custm">{{gridTotalAmount | number:2}}</td>
</tr>
</tfoot>
</table>
AngularJs:-
var appKitchenOrderReport = angular.module("myKitchenOrderReportApp", ['ngTable']);
appKitchenOrderReport.controller("myKitchenOrderReportCntrl", function ($scope, $window, $timeout, myKitchenOrderReportService, ngTableParams) {
var getData = myKitchenOrderReportService.SearchData($scope.CustomerName, $scope.Year);
getData.then(function (kitchenreportdata) {
var yearlyGridData = kitchenreportdata.data.OrderYearlyReport;
$scope.yearly_Table = new ngTableParams({
page: 1,
count: 10
}, {
total: $scope.yearlyGridData.length,
getData: function ($defer, params) {
$scope.YearlyReport = $scope.yearlyGridData.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.YearlyReport);
}
});
}, function () {
alert('Error in getting data');
});
});
appKitchenOrderReport.service("myKitchenOrderReportService", function ($http) {
this.getKitchenOrderReportData = function () {
var response = '';
return $http.get("GetOrderReport"); };
this.SearchData = function (CustomerName, Year)
{
var GetParams = new Object();
GetParams.CustomerName = CustomerName;
GetParams.Year = Year
var response = $http({
method: "post",
url: "GetOrderReport",
data: '{model: ' + JSON.stringify(GetParams) + '}',
});
return response;
}
});
you can Use $('#myYealyGrid').DataTable(); to initialize your datatable .
But Use just befor , when you Put data into the HTML table .
It will automatically initialize your Datatable.
Try it and let me know is it working or not .

AngularJS view not updated after model updates

New to Angular, I am trying to save a form and update the view after calling a PUT or POST call to the backend. Once I receive an OK status from the backend, I am updating my models with the latest response. But only the model in the directive "ng-click" gets updated but others do not. Here is my code:
///HTML
<table class="footable table table-stripped toggle-arrow-tiny" data-page-size="8">
<thead>
<tr>
<th data-toggle="all">Release Title</th>
<th data-hide="all">Release Genre</th>
<th data-hide="all">UID</th>
<th data-hide="all">Classical</th>
<th data-hide="all">Tracks</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="album in vm.albums" footable>
// This one (album.data.title) gets updated but the other ones do not
<td ng-click="vm.editAlbum(album, $index)">{{album.data.title}}</small></td>
<td>{{album.data.genre}}</td>
<td>{{album.data.uid}}</td>
<td ng-if!="album.data.classical">No</td>
<td ng-if="album.data.classical">Yes</td>
<td>
<li ng-repeat="track in album.data.tracks">
<a ng-click="vm.selectTrack(album, track)">{{track.title}}</a>
</li>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<ul class="pagination pull-right"></ul>
</td>
</tr>
</tfoot>
</table>
Here is my controller:
// controller.js (Just pasting the saveRelease method that does the on-click event handling in HTML:
(function (){
angular.module('app.uploadedReleases').controller('UploadedReleasesController', UploadedReleasesController);
UploadedReleasesController.$inject = ['$http', '$log', '$scope', '$state', '$rootScope', 'APP_CONFIG'];
function UploadedReleasesController ($http, $log, $scope, $state, $rootScope, APP_CONFIG){
var vm = this;
vm.albums = []; // list of all albums
vm.albumPriority = [0, 4, 6, 8, 10];
vm.getAlbumTracks = getAlbumTracks;
vm.editAlbum = editAlbum;
vm.selectTrack = selectTrack;
vm.selected = {};
vm.saveRelease = saveRelease;
vm.testingAlbumSelected = false;
return init();
function init(){
$http.get('http://localhost:8080/api/releases').then(function(responseData){
//check the status from the response data.
vm.responseStatus = responseData.status;
if(vm.responseStatus !== 200){
//error message
}
// else, Parse the json data here and display it in the UI
for(var album in responseData.data){
vm.albums.push({slug: album, data: responseData.data[album]});
}
})
}
function getAlbumTracks(slug, index){
$http.get('http://localhost:8080/api/releases/' + slug).success(function(trackResponse){
//parse each album and get the track list
vm.showingAlbumIndex = index;
vm.albums.tracks = [];
vm.selected = {};
vm.selected.album = vm.albums[index];
vm.testingAlbumSelected = true;
for(var i = 0; i<trackResponse.tracks.length; i++) {
vm.albums.tracks.push(trackResponse.tracks[i]);
}
$log.debug(vm.albums.tracks);
vm.formAlbum = new Album(vm.selected.album.data.upc,
vm.selected.album.data.title,
vm.selected.album.data.label,
vm.selected.album.data.genre,
vm.selected.album.data.releaseType,
vm.selected.album.data.holdDate,
vm.selected.album.data.priority,
vm.selected.album.data.memo);
})
}
function selectTrack(album, track){
vm.selected.album = album;
vm.selected.track = track;
vm.testingAlbumSelected = false;
}
function editAlbum(album, index){
getAlbumTracks(album.slug, index);
vm.selected = album;
}
function saveRelease(){
// Call the PUT request to update the release metadata and refresh the page
// so that the Album list gets updated with the latest changes
var url = 'http://localhost:8080/api/releases/' + vm.selected.album.slug;
$http.put(url, vm.formAlbum).then(function(saveAlbumResponse){
if(saveAlbumResponse.status === 202){
//successfully saved response on backend
// Update the current models to show the newer data
vm.album.data = vm.formAlbum;
console.log("album array vm.albums = "+vm.albums);
}
})
}
})();
Any idea why ?
try remove "var vm=this" line. And rename vm.xxxx to $scope.xxxx in your controller.
in the view: remove the "vm."

Meteor returning NaN in the browser

I'm building a simple ordering app in Meteor and have come a cropper trying to get the order total even though I can get it to log in the console as a bona fide number - it is being rendered as NaN. Any help would be greatly appreciated.
Note the totals of individual products are appearing fine.
I have the following files:
meteorder/client/templates/orders/order_build.js:
Template.order.helpers({
'orderitems': function() {
var orderCart = [];
var orderItems = OrderItems.find({});
var total = 0;
orderItems.forEach(function(orderItem) {
var item = _.extend(orderItem, {});
var product = Products.findOne({
_id: orderItem.product
});
orderItem.productname = product.description;
orderItem.price = (Number(product.price) * orderItem.qty);
total += orderItem.price;
orderCart.push(orderItem);
});
orderCart.subtotal = total;
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
})
meteorder/client/templates/orders/order_build.html:
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderitems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
</tbody>
</table>
</template>
meteorder/client/lib/main.js:
Template.registerHelper('currency', function(num){
return '€' + Number(num).toFixed(2);
});
meteorder/server/server.js:
Meteor.methods({
addToOrder:function(qty,product,session){
check(qty, Number);
check(product, String);
check(session, String);
if(qty > 0){
OrderItems.insert({qty:qty,product:product,sessid:session});
console.log('reaching this fn', typeof qty, typeof product, typeof session);
} else{
console.log('Quantity is Zero');
}
},
removeOrderItem:function(id){
check(id, String);
OrderItems.remove({_id:id});
console.log('successfully deleted');
}
});
Here is a link to the GitHub repo
And the latest version of the deployed App
Thanks in advance!
Edit:
Just adding this in for Matthias:
Template.productItem.events({
'click .addOrder':function(evt,tmpl){
var qty1 = tmpl.find('.prodqty').value;
var qty = parseInt(qty1);
var product = this._id;
var sessid = Meteor.default_connection._lastSessionId; //stops others adding to your cart etc
Meteor.call('addToOrder',qty, product, sessid);
console.log('this is the quantity:', typeof qty, product, sessid);//stops others ad
}
});
to see if it gives a better picture of why the cart is not populating. Thanks
You're trying to use orderCart as both an array of objects and an object. You push a bunch of orderItem objects on to the array but at the end you attempt to set orderCart.subtotal etc...
Change your helper to have a separate summary object:
var summary = {};
summary.subtotal = total;
summary.tax = summary.subtotal * .23;
summary.total = summary.subtotal + summary.tax;
return {items: orderCart, summary: summary}
Then in your html do:
{{#each orderitems.items}}
...
{{/each}}
Finally in your summary line use {{currency orderitems.summary.tax}} etc...
Your values are rendered as NaN because orderCart is undefined.
You could define a separate helper to fix your code:
Template.order.helpers({
orderItems: function () {
return OrderItems.find().map((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) {
orderItem.productname = product.description;
orderItem.price = calcPrice(product, orderItem);
return orderItem;
}
});
},
orderCart: function () {
let orderCart = {subtotal: 0};
OrderItems.find().forEach((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) orderCart.subtotal += calcPrice(product, orderItem);
});
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
});
function calcPrice(product, orderItem) {
return (Number(product.price) * orderItem.qty);
}
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderItems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
{{#with orderCart}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
{{/with}}
</tbody>
</table>
</template>
Please note: I noticed a lot of missing semicolons. I strongly recommend to fix that, as this may cause several issues on deployment due to Meteor's minifying process.

Can't fetch single record in Angular js/HTML

Hope you are doing good..
I'm trying to fetch single record from datasource by Id in UI via Angular-js.
Using Web-API for retrieving values from DB.
To make it simple : HTML-->Angular-->WebAPI-->DB
When i'm trying it says Id passed is Null..Don't know how to rectify.
hope i've missed to fill hole in somewhere....below snippets fr ref.
(Also can u verify/correct me the way i've coded in html is right way to display values fetched by Id)
HTML :
<div ng-controller="SingleController">
<input type="text" ng-model="_Id" />
<input type="button" value="search" ng-click="search()" />
<table>
<tr>
<td>MovieId</td>
<td>{{MovID}}</td>
</tr>
<tr>
<td>Title</td>
<td>{{Movtitle}}</td>
</tr>
<tr>
<td>Genre</td>
<td>{{Movgnre}}</td>
</tr>
<tr>
<td>Classification</td>
<td>{{Movcls}}</td>
</tr>
<tr>
<td>ReleaseDate</td>
<td>{{Movdate}}</td>
</tr>
<tr>
<td>Rating</td>
<td>{{Movrate}}</td>
</tr>
<tr>
<td>Cast</td>
<td>{{Cast}}</td>
</tr>
</table>
</div>
Controller.JS
app.controller('SingleController', function ($scope, MyService) {
var Id = $scope._Id;
$scope.search = function (Id) {
var promiseGetSingle = MyService.getbyId(Id);
promiseGetSingle.then(function (pl) {
var res = pl.data;
$scope.MovID = res._movieId;
$scope.Movtitle = res._title;
$scope.Movgnre = res._genre;
$scope.Movcls = res._classification;
$scope.Movdate = res._releaseDate;
$scope.Movrate = res._rating;
$scope.Cast = res._cast;
// $scope.IsNewRecord = 0;
},
function (errorPl) {
console.log('failure loading Employee', errorPl);
});
}
});
service.js
this.getbyId = function (Id) {
return $http.get("/api/values/" + Id);
};
Please ignore this lengthy snippets.
Could you please help me on this.
Your search function is expecting you to pass a value when it is invoked on ng-click:
<input type="button" value="search" ng-click="search(_Id)" />

Categories