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
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.
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 .
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."
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.
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)" />