Angular Smart table doesn't works - javascript

I am trying to use Angular Smart table. But I get this error message in the browser.
Error: [ng:areq] http://errors.angularjs.org/1.3.9/ng/areq?p0=safeCtrl&p1=not%20aNaNunction%2C%20got%20undefined
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:6:416
at Qb (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:19:417)
at sb (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:20:1)
at $get (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:76:95)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:57:257
at s (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:7:408)
at v (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:57:124)
at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:52:9)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js:51:118
This is my HTML
<div ng-controller="safeCtrl">
<button type="button" ng-click="addRandomItem(row)" class="btn btn-sm btn-success">
<i class="glyphicon glyphicon-plus">
</i> Add random item
</button>
<table st-table="displayedCollection" st-safe-src="rowCollection" class="table table-striped">
<thead>
<tr>
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
<th st-sort="birthDate">birth date</th>
<th st-sort="balance">balance</th>
</tr>
<tr>
<th colspan="5"><input st-search="" class="form-control" placeholder="global search ..." type="text" /></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td>{{row.firstName}}</td>
<td>{{row.lastName}}</td>
<td>{{row.birthDate}}</td>
<td>{{row.balance}}</td>
<td>
<button type="button" ng-click="removeItem(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle">
</i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<script src="~/Scripts/CustomerView.js"></script>
and this is my Javascript:
angular.module('customerDetailTableApp', ['smart-table']).controller('safeCtrl', ['$scope', function($scope) {
var firstnames = ['Laurent', 'Blandine', 'Olivier', 'Max'];
var lastnames = ['Renard', 'Faivre', 'Frere', 'Eponge'];
var dates = ['1987-05-21', '1987-04-25', '1955-08-27', '1966-06-06'];
var id = 1;
function generateRandomItem(id) {
var firstname = firstnames[Math.floor(Math.random() * 3)];
var lastname = lastnames[Math.floor(Math.random() * 3)];
var birthdate = dates[Math.floor(Math.random() * 3)];
var balance = Math.floor(Math.random() * 2000);
return {
id: id,
firstName: firstname,
lastName: lastname,
birthDate: new Date(birthdate),
balance: balance
}
}
$scope.rowCollection = [];
for (id; id < 5; id++) {
$scope.rowCollection.push(generateRandomItem(id));
}
//copy the references (you could clone ie angular.copy but then have to go through a dirty checking for the matches)
$scope.displayedCollection = [].concat($scope.rowCollection);
//add to the real data holder
$scope.addRandomItem = function addRandomItem() {
$scope.rowCollection.push(generateRandomItem(id));
id++;
};
//remove to the real data holder
$scope.removeItem = function removeItem(row) {
var index = $scope.rowCollection.indexOf(row);
if (index !== -1) {
$scope.rowCollection.splice(index, 1);
}
}
}]);
I have tried with several ways, but couldn't find any solution. I have used ng-app inside html tag <html ng-app="myapp"> and controller in body tag <body ng-app="customerDetailTableApp">

You need to use only one ng-app into your view, and include(inject) your second dependency module into your first ng-app.
Multiple ng-app directives on a page
How many ng-App can be declared in in Angular JS?
angular.module('myapp', ['customerDetailTableApp']);

Related

smart-table slow performance while displaying large data set

Im trying to display large data set using smart-table. Im contacting server with $http request and when I assign response data to $scope.rowCollection, application stuck for nearly 40 second until all data is displayed on page. In response json i got nearly 18000 results to display. I dont know if I do something wrong. I get response from server in 600 ms but after assign application stuck. It looks like smart-table is trying to make a copy of response in displayedCollection array and this operation take long time but its only my opinion. Please help. Thanks in advance.
HTML
<table st-table="displayedCollection" st-safe-src="rowCollection" class="table">
<thead>
<tr>
<th colspan="8"><input st-search="" class="form-control" placeholder="global search ..." type="text" /></th>
</tr>
<tr>
<th st-sort="TestEndDate">Test Date</th>
<th st-sort="Workplace">Workplace</th>
<th st-sort="Tester">Worker</th>
<th st-sort="SerialNo">Serial Number</th>
<th st-sort="TestProgram">Testing program</th>
<th st-sort="TestResult">Test Result</th>
<th>Download</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in displayedCollection">
<td>{{row.TestEndDate | date}}</td>
<td>{{row.Workplace}}</td>
<td>{{row.Tester}}</td>
<td>{{row.SerialNo}}</td>
<td>{{row.TestProgram}}</td>
<td>{{row.TestResult}}</td>
<td>
<button type="button" ng-click="downloadItem(row)" class="btn btn-sm btn-success">
<i class="glyphicon glyphicon-download">
</i>
</button>
</td>
<td>
<button type="button" ng-click="detailItem(row)" class="btn btn-sm btn-primary">
<i class="glyphicon glyphicon-eye-open">
</i>
</button>
</td>
</tr>
</tbody>
</table>
Javascript
app.controller('AppController', ['$scope', '$http', '$modal', function ($scope, $http, $modal) {
var search = this;
search.serials = [];
$scope.rowCollection = [];
$scope.init = function () {
waitingDialog.show();//show loading
getTestResults();
};
var getTestResults = function () {
$http({
method: 'GET',
url: "http://sqldev/api/testresults"
}).then(function successCallback(response) {
$scope.rowCollection = response.data;//after assign response.data into rowCollection application stuck
waitingDialog.hide();//hide loading
}, function errorCallback(response) {
console.log('Error: ' + response);
waitingDialog.hide();//hide loading
$scope.open()//open modal with error message
});
};
}]);

AngularJS Smart-Table Client Side Pagination - What is the minimum version of AngularJS required?

I am developing a webpage that displays data in a smart table because I will need to allow the user to select multiple rows for processing.
I am using AngularJS version 1.3.20.
I have a test web page upon which I copied the example found on GitHub (lorenzofox2.github.io/smart-table-website). I copied the provided table script into my test HTML. I copied the provided JavaScript script into my client controller. I execute the web page through my application. The webpage opens with the appropriate data displayed. The webpage does not display the pagination in the footer as defined. I do not know why the pagination does not show.
Listed below, you will find HTML, JavaScript, and Results
HTML :
<div class="smart-table">
<table st-table="rowCollection" class="table table-striped">
<thead>
<tr>
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
<th st-sort="birthDate">birth date</th>
<th st-sort="balance">balance</th>
<th>email</th>
</tr>
<tr>
<th>
<input st-search="'firstName'" placeholder="search for firstname" class="input-sm form-control" type="search"/>
</th>
<th colspan="4">
<input st-search placeholder="global search" class="input-sm form-control" type="search"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rowCollection">
<td>{{row.firstName | uppercase}}</td>
<td>{{row.lastName}}</td>
<td>{{row.birthDate | date}}</td>
<td>{{row.balance | currency}}</td>
<td><a ng-href="mailto:{{row.email}}">email</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
</div>
JavaScript :
var
nameList = ['Pierre', 'Pol', 'Jacques', 'Robert', 'Elisa'],
familyName = ['Dupont', 'Germain', 'Delcourt', 'bjip', 'Menez'];
function createRandomItem() {
var
firstName = nameList[Math.floor(Math.random() * 4)],
lastName = familyName[Math.floor(Math.random() * 4)],
age = Math.floor(Math.random() * 100),
email = firstName + lastName + '#whatever.com',
balance = Math.random() * 3000;
return{
firstName: firstName,
lastName: lastName,
age: age,
email: email,
balance: balance
};
}
$scope.itemsByPage=15;
$scope.rowCollection = [];
for (var j = 0; j < 200; j++) {
$scope.rowCollection.push(createRandomItem());
}
Results
I hope someone can let me know if I am using the appropriate version of AngularJS. If so, I hope someone can guide me into what I missed?
After further searching, this issue was the result of running version 1.3.0 of smart-table instead of 2.1.8. After upgrading angular-smart-table to version 2.1.8, the issue was resolved

AngularJS Factory Service

I am trying to use a Factory Service function in my app to add a movie to my list. I have been able to remove a movie from the list, but I am having trouble figuring out why I can't add a movie to the current list.
var app = angular.module('application', []);
app.factory("MoviesService",[function(){
var movies = [
{title:"Avengers: Age of Ultron",rating:"PG-13",year:"2015"},
{title:"Ant-Man",rating:"PG-13",year:"2015"},
{title:"The Martian",rating:"PG-13",year:"2015"},
{title:"San Andreas",rating:"PG-13",year:"2015"},
{title:"Jurassic Park",rating:"PG-13",year:"2015"},
{title:"Dope",rating:"PG-13",year:"2015"}
];
var factory = {};
factory.getMovies = function(){
return movies;
};
factory.addMovie = function(){
var newMovie = {
title: movie.title,
rating: movie.rating,
year: movie.year
}
movies.push(newMovie);
};
factory.removeMovie = function(movie){
var index = movies.indexOf(movie);
movies.splice(index,1);
};
return factory;
}]);
app.controller('CustomerController',['$scope','MoviesService',function($scope,MoviesService){
$scope.movies = MoviesService.getMovies();
$scope.removeMovie = function(movie){
MoviesService.removeMovie();
};
$scope.addMovie = function(){
MoviesService.addMovie();
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app = "application">
<div class = "row">
<div class = "col-md-12" ng-controller = "CustomerController">
<table class="table">
<caption>Optional table caption.</caption>
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Year</th>
<th>Rating</th>
<th>Options</th>
</tr>
<tr>
<th>Add</th>
<th><input ng-model="movie.title" class="form-control"></th>
<th><input ng-model="movie.year" class="form-control"></th>
<th><input ng-model="movie.rating" class="form-control"></th>
<th>
<button class = "btn btn-success" ng-click="addMovie()"><span class = "glyphicon glyphicon-plus"></span></button>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat = "movie in movies">
<th scope="row">{{$index}}</th>
<td>{{movie.title}}</td>
<td>{{movie.year}}</td>
<td>{{movie.rating}}</td>
<td>
<button ng-click="removeMovie(movie)" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
First off, your addMovie function doesn't have access to movie, so it's probably throwing an error in the console. Change this:
factory.addMovie = function(){
to
factory.addMovie = function(movie) {
and change this:
$scope.addMovie = function(){
MoviesService.addMovie();
}
to:
$scope.addMovie = function() {
MoviesService.addMovie($scope.movie);
}
always pay attention to console errors. I made a working plunker of this in action:
http://plnkr.co/edit/AXNhovhKrW24FLOt9KGM?p=preview
Inside your addMovie function, you trying to add a movie from a movie variable that does not exist in this context. So you are probably getting an error there.
It looks like you're trying to do something like:
$scope.movie = {}; // add this
$scope.addMovie = addMovie; // modify to this
...
factory.addMovie = function(movie){ // add parameter movie
movies.push(movie);
};
...
give that a shot.

How to edit contents in Angular js Smart Table

I am quite new to java script, so I must apologise if this seems basic.
How can I edit rows tables in Smart-Table with Angularjs? There doesn't seem to be a tutorial with the new Smart-Table. I would like to create a simple form for users to enter the hours open for a particular place.
I have created buttons which can add and remove rows on the table, but when I add in contenteditable="true" none of the changes are persisted when I update the object. I understand that the contenteditable is a specific html5 parameters independent of smart-table, but I don't understand how else I can update the data or how I could retrieve the updated data.
The data is retrieved from the angularjs controller via the mean.js routes.
<div class="controls">
<table st-table="place.openHours" class="table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Opening Time</th>
<th>Closing Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in place.openHours" contenteditable="true" >
<td>{{row.day}}</td>
<td>{{row.open}}</td>
<td>{{row.close}}</td>
<button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle">
</i>
</button>
</tr>
</tbody>
</table>
<button type="button" ng-click="addOpenHour(row)" class="btn btn-sm btn-success">
<i class="glyphicon glyphicon-plus">
</i> Add new Row
</button>
</div>
Inside the javascript:
$scope.removeOpenHour = function removeOpenHour(row) {
var index = $scope.place.openHours.indexOf(row);
if (index !== -1) {
$scope.rowCollection.splice(index, 1);
}
}
$scope.addOpenHour = function addOpenHour() {
$scope.place.openHours.push(
{
day: 'Monday',
open: 540,
close: 1080
});
};
Thanks I had a look around and used the code from here http://jsfiddle.net/bonamico/cAHz7/ and merged it with my code.
HTML file:
<tr ng-repeat="row in place.openHours">
<td><div contentEditable="true" ng-model="row.day">{{row.day}}</div></td>
<td><div contentEditable="true" ng-model="row.open">{{row.open}}</div></td>
<td><div contentEditable="true" ng-model="row.close">{{row.close}}</div></td>
<td>
<button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle">
</i>
</button>
</td>
JS file:
myApp.directive('contenteditable', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
// view -> model
elm.bind('blur', function() {
scope.$apply(function() {
ctrl.$setViewValue(elm.html());
});
});
// model -> view
ctrl.render = function(value) {
elm.html(value);
};
elm.bind('keydown', function(event) {
console.log("keydown " + event.which);
var esc = event.which == 27,
el = event.target;
if (esc) {
console.log("esc");
ctrl.$setViewValue(elm.html());
el.blur();
event.preventDefault();
}
});
}
};
});
My solution is it:
Angular directive :
app.directive("markdown", function() {
return {
restrict: 'EA',
scope: {
value: '='},
template: '<span ng-click="edit()" ng-bind="value"></span><input ng-blur="blur()" ng-model="value"></input>',
link: function($scope, element, attrs) {
// Let's get a reference to the input element, as we'll want to reference it.
var inputElement = angular.element(element.children()[1]);
// This directive should have a set class so we can style it.
element.addClass('edit-in-place');
// Initially, we're not editing.
$scope.editing = false;
// ng-click handler to activate edit-in-place
$scope.edit = function() {
$scope.editing = true;
// We control display through a class on the directive itself. See the CSS.
element.addClass('active');
// And we must focus the element.
// `angular.element()` provides a chainable array, like jQuery so to access a native DOM function,
// we have to reference the first element in the array.
inputElement[0].focus();
};
// When we leave the input, we're done editing.
$scope.blur = function() {
$scope.editing = false;
element.removeClass('active');
}
}
};
});
HTML:
<table st-table="displayedCollection" st-safe-src="rowCollection" class="table table-striped">
<thead>
<tr>
<th st-sort="sku">SKU</th>
<th st-sort="skuSupplier">SKU proveedor</th>
<th st-sort="name">DescripciĆ³n</th>
<th st-sort="cantidad">Cantidad</th>
<th st-sort="precio">Precio unitario</th>
<th st-sort="total">Total</th>
</tr>
<tr>
<th colspan="5"><input st-search="" class="form-control" placeholder="Buscar producto ..." type="text"/></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td><markdown value="row.sku"></markdown></td>
<td><markdown value="row.skuSupplier"></markdown></td>
<td><markdown value="row.name"></markdown></td>
<td><markdown value="row.cantidad"></markdown></td>
<td><markdown value="row.precio"></markdown></td>
<td><markdown value="row.total"></markdown></td>
<td>
<button type="button" ng-click="removeItem(row)" class="btn btn-sm btn-danger">
<i class="glyphicon glyphicon-remove-circle"></i>
</button>
</td>
</tr>
</tbody>
</table>

Angular search filter doesn't search in entire table

The problem is the search filter only finds records from the current page and I want it to find record from entire table. How can I do that?
<input type="text" placeholder="Search By Any..." ng-model="search.$"/>
<table dir="ltr" width="477" border="1" class="table table-striped table-bordered">
<thead>
<tr>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('name')">User</a></th>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('contentType')">Content Type</a></th>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('contentName')">Content Name</a></th>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('startTime')">Start Time</a></th>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('endTime')">End Time</a></th>
<th><a style="font-size: 16px;" href="#" ng-click="changeSort('duration')">Duration(In Secs)</a></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in filteredRecords | filter: search | orderBy:sort:reverse track by $index">
<td>{{record.user}}</td>
<td>{{record.contentType}}</td>
<td>{{record.contentName}}</td>
<td>{{record.startTime}}</td>
<td>{{record.endTime}}</td>
<td>{{record.duration}}</td>
</tr>
</tbody>
</table>
<pagination class="pull-right" style="cursor: pointer;" num-pages="numPages()" current-page="currentPage" on-select-page="pageChanged(page)"></pagination>
Angular code:
angular.module("contentViewStatusApp")
.controller("contentViewStatusController", function($scope, contentViewStatusService){
$scope.records = contentViewStatusService.list();
$scope.currentPage = 1
$scope.numPerPage = 10
$scope.maxSize = 5;
$scope.numPages = function(){
return Math.ceil($scope.records.length / $scope.numPerPage);
};
$scope.changeSort = function(value){
if ($scope.sort == value){
$scope.reverse = !$scope.reverse;
return;
}
$scope.sort = value;
$scope.reverse = false;
}
$scope.$watch('currentPage + numPerPage', function(){
var begin = (($scope.currentPage - 1) * $scope.numPerPage), end = begin + $scope.numPerPage;
$scope.filteredRecords = $scope.records.slice(begin, end);
});
});
You could do pagination using filters instead of creating another array. This way it would search through the entire array before being filtered down.
This page shows an example of pagination with filters.
Then you could just have the search query first and it should search through the whole array.
Update
Here's one with pagination that updates based on search text.
It watches the search text and updates the page range after filtering:
$scope.$watch('searchText.name', function (v) {
$scope.currentPage = 0;
$scope.pages = $scope.range();
});
Then the pageCount is updated based on the filtered results:
$scope.pageCount = function () {
var pages = $filter('filter')($scope.items, $scope.searchText);
return Math.ceil(pages.length / $scope.itemsPerPage);
};
Yeah, I agree with #agreco but I think you have to define filtered records in such way that it always works with your search.$ model. So to do this please have a look at this fiddle.
Hope this solves your problem. good luck.

Categories

Resources