Smart Table data is disappearing when sorting - angularjs

I have created a custom directive with Typescript angular for smart table. But when I sort the columns table data is disappearing... When I write the same only with angular js. It works fine.
Can you please help what I did wrong...
Grid-HTML
<table st-safe-src="rowCollection" st-table="gridOptions" class="table table-condensed table-hover">
<thead>
<tr>
<th st-sort="type">Type</th>
<th st-sort="name">Name</th>
<th st-sort="address">Address</th>
<th ng-if="city">City/State</th>
<th ng-if="zip">Zip</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in options">
<td width="20%">{{row.type | uppercase}}</td>
<td width="20%">{{row.name | uppercase}}</td>
<td width="30%">{{row.address | uppercase}}</td>
<td width="15%" ng-if="city">{{row.cityState | uppercase}}</td>
<td width="15%" ng-if="zip">{{row.zip | uppercase}}</td>
</tr>
</tbody>
</table>
Typescript controller
/// <reference path="../../typings/app.d.ts" />
namespace app.widgets {
'use strict';
interface IGridAttributes extends ng.IAttributes {
cityVisible: string;
zipVisible: string;
options: string;
}
export class updGridCtrl {
static $inject: Array<string> = ['$scope', '$filter'];
constructor(private scope: ng.IFormController) {
this.activate();
}
gridOptions: any = null;
city: boolean;
zip: boolean;
activate() {}
}
class LtcgUpdGridDirective implements ng.IDirective {
static instance(): ng.IDirective { return new LtcgUpdGridDirective(); }
restrict: string = 'E';
transclude = true;
scope = {
'cityVisible': "#",
'zipVisble': "#",
'options': '='
};
templateUrl = 'views/widgets/ltcg-updgrid.html';
link = (scope: any, element: ng.IAugmentedJQuery, attrs: IGridAttributes, ctrl: any) => {
scope.gridOptions = scope.options //private scoped from options : '=',
scope.city = true;
scope.zip = true;
console.log(scope.zipVisible);
if (attrs.cityVisible == "no") {
scope.city = false;
}
if (attrs.zipVisible == "no") {
scope.zip = false;
}
}
}
angular
.module('app.widgets')
.directive('ltcgUpdGrid', LtcgUpdGridDirective.instance);
}

Related

Controller function not call in Angular module md-data-table

As per documentation of "md-data-table". I have implemented datatable. But function getDesserts is not calling.
Service code is as below
return {
'getPagingData': function (params) {
var defered = $q.defer();
console.log("Get Paging Service...");
pagination.getPagingData(params,function (response) {
defered.resolve(response);
},
function (error) {
defered.reject(error);
});
return defered.promise;
}
}
And Controller code is as below
$scope.selected = [];
$scope.queryy = {
order: 'name',
limit: 5,
page: 1,
className :"Sla"
};
function success(desserts) {
alert("d");
$scope.desserts = desserts;
}
$scope.getDesserts = function () {
alert("d");
//$scope.promise = $nutrition.desserts.get($scope.query, success).$promise;
$scope.promise = pagingService.getPagingDataHttp($scope.queryy, success).$promise;
};
My html code is as below
<!-- exact table from live demo -->
<md-table-container>
<table md-table md-row-select multiple ng-model="selected" md-progress="promise">
<thead md-head md-order="query.order" md-on-reorder="getDesserts">
<tr md-row>
<th md-column md-order-by="nameToLower"><span>Dessert (100g serving)</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row md-select="dessert" md-select-id="name" md-auto-select ng-repeat="dessert in desserts.data">
<td md-cell>{{dessert.name}}</td>
</tr>
</tbody>
</table>
</md-table-container>
<md-table-pagination md-limit="query.limit" md-limit-options="[5, 10, 15]" md-page="query.page" md-total="{{desserts.count}}" md-on-paginate="getDesserts" md-page-select></md-table-pagination>
After this implementation, getDessert function in controller is not being
called. Kindly guide me

Unable to figure out the async nature of the $http call

My controller/service retrieve the data from the url, and it returns with no errors. However, the repeat for the <tbody> doesn't show the data. The inspector shows no errors, and fiddler shows the url is called for the rest api.
Model
export interface IAuthor {
AuthorId: number;
FirstName: string;
LastName: string;
GoogleAuthorId: string;
CreatedByEmployeeId: any;
CreatedOn: Date;
ModifiedByEmployeeId: any;
ModifiedOn: Date;
PhotoURI: string;
}
Service
export class AuthorService implements IAuthorService {
private url: string;
static $inject = ["$http"];
constructor(private $http: ng.IHttpService) {
this.url = "/odata/Author";
}
getAuthors(): ng.IPromise<IAuthor[]> {
return this.$http
.get(this.url)
.then((response: ng.IHttpPromiseCallbackArg<IAuthor[]>): IAuthor[] => {
return response.data;
});
}
}
Controller
export class AuthorController implements IAuthorController {
authorItems: IAuthor[];
static $inject: string[] = ["AuthorService"];
constructor(private authorService: Services.IAuthorService) {
var results = this.getAuthors();
}
getAuthors(): IAuthor[] {
this.authorItems = [];
var results = this.authorService.getAuthors()
.then((authorItemsLocal: IAuthor[]): void => {
this.authorItems = authorItemsLocal;
});
return this.authorItems;
}
}
Html
<div class="container" ng-controller="AuthorController as vm">
<h2>Authors</h2>
<div>
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Author ID</th>
</tr>
</thead>
<tbody ng-repeat="c in vm.authorItems">
<tr>
<td>{{ c.FirstName }}</td>
<td>{{ c.LastName }}</td>
<td>{{ c.AuthorId }}</td>
</tr>
</tbody>
</table>
</div>
</div>
I had typed the results to the proper type in typescript. When I typed them to "any", it worked.

How to set checkAll for in angularjs ng-repeat table

I have a complex ng-repeat table,which I need to set the select all function for the checkbox of each row.He is my code:
JS:
$scope.getCCGenie = function(){
CCGenieService.transactionList().then(function(list){
$scope.CreditCardsList = list;
$scope.CorporateCardsNum = $scope.CreditCardsList.transactionInfo.corpCardCount;
$scope.PersonalCardsNum = $scope.CreditCardsList.transactionInfo.personalCardCount;
});
}
$scope.hasExpenseTypeLabel = false;
$scope.getCCGenie();
$scope.checkAllcorp = function(copcards) {
console.log(copcards);
if (copcards.selectedAllcorp) {
copcards.selectedAllcorp = true;
$scope.hasSelectedExpense = true;
} else {
copcards.selectedAllcorp = false;
$scope.hasSelectedExpense = false;
}
angular.forEach('copcards.transactions',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
// I need to loop the selected table to reset each corpisSelected,assign them the new value selectedAllcorp. but how?
};
Html:
<ul>
<li ng-repeat='copcards in CreditCardsList.transactionInfo.corporateCards'>
<span class='creditcardsubtitle'>{{copcards.cardName}} (****{{copcards.cardNumber}})</span>
<table class='table col-xs-12 col-md-12 col-lg-12' border="0" cellpadding="10" cellspacing="0" width="100%">
<thead>
<th class='text-center'><input type="checkbox" ng-model="copcards.selectedAllcorp" ng-change="checkAllcorp(copcards)"/></th>
<th class='text-left'>Date</th>
<th class='text-left'>Merchant</th>
<th class='text-right'>Amount</th>
<th class='text-center'>Expense Type</th>
<th class='text-left'><input type="checkbox" ng-model="selectedAllBill" ng-change="checkAllBillable()" style='margin-right:3px;'/> Billable</th>
<th class='text-center'>Attachment</th>
<th class='text-center'>Description</th>
</thead>
<tbody><tr ng-show='noExpense'><td colspan="8" align="center" style="text-align: center;" >No any Personal Cards!</td>
</tr>
<tr ng-repeat='componentObject in copcards.transactions' ng-class="{'selectedrow':componentObject.corpisSelected}">
<td type='checkbox' class='text-center'><input type='checkbox' ng-model='componentObject.corpisSelected' class='deletebox'/>{{componentObject.corpisSelected}}</td>
<td class='text-left tdwidth'>{{componentObject.transactionDateString | parseDateFormat | date}}</td>
<td class='text-left tdwidth'>{{componentObject.merchant}}</td>
<td class='text-right tdwidth'>${{componentObject.amount}}</td>
<td class='text-center tdwidth'><smart-expense-type></smart-expense-type></td>
<td class='text-left tdwidth'><input type='checkbox' ng-model='componentObject.isBillable'/></td>
<td class='text-center tdwidth'>{{componentObject.hasImage}}</td>
<td class='text-center tdwidth'><input type='text'ng-model='componentObject.description'/></td>
</tr>
</tbody>
</table>
</li>
</ul>
As you can see, I use nasted ng-repeat the loop data, there may be many tables over there, I want each table has his own selectAll function which works independently. Now the code is partly working fine, the problem is if you check the single checkbox in row, the checkall function will not work.I know I need to do something like this:
$scope.checkAllcorp = function() {
if (this.selectedAllcorp) {
$scope.hasSelectedExpense = true
this.selectedRow = true;
this.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
this.selectedRow = false;
this.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = this.selectedAllcorp;
})
};
But how can I access this 'selectedTable'?
Pass copcards to your function and then operate on that object instead of this:
ng-change="checkAllcorp(copcards)"
And then in your controller:
$scope.checkAllcorp = function(copcards) {
if (copcards.selectedAllcorp) {
$scope.hasSelectedExpense = true
copcards.selectedRow = true;
copcards.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
copcards.selectedRow = false;
copcards.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
you can pass the object you are on by calling it thru the function itself like this
ng-change="checkAllcorp(copcards)
and then use it as a parameter for you checkAllcorp function instead of this in you function
example :
<div ng-repeat="name in names"><button ng-click="msg(name)"></button></div>
controller scope :
$scope.msg = function(name) { alert(name.first)};

AngularJS pass function with dynamic parameter to directive

TL;DR version: I'm trying to write a directive to show various objects in a table, and add an edit / delete button at the end of the table rows.
The example entity will be ProjectType, so:
project-type.controller.js
// determines which attributes we want to show in the table
$scope.attr = [
'computerName',
'shortName',
'longName'
];
// puts the current projectType object to the form
$scope.edit = function(projectType) {
$scope.projectType = projectType;
$scope.computerName = projectType.computerName;
$scope.isEdit = true;
};
// shows a delete modal window
$scope.deleteConfirm = function (projectType) {
Modal.confirm.deleteModal('Project type', projectType.computerName, function () {
Message.createMessage('project-type.message.delete.success', { projectType: projectType.computerName }, { type: 'warning', timeout: 4000 });
$scope.remove(projectType);
})();
};
project-type.html
<!-- show table with directive -->
<entity-table object="projectTypes" entity="'project-type'" attr="attr"></entity-table>
<!-- show table without directive -->
<table class="table table-responsive">
<thead>
<tr>
<th>{{ 'project-type.create.label.computerName' | translate }}</th>
<th>{{ 'project-type.create.label.shortName' | translate }}</th>
<th>{{ 'project-type.create.label.longName' | translate }}</th>
<th>{{ 'common.operations' | translate }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="projectType in projectTypes">
<td><strong>{{ projectType.computerName }}</strong></td>
<td>{{ projectType.shortName }}</td>
<td>{{ projectType.longName }}</td>
<td>
<a ng-click="edit(projectType)" class="pencil"><span class="glyphicon glyphicon-pencil"></span></a>
<a ng-click="deleteConfirm(projectType)" class="trash"><span class="glyphicon glyphicon-trash"></span></a>
</td>
</tr>
</tbody>
</table>
entity-table.directive.js
angular.module('unioffice-centralApp')
.directive('entityTable', function () {
return {
restrict: 'E',
replace: true,
transclude : true,
templateUrl: '/components/directives/entity-table/entity-table.html',
scope: {
object: '=',
entity: '=',
attr: '='
},
link: function (scope, element, attrs, controllers, transclude) {
console.log(scope);
}
};
});
entity-table.html
<div>
<table class="table table-responsive">
<thead>
<tr>
<th ng-repeat="att in attr">{{ (entity + ".table.label." + att) | translate }}</th>
<th ng-repeat-end translate>common.operations</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="obj in object">
<td ng-repeat="att in attr">{{ obj[att] }}</td>
<td ng-repeat-end>
<a ng-click="edit(obj)" class="pencil"><span class="glyphicon glyphicon-pencil"></span></a>
<a ng-click="deleteConfirm(obj)" class="trash"><span class="glyphicon glyphicon-trash"></span></a>
</td>
</tr>
</tbody>
</table>
(there is a /div at the end of the entity-table.html, stackoverflow seems to kill it)
So the question is: how do I pass the edit() and deleteConfirm() functions to the directive to make them work?
In this picture you can see the two tables are the same, but the buttons in the first one obviously won't do anything at this point: (also I know the second one has bold first column, it's ok, that's not the point now)
Passing/binding the functions from the controller to the directive is done in the same manner as binding an object = or a string # with the difference being how it's referenced in the directive
Pass in the functions as attributes on the directive as shown below ..
<entity-table object="projectTypes" entity="'project-type'" on-delete="deleteConfirm" on-edit="edit" attr="attr"></entity-table>
In your directive do this ..
angular.module('unioffice-centralApp')
.directive('entityTable', function () {
return {
restrict: 'E',
replace: true,
transclude : true,
templateUrl: '/components/directives/entity-table/entity-table.html',
scope: {
object: '=',
entity: '=',
attr: '=',
onDelete: '&', // function referencing
onEdit: '&' // function referencing
},
link: function (scope, element, attrs, controllers, transclude) {
scope.deleteFn = function (obj) {
scope.onDelete()(obj); // this invokes the deleteConfirm function in the controller
}
scope.editFn = function (obj) {
scope.onEdit()(obj); // this invokes the deleteConfirm function in the controller
}
}
};
});
In your controller ...
$scope.edit = function(projectType) {
$scope.projectType = projectType;
$scope.computerName = projectType.computerName;
$scope.isEdit = true;
};
// shows a delete modal window
$scope.deleteConfirm = function (projectType) {
Modal.confirm.deleteModal('Project type', projectType.computerName, function () {
Message.createMessage('project-type.message.delete.success', { projectType: projectType.computerName }, { type: 'warning', timeout: 4000 });
$scope.remove(projectType);
})();
};
PLUNKR

How to implement filter with Typescript?

I have this filter:
module App.Filters {
export class LabelCase implements ng.IFilterService {
static $inject = ['$filter'];
public static factory(): Function {
return (input: string) => {
input = input.replace(/(A-Z)/g, '$1');
return input[0].toUpperCase() + input.slice(1);
}
}
}
}
Here is the registration in app.js
this.app.filter("labelCase", () => App.Filters.LabelCase.factory);
This gives me an error.
What I'm doing wrong?
Error: [$injector:unpr] http://errors.angularjs.org/1.2.23/$injector/unpr?p0=lableCaseFilterProvider%20%3C-%20lableCaseFilter
x/<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:6:443
gc/l.$injector<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:36:196
c#http://localhost:2861/Scripts/vendors/angular/angular.min.js:34:300
gc/p.$injector<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:36:266
c#http://localhost:2861/Scripts/vendors/angular/angular.min.js:34:300
mc/this.$get</<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:124:325
db.prototype.filter#http://localhost:2861/Scripts/vendors/angular/angular.min.js:171:352
db.prototype.filterChain#http://localhost:2861/Scripts/vendors/angular/angular.min.js:171:257
db.prototype.statements#http://localhost:2861/Scripts/vendors/angular/angular.min.js:171:1
db.prototype.parse#http://localhost:2861/Scripts/vendors/angular/angular.min.js:167:470
Yd/this.$get</<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:99:13
f#http://localhost:2861/Scripts/vendors/angular/angular.min.js:80:39
x#http://localhost:2861/Scripts/vendors/angular/angular.min.js:62:8
ea#http://localhost:2861/Scripts/vendors/angular/angular.min.js:49:421
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:47:344
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:40
w#http://localhost:2861/Scripts/vendors/angular/angular.min.js:46:124
F#http://localhost:2861/Scripts/vendors/angular/angular.min.js:56:187
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:47:373
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:40
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:40
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:40
K#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:40
w#http://localhost:2861/Scripts/vendors/angular/angular.min.js:46:124
z/<.link#http://localhost:2861/Scripts/vendors/angular/angular-route.min.js:7:202
O#http://localhost:2861/Scripts/vendors/angular/angular.min.js:54:392
g#http://localhost:2861/Scripts/vendors/angular/angular.min.js:47:256
w/<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:46:374
W/<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:48:215
L#http://localhost:2861/Scripts/vendors/angular/angular.min.js:52:40
v#http://localhost:2861/Scripts/vendors/angular/angular-route.min.js:6:355
Zd/this.$get</k.prototype.$broadcast#http://localhost:2861/Scripts/vendors/angular/angular.min.js:114:322
l/<#http://localhost:2861/Scripts/vendors/angular/angular-route.min.js:11:177
ye/e/l.promise.then/L#http://localhost:2861/Scripts/vendors/angular/angular.min.js:100:167
ye/e/l.promise.then/L#http://localhost:2861/Scripts/vendors/angular/angular.min.js:100:167
ye/f/<.then/<#http://localhost:2861/Scripts/vendors/angular/angular.min.js:101:340
Zd/this.$get</k.prototype.$eval#http://localhost:2861/Scripts/vendors/angular/angular.min.js:112:57
Zd/this.$get</k.prototype.$digest#http://localhost:2861/Scripts/vendors/angular/angular.min.js:109:139
Zd/this.$get</k.prototype.$apply#http://localhost:2861/Scripts/vendors/angular/angular.min.js:112:396
h#http://localhost:2861/Scripts/vendors/angular/angular.min.js:72:441
v#http://localhost:2861/Scripts/vendors/angular/angular.min.js:77:463
we/</w.onreadystatechange#http://localhost:2861/Scripts/vendors/angular/angular.min.js:79:24
HTML:
<table class="table table-bordered table-hover text-right">
<thead>
<tr>
<th ng-repeat="field in report.fields" class="text-center" ng-click="report.sorterer(field)">
<span ng-show="report.sort.field === field && !report.sort.order" class="glyphicon glyphicon-chevron-down"></span>
<span ng-show="report.sort.field === field && report.sort.order" class="glyphicon glyphicon-chevron-up"></span>
{{ field | lableCase }}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="contact in report.contacts | filter: report.query | orderBy: report.sort.field : report.sort.order">
<td ng-repeat="field in report.fields">
{{contact[field]}}
</td>
</tr>
</tbody>
</table>
You misspelled "label" in your HTML:
{{ field | lableCase }}
should be
{{ field | labelCase }}
here is how i write filters in typescript
module portal{
export var app = angular.module("demo", []);
app.filter(filters);
}
module portal.filters{
export class fromNow{
constructor(){
return function(date){
return moment(date).fromNow();//return anything m using moment.js
}
}
}
}

Resources