From d550bd9f47a9d14778bc8ae0b255047bb37a08e2 Mon Sep 17 00:00:00 2001 From: Heli Perez Date: Sun, 19 Mar 2017 05:25:29 -0400 Subject: [PATCH] Ajustes 0.1.4 --- .gitignore | 3 +- README.md | 4 +- demo/app.js | 39 +++++++++++-------- demo/index.html | 42 ++++++++++++++------- dist/md-crud.js | 74 ++++++++++++++++++++++--------------- dist/md-crud.min.js | 2 +- package.json | 2 +- src/directives/crud.js | 50 ++++++++++++++++--------- src/directives/crudForm.js | 6 +-- src/services/crudService.js | 16 ++++---- src/views/crud.html | 8 ++-- 11 files changed, 151 insertions(+), 95 deletions(-) diff --git a/.gitignore b/.gitignore index 12d21f0..714a9bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules bower_components -temp \ No newline at end of file +temp +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 4619d44..289fe2e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Permite crear un cotrol CRUD simple o personalizado sobre un RESTful Api utilizando $http. ## Demo -[Aplicación Demo](https://cdn.rawgit.com/ClassHP/md-crud/0.1.1/demo/index.html) +[Aplicación Demo](https://cdn.rawgit.com/ClassHP/md-crud/0.1.4/demo/index.html) ## Dependecias ```javascript @@ -20,7 +20,7 @@ Permite crear un cotrol CRUD simple o personalizado sobre un RESTful Api utiliza } ``` ## CDN -[https://cdn.rawgit.com/ClassHP/md-crud/0.1.1/dist/md-crud.min.js](https://cdn.rawgit.com/ClassHP/md-crud/0.1.1/dist/md-crud.min.js) +[https://cdn.rawgit.com/ClassHP/md-crud/0.1.4/dist/md-crud.min.js](https://cdn.rawgit.com/ClassHP/md-crud/0.1.4/dist/md-crud.min.js) ## npm ```sh diff --git a/demo/app.js b/demo/app.js index bb69deb..57e4423 100644 --- a/demo/app.js +++ b/demo/app.js @@ -117,6 +117,12 @@ angular.module('app', ['ngAnimate', 'ngMessages', 'ngSanitize', 'ngMaterial', 'm noDetail: false, noSearch: false, fields: [ + { + name: 'thumbnail', + label: 'Image', + type: 'template', + columnTemplate: '' + }, { name: 'name', label: 'Name', @@ -127,26 +133,29 @@ angular.module('app', ['ngAnimate', 'ngMessages', 'ngSanitize', 'ngMaterial', 'm label: 'Description', type: 'text' }, - { - name: 'thumbnail', - label: 'Image', - type: 'template', - columnTemplate: '' - } ], serverSide: { - searchParam: 'nameStartsWith' - }, - getParams: { - apikey: 'c3c80a056a45ea887f1c77c2525e66a5' + searchParam: 'nameStartsWith', + offsetParam: 'offset', + limitParam: 'limit', }, http: { rootApi: 'https://gateway.marvel.com:443/v1/public', - functionData: function (response, resolve, reject) { - resolve({ - data: response.data.data.results, - total: response.data.data.total - }); + params: { + apikey: 'c3c80a056a45ea887f1c77c2525e66a5' + }, + functionData: function (response, resolve, reject, method) { + if(method == 'getById') { + resolve({ + data: response.data.data.results[0] + }); + } + else { + resolve({ + data: response.data.data.results, + total: response.data.data.total + }); + } } } }; diff --git a/demo/index.html b/demo/index.html index f04efb3..6e2a1fc 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,17 +17,25 @@ - - -
-
Angular material crud
-
- Spanish - English -
-
- + + +
+
Angular material crud
+
+ Spanish + English + + + +
+
+ + + +
noEdit @@ -37,11 +45,19 @@ noSearch
-
- - +
+
+ +
+ Made with favorite by ClassHP + Version 0.1.4 + GitHub + Twitter +
diff --git a/dist/md-crud.js b/dist/md-crud.js index b264586..44d58a4 100644 --- a/dist/md-crud.js +++ b/dist/md-crud.js @@ -1,4 +1,4 @@ -angular.module('mdCrudTemplates', []).run(['$templateCache', function($templateCache) {$templateCache.put('/views/crud.html','
{{translate(text.createOption)}}

{{translate(field.label)}}
{{ row[field.name] | date:\'shortDate\' }} {{ row[field.name] | date:\'shortTime\' }} {{ row[field.name] | date:\'short\' }} {{ getTextSelect(field, row) }} {{translate(row[field.name])}}
'); +angular.module('mdCrudTemplates', []).run(['$templateCache', function($templateCache) {$templateCache.put('/views/crud.html','
{{translate(text.createOption)}}

{{translate(field.label)}}
{{ row[field.name] | date:\'shortDate\' }} {{ row[field.name] | date:\'shortTime\' }} {{ row[field.name] | date:\'short\' }} {{ getTextSelect(field, row) }} {{translate(row[field.name])}}
'); $templateCache.put('/views/crudForm.html','

{{translate(field.label)}}{{mdSelectItem[field.text || \'text\']}}{{mdSelectItem[field.text || \'text\']}}
access_time
access_time
{{translate(message)}}
{{translate(option.formCancelText || text.formCancel)}}
{{translate(option.formSubmit || text.formSubmit)}}
'); $templateCache.put('/views/crudFormDialog.html','

{{formTitle | translate}}

close
'); $templateCache.put('/views/crudFormMessages.html','
{{translate(field.messageRequired || text.messageRequired)}}
{{translate(field.messageMinlength || text.messageMinlength)}} ({{field.minlength}}).
{{translate(field.messageMaxlength || text.messageMaxlength)}} ({{field.maxlength}}).
{{translate(field.messagePattern || text.messagePattern)}}
{{translate(field.messageMin || text.messageMin)}} ({{field.min}}).
{{translate(field.messageMax || text.messageMax)}} ({{field.max}}).
{{translate(field.messageMimetype || text.messageMimetype)}}
{{translate(field.messageValid || text.messageValid)}}
{{translate(field.messageMindate || text.messageMindate)}} {{field.minDate | date:\'shortDate\'}}.
{{translate(field.messageMaxdate || text.messageMaxdate)}} {{field.maxDate | date:\'shortDate\'}}.
');}]); @@ -18,9 +18,9 @@ $templateCache.put('/views/crudFormMessages.html','
{{ .module('mdCrudModule') .directive('mdCrud', crudDirective); - crudDirective.$inject = ['mdCrudService', 'mdCrudToolsService', '$mdDialog', '$interpolate']; + crudDirective.$inject = ['mdCrudService', 'mdCrudToolsService', '$mdDialog', '$interpolate', '$sce']; - function crudDirective(crudService, tools, $mdDialog, $interpolate) { + function crudDirective(crudService, tools, $mdDialog, $interpolate, $sce) { var directive = { link: link, restrict: 'EA', @@ -45,6 +45,8 @@ $templateCache.put('/views/crudFormMessages.html','
{{ var deleteConfirm = tools.evalDefined([attrs.deleteConfirm, options.deleteConfirm, crudService.options.deleteConfirm]); var autoRefresh = tools.evalDefined([attrs.autoRefresh, options.autoRefresh, crudService.options.autoRefresh]); var getParams = tools.evalDefined([attrs.getParams, options.getParams, {}]); + $scope.searchText = attrs.searchText || options.searchText || ""; + $scope.searchDelay = attrs.searchDelay || options.searchDelay || (options.serverSide ? 500 : 0); $scope.fields = options.fields; $scope.rowSelected = null; @@ -53,7 +55,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ $scope.ef = tools.evalFunction; $scope.stringToHtml = function(str, data) { - return $interpolate(str)(data); + return $sce.trustAsHtml($interpolate(str)(data)); } $scope.isLoading = true; @@ -69,21 +71,32 @@ $templateCache.put('/views/crudFormMessages.html','
{{ return row[field.name]; } + $scope.onSearchTextChange = function(text) { + $scope.searchText = text; + if(options.serverSide && options.serverSide.searchParam) { + $scope.table.page = 1; + options.refresh(); + } + } + $scope.table = { rows: [], refresh: function (params) { $scope.isLoading = true; - if (params) - getParams = params; - var optionsGet = {}; - angular.extend(optionsGet, options.http); + angular.extend(getParams, params); + var optionsGet = angular.copy(options.http); optionsGet.entity = options.entity; - optionsGet.params = getParams; + optionsGet.params = angular.copy(optionsGet.params || {}); + angular.extend(optionsGet.params, getParams); if(options.serverSide) { - optionsGet.params[options.serverSide.pageParam | 'page'] = $scope.table.page; - optionsGet.params[options.serverSide.limitParam | 'limit'] = $scope.table.limit; - optionsGet.params[options.serverSide.offsetParam | 'offset'] = $scope.table.page * $scope.table.limit; - optionsGet.params[options.serverSide.searchParam | 'search'] = $scope.searchText; + if(options.serverSide.pageParam) + optionsGet.params[options.serverSide.pageParam || 'page'] = $scope.table.page; + if(options.serverSide.offsetParam) + optionsGet.params[options.serverSide.offsetParam || 'offset'] = ($scope.table.page - 1) * $scope.table.limit; + if(options.serverSide.limitParam) + optionsGet.params[options.serverSide.limitParam || 'limit'] = $scope.table.limit; + if(options.serverSide.searchParam) + optionsGet.params[options.serverSide.searchParam || 'search'] = ($scope.searchText != "") ? $scope.searchText : undefined; } $scope.table.promise = crudService.get(optionsGet).then(function (response) { $scope.isLoading = false; @@ -138,12 +151,11 @@ $templateCache.put('/views/crudFormMessages.html','
{{ var index = this.rows.findIndex(function (r) { return r[options.id] == rowId; }); - var optionsDelete = {}; - angular.extend(optionsDelete, options.http); - optionsDelete.entity = options.entity; - optionsDelete.id = rowId; + var optionsHttp = angular.copy(options.http); + optionsHttp.entity = options.entity; + optionsHttp.id = rowId; var deleteFunct = function () { - crudService.delete(optionsDelete).then(function (data) { + crudService.delete(optionsHttp).then(function (data) { t.rows.splice(index, 1); }, function (error) { if (!error) @@ -174,6 +186,10 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rowsPerPage: translate(text.tablePaginationRowsPerPage), of: translate(text.tablePaginationOf) } + }, + onPaginate: function() { + if(options.serverSide) + $scope.table.refresh(); } } @@ -336,8 +352,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ if (idValue) { $scope.isLoading = true; - var optionsHttp = {}; - angular.extend(optionsHttp, options.http); + var optionsHttp = angular.copy(options.http); optionsHttp.entity = options.entity; optionsHttp.id = idValue; crudService.getById(optionsHttp).then(function (response) { @@ -354,8 +369,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ $scope.save = function () { var promise; - var optionsHttp = {}; - angular.extend(optionsHttp, options.http); + var optionsHttp = angular.copy(options.http); optionsHttp.entity = options.entity; optionsHttp.data = $scope.item; if (idValue) { @@ -412,7 +426,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ urlPost: '{{rootApi}}/{{entity}}', urlPatch: '{{rootApi}}/{{entity}}/{{id}}', urlDelete: '{{rootApi}}/{{entity}}/{{id}}', - functionHttp: function(options) { + functionHttp: function(options, method) { if(options.functionHttp) return options.functionHttp(options); return $q(function (resolve, reject) { @@ -422,13 +436,13 @@ $templateCache.put('/views/crudFormMessages.html','
{{ params: options.params, data: options.data }).then(function (response) { - (options.functionData || defaultOptions.functionData)(response, resolve, reject); + (options.functionData || defaultOptions.functionData)(response, resolve, reject, method); }, function (response) { reject(response.data); }); }) }, - functionData: function(response, resolve, reject) { + functionData: function(response, resolve, reject, method) { resolve(response); }, formType: 'inline', @@ -486,7 +500,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'get'); }, getById: function (options) { var httpOptions = { @@ -495,7 +509,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'getById'); }, post: function (options) { var httpOptions = { @@ -504,7 +518,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'post'); }, patch: function (options) { var httpOptions = { @@ -513,7 +527,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'patch'); }, delete: function (options) { var httpOptions = { @@ -522,7 +536,7 @@ $templateCache.put('/views/crudFormMessages.html','
{{ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'delete'); }, }; } diff --git a/dist/md-crud.min.js b/dist/md-crud.min.js index ac33b93..d2c61ca 100644 --- a/dist/md-crud.min.js +++ b/dist/md-crud.min.js @@ -1 +1 @@ -angular.module("mdCrudTemplates",[]).run(["$templateCache",function(e){e.put("/views/crud.html",'
{{translate(text.createOption)}}

{{translate(field.label)}}
{{ row[field.name] | date:\'shortDate\' }} {{ row[field.name] | date:\'shortTime\' }} {{ row[field.name] | date:\'short\' }} {{ getTextSelect(field, row) }} {{translate(row[field.name])}}
'),e.put("/views/crudForm.html",'

{{translate(field.label)}}{{mdSelectItem[field.text || \'text\']}}{{mdSelectItem[field.text || \'text\']}}
access_time
access_time
{{translate(message)}}
{{translate(option.formCancelText || text.formCancel)}}
{{translate(option.formSubmit || text.formSubmit)}}
'),e.put("/views/crudFormDialog.html",'

{{formTitle | translate}}

close
'),e.put("/views/crudFormMessages.html",'
{{translate(field.messageRequired || text.messageRequired)}}
{{translate(field.messageMinlength || text.messageMinlength)}} ({{field.minlength}}).
{{translate(field.messageMaxlength || text.messageMaxlength)}} ({{field.maxlength}}).
{{translate(field.messagePattern || text.messagePattern)}}
{{translate(field.messageMin || text.messageMin)}} ({{field.min}}).
{{translate(field.messageMax || text.messageMax)}} ({{field.max}}).
{{translate(field.messageMimetype || text.messageMimetype)}}
{{translate(field.messageValid || text.messageValid)}}
{{translate(field.messageMindate || text.messageMindate)}} {{field.minDate | date:\'shortDate\'}}.
{{translate(field.messageMaxdate || text.messageMaxdate)}} {{field.maxDate | date:\'shortDate\'}}.
')}]),function(){"use strict";angular.module("mdCrudModule",["mdCrudTemplates"])}(),function(){"use strict";function e(e,t,n,i){function l(l,a,d){var o=e.text;l.text=o;var r=e.options.translate;l.translate=r;var m=l.options;m.id=m.id||"id",l.formType=t.evalDefined([d.formType,m.formType,e.options.formType]);var s=t.evalDefined([d.deleteConfirm,m.deleteConfirm,e.options.deleteConfirm]),c=t.evalDefined([d.autoRefresh,m.autoRefresh,e.options.autoRefresh]),u=t.evalDefined([d.getParams,m.getParams,{}]);l.fields=m.fields,l.rowSelected=null,l.rowCreate=null,l.ef=t.evalFunction,l.stringToHtml=function(e,t){return i(e)(t)},l.isLoading=!0,l.getTextSelect=function(e,n){if(e.getTextSelect)return e.getTextSelect(e,n);var i=t.evalFunction(e.data,n);for(var l in i)if(i[l][e.value]==n[e.name])return i[l][e.text];return n[e.name]},l.table={rows:[],refresh:function(t){l.isLoading=!0,t&&(u=t);var n={};angular.extend(n,m.http),n.entity=m.entity,n.params=u,m.serverSide&&(n.params["page"|m.serverSide.pageParam]=l.table.page,n.params["limit"|m.serverSide.limitParam]=l.table.limit,n.params["offset"|m.serverSide.offsetParam]=l.table.page*l.table.limit,n.params["search"|m.serverSide.searchParam]=l.searchText),l.table.promise=e.get(n).then(function(e){l.isLoading=!1,l.table.rows=e.data,m.serverSide&&(l.table.total=e.total)})},create:function(e){e.stopPropagation(),l.rowSelected=null,l.rowCreate={},"window"==l.formType&&f({},!0,e).then(function(e){})},edit:function(e,t){t.stopPropagation(),e[m.id]&&("inline"==l.formType&&l.selectRow(e,!0),"window"==l.formType&&f(e,!0,t).then(function(e){}))},detail:function(e,t){t.stopPropagation(),"inline"==l.formType&&(l.rowSelected==e?l.rowSelected=null:m.noDetail||l.selectRow(e,!1)),"window"==l.formType&&f(e,!1,t).then(function(e){})},delete:function(n,i){l.rowSelected=null,i.stopPropagation();var a=this,d=this.rows.findIndex(function(e){return e[m.id]==n}),c={};angular.extend(c,m.http),c.entity=m.entity,c.id=n;var u=function(){e.delete(c).then(function(e){a.rows.splice(d,1)},function(e){e||(e=o.deleteError),t.showAlert(r(o.deleteErrorTitle),r(e),r(o.btnAlertOk))})};s?t.showConfirm(r(o.deleteConfirmTitle),r(o.deleteConfirmMessage),r(o.deleteConfirmOk),r(o.btnConfirmCancel),r(o.btnConfirmCancel)).then(function(){u()}):u()},promise:null,order:"",limit:t.evalDefined([d.tableLimit,m.tableLimit,e.options.tableLimit]),limitOptions:t.evalDefined([d.limitOptions,m.limitOptions,e.options.limitOptions]),page:1,rowSelection:!1,selected:[],labels:function(){return{page:r(o.tablePaginationPage),rowsPerPage:r(o.tablePaginationRowsPerPage),of:r(o.tablePaginationOf)}}},m.refresh=function(e){l.table.refresh(e)},c&&m.refresh();var f=function(e,t,i){return l.formEditable=t,n.show({controller:["$scope","$mdDialog","mdCrudService","item","options",g],templateUrl:"/views/crudFormDialog.html",clickOutsideToClose:!0,fullscreen:!0,scope:l,preserveScope:!0,controllerAs:"vm",locals:{item:e,options:m},targetEvent:i,parent:a})};l.templateUrl=(m.form||{}).templateUrl,l.onOpen=function(e){(m.form||{}).onOpen&&m.form.onOpen(e)},l.onEdit=function(e){(m.form||{}).onEdit&&m.form.onEdit(e)},l.onCancel=function(e){(m.form||{}).onCancel&&m.form.onCancel(e),l.rowSelected=null,l.rowCreate=null,e&&t.showAlert(r(o.generalErrorTitle),r(e),r(o.btnAlertOk))},l.onSussces=function(e,t){(m.form||{}).onSussces&&m.form.onSussces(e,t),"create"==t&&l.table.rows.unshift(e),l.rowSelected=null,l.rowCreate=null},l.selectRow=function(e,t){l.rowSelected=e,l.formEditable=t};var g=function(e,t,n,i,l){e.formTitle=r(i[l.id]?e.formEditable?o.editTitle:o.detailTitle:o.createTitle),e.item=i,e.onCancelDialog=function(e){(l.form||{}).onCancel&&l.form.onCancel(e),t.cancel()},e.onSusscesDialog=function(e,n){(l.form||{}).onSussces&&l.form.onSussces(e,n),t.hide(e)},e.cancelDialog=function(){e.onCancelDialog(i)}}}var a={link:l,restrict:"EA",scope:{options:"="},templateUrl:"/views/crud.html"};return a}angular.module("mdCrudModule").directive("mdCrud",e),e.$inject=["mdCrudService","mdCrudToolsService","$mdDialog","$interpolate"]}(),function(){"use strict";function e(e,t,n){function i(n,i,a){var d=e.text;n.text=d;var o=e.options.translate;n.translate=o;var r=n.options;n.fields=r.fields,n.readonly=0==n.editable,n.ef=t.evalFunction,n.isLoading=!1;var m=n.ngModel[r.id];if(n.formTitle=m?n.editable?d.editTitle:d.detailTitle:d.createTitle,n.formType=m?n.editable?"edit":"detail":"create",n.fields=r.fields,n.item={},n.getContentUrl=function(e,t){return n.templateUrl||"/views/crudForm.html"},n.showTimePicker=function(e,t,n){l&&l(t[n],{targetEvent:e}).then(function(e){t[n]=e})},n.onOpen&&n.onOpen(n.item),m){n.isLoading=!0;var s={};angular.extend(s,r.http),s.entity=r.entity,s.id=m,e.getById(s).then(function(e){n.item=e.data,n.onEdit&&n.onEdit(n.item),n.isLoading=!1},function(e){n.onError&&n.onError(e),n.cancel(e)})}n.save=function(){var t,i={};angular.extend(i,r.http),i.entity=r.entity,i.data=n.item,m?(i.id=n.item[r.id],t=e.patch(i)):t=e.post(i),n.isLoading=!0,t.then(function(e){angular.copy(e.data,n.ngModel),n.onSussces&&n.onSussces(e.data,n.formType),n.isLoading=!1},function(e){e.details?n.errors=e.details:n.errors=[e.error],n.onError&&n.onError(e),n.isLoading=!1})},n.cancel=function(e){n.onCancel&&n.onCancel(e)},n.onMarkerDrag=function(e){n.item[this.data.lat]=e.latLng.lat(),n.item[this.data.lng]=e.latLng.lng()}}var l;try{l=n.get("$mdpTimePicker")}catch(e){}var a={link:i,restrict:"EA",scope:{options:"=",ngModel:"=",onOpen:"=",onEdit:"=",onCancel:"=",onSussces:"=",templateUrl:"
'};return a}angular.module("mdCrudModule").directive("mdCrudForm",e),e.$inject=["mdCrudService","mdCrudToolsService","$injector"]}(),function(){"use strict";function e(e,t,n,i){var l={rootApi:"/api",methodGet:"GET",methodPost:"POST",methodPatch:"PATCH",methodDelete:"DELETE",urlGet:"{{rootApi}}/{{entity}}",urlGetById:"{{rootApi}}/{{entity}}/{{id}}",urlPost:"{{rootApi}}/{{entity}}",urlPatch:"{{rootApi}}/{{entity}}/{{id}}",urlDelete:"{{rootApi}}/{{entity}}/{{id}}",functionHttp:function(i){return i.functionHttp?i.functionHttp(i):e(function(e,a){n({url:t(i.url)(i),method:i.method,params:i.params,data:i.data}).then(function(t){(i.functionData||l.functionData)(t,e,a)},function(e){a(e.data)})})},functionData:function(e,t,n){t(e)},formType:"inline",deleteConfirm:!0,tableLimit:10,limitOptions:[10,20,30],translate:function(e){return e}},a={editTitle:"Edit",detailTitle:"Detail",createTitle:"Create",deleteError:"Error while trying to delete row",deleteErrorTitle:"Error deleting",deleteConfirmTitle:"Delete",deleteConfirmMessage:"Are you sure you want to delete the row?",tablePaginationPage:"Page",tablePaginationRowsPerPage:"Rows per page:",tablePaginationOf:"of",createOption:"Create",btnConfirmOk:"Yes",btnConfirmCancel:"No",btnAlertOk:"Ok",generalErrorTitle:"Error",messageRequired:"Required",messageMinlength:"Min length",messageMaxlength:"Max length",messagePattern:"Invalid input format.",messageMin:"Min value",messageMax:"Max value",messageMimetype:"Invalid file type.",messageValid:"Invalid input format.",messageMindate:"Min date",messageMaxdate:"Max date",formCancel:"Cancel",formSubmit:"Save"};return{options:l,setDefaultOptions:function(e){angular.extend(l,i.removeNull(e))},text:a,setDefaultText:function(e){angular.extend(a,i.removeNull(e))},get:function(e){var t={url:e.urlGet||l.urlGet,method:e.methodGet||l.methodGet,rootApi:l.rootApi};return angular.extend(t,i.removeNull(e)),l.functionHttp(t)},getById:function(e){var t={url:e.urlGetById||l.urlGetById,method:e.methodGet||l.methodGet,rootApi:l.rootApi};return angular.extend(t,i.removeNull(e)),l.functionHttp(t)},post:function(e){var t={url:e.urlPost||l.urlPost,method:e.methodPost||l.methodPost,rootApi:l.rootApi};return angular.extend(t,i.removeNull(e)),l.functionHttp(t)},patch:function(e){var t={url:e.urlPatch||l.urlPatch,method:e.methodPatch||l.methodPatch,rootApi:l.rootApi};return angular.extend(t,i.removeNull(e)),l.functionHttp(t)},delete:function(e){var t={url:e.urlDelete||l.urlDelete,method:e.methodDelete||l.methodDelete,rootApi:l.rootApi};return angular.extend(t,i.removeNull(e)),l.functionHttp(t)}}}angular.module("mdCrudModule").service("mdCrudService",["$q","$interpolate","$http","mdCrudToolsService",e])}(),function(){"use strict";function e(e){return{showConfirm:function(t,n,i,l){i=i||"Yes",l=l||"No";var a=e.confirm().title(t).ariaLabel(t).textContent(n).ok(i).cancel(l);return e.show(a)},showAlert:function(t,n,i){i=i||"Ok",e.show(e.alert().clickOutsideToClose(!0).title(t).ariaLabel(t).textContent(n).ok(i))},getBase64:function(e){return $q(function(t,n){var i=new FileReader;i.readAsDataURL(e),i.onload=function(){t(i.result)},i.onerror=function(e){n(e)}})},removeNullRecursive:function(e){var t=function(e,n){var i=n[e];if(null===i||void 0===i)delete n[e];else if("object"==typeof i)for(var l in i)t(l,i)};for(var n in e)t(n,e);return e},removeNull:function(e){for(var t in e){var n=e[t];null!==n&&void 0!==n||delete e[t]}return e},evalFunction:function(e,t){return angular.isFunction(e)?e(t):e},evalDefined:function(e){for(var t in e)if(angular.isDefined(e[t]))return e[t]}}}angular.module("mdCrudModule").service("mdCrudToolsService",["$mdDialog",e])}(); \ No newline at end of file +angular.module("mdCrudTemplates",[]).run(["$templateCache",function(e){e.put("/views/crud.html",'
{{translate(text.createOption)}}

{{translate(field.label)}}
{{ row[field.name] | date:\'shortDate\' }} {{ row[field.name] | date:\'shortTime\' }} {{ row[field.name] | date:\'short\' }} {{ getTextSelect(field, row) }} {{translate(row[field.name])}}
'),e.put("/views/crudForm.html",'

{{translate(field.label)}}{{mdSelectItem[field.text || \'text\']}}{{mdSelectItem[field.text || \'text\']}}
access_time
access_time
{{translate(message)}}
{{translate(option.formCancelText || text.formCancel)}}
{{translate(option.formSubmit || text.formSubmit)}}
'),e.put("/views/crudFormDialog.html",'

{{formTitle | translate}}

close
'),e.put("/views/crudFormMessages.html",'
{{translate(field.messageRequired || text.messageRequired)}}
{{translate(field.messageMinlength || text.messageMinlength)}} ({{field.minlength}}).
{{translate(field.messageMaxlength || text.messageMaxlength)}} ({{field.maxlength}}).
{{translate(field.messagePattern || text.messagePattern)}}
{{translate(field.messageMin || text.messageMin)}} ({{field.min}}).
{{translate(field.messageMax || text.messageMax)}} ({{field.max}}).
{{translate(field.messageMimetype || text.messageMimetype)}}
{{translate(field.messageValid || text.messageValid)}}
{{translate(field.messageMindate || text.messageMindate)}} {{field.minDate | date:\'shortDate\'}}.
{{translate(field.messageMaxdate || text.messageMaxdate)}} {{field.maxDate | date:\'shortDate\'}}.
')}]),function(){"use strict";angular.module("mdCrudModule",["mdCrudTemplates"])}(),function(){"use strict";function e(e,t,n,i,a){function l(l,d,o){var r=e.text;l.text=r;var s=e.options.translate;l.translate=s;var m=l.options;m.id=m.id||"id",l.formType=t.evalDefined([o.formType,m.formType,e.options.formType]);var c=t.evalDefined([o.deleteConfirm,m.deleteConfirm,e.options.deleteConfirm]),u=t.evalDefined([o.autoRefresh,m.autoRefresh,e.options.autoRefresh]),f=t.evalDefined([o.getParams,m.getParams,{}]);l.searchText=o.searchText||m.searchText||"",l.searchDelay=o.searchDelay||m.searchDelay||(m.serverSide?500:0),l.fields=m.fields,l.rowSelected=null,l.rowCreate=null,l.ef=t.evalFunction,l.stringToHtml=function(e,t){return a.trustAsHtml(i(e)(t))},l.isLoading=!0,l.getTextSelect=function(e,n){if(e.getTextSelect)return e.getTextSelect(e,n);var i=t.evalFunction(e.data,n);for(var a in i)if(i[a][e.value]==n[e.name])return i[a][e.text];return n[e.name]},l.onSearchTextChange=function(e){l.searchText=e,m.serverSide&&m.serverSide.searchParam&&(l.table.page=1,m.refresh())},l.table={rows:[],refresh:function(t){l.isLoading=!0,angular.extend(f,t);var n=angular.copy(m.http);n.entity=m.entity,n.params=angular.copy(n.params||{}),angular.extend(n.params,f),m.serverSide&&(m.serverSide.pageParam&&(n.params[m.serverSide.pageParam||"page"]=l.table.page),m.serverSide.offsetParam&&(n.params[m.serverSide.offsetParam||"offset"]=(l.table.page-1)*l.table.limit),m.serverSide.limitParam&&(n.params[m.serverSide.limitParam||"limit"]=l.table.limit),m.serverSide.searchParam&&(n.params[m.serverSide.searchParam||"search"]=""!=l.searchText?l.searchText:void 0)),l.table.promise=e.get(n).then(function(e){l.isLoading=!1,l.table.rows=e.data,m.serverSide&&(l.table.total=e.total)})},create:function(e){e.stopPropagation(),l.rowSelected=null,l.rowCreate={},"window"==l.formType&&g({},!0,e).then(function(e){})},edit:function(e,t){t.stopPropagation(),e[m.id]&&("inline"==l.formType&&l.selectRow(e,!0),"window"==l.formType&&g(e,!0,t).then(function(e){}))},detail:function(e,t){t.stopPropagation(),"inline"==l.formType&&(l.rowSelected==e?l.rowSelected=null:m.noDetail||l.selectRow(e,!1)),"window"==l.formType&&g(e,!1,t).then(function(e){})},delete:function(n,i){l.rowSelected=null,i.stopPropagation();var a=this,d=this.rows.findIndex(function(e){return e[m.id]==n}),o=angular.copy(m.http);o.entity=m.entity,o.id=n;var u=function(){e.delete(o).then(function(e){a.rows.splice(d,1)},function(e){e||(e=r.deleteError),t.showAlert(s(r.deleteErrorTitle),s(e),s(r.btnAlertOk))})};c?t.showConfirm(s(r.deleteConfirmTitle),s(r.deleteConfirmMessage),s(r.deleteConfirmOk),s(r.btnConfirmCancel),s(r.btnConfirmCancel)).then(function(){u()}):u()},promise:null,order:"",limit:t.evalDefined([o.tableLimit,m.tableLimit,e.options.tableLimit]),limitOptions:t.evalDefined([o.limitOptions,m.limitOptions,e.options.limitOptions]),page:1,rowSelection:!1,selected:[],labels:function(){return{page:s(r.tablePaginationPage),rowsPerPage:s(r.tablePaginationRowsPerPage),of:s(r.tablePaginationOf)}},onPaginate:function(){m.serverSide&&l.table.refresh()}},m.refresh=function(e){l.table.refresh(e)},u&&m.refresh();var g=function(e,t,i){return l.formEditable=t,n.show({controller:["$scope","$mdDialog","mdCrudService","item","options",p],templateUrl:"/views/crudFormDialog.html",clickOutsideToClose:!0,fullscreen:!0,scope:l,preserveScope:!0,controllerAs:"vm",locals:{item:e,options:m},targetEvent:i,parent:d})};l.templateUrl=(m.form||{}).templateUrl,l.onOpen=function(e){(m.form||{}).onOpen&&m.form.onOpen(e)},l.onEdit=function(e){(m.form||{}).onEdit&&m.form.onEdit(e)},l.onCancel=function(e){(m.form||{}).onCancel&&m.form.onCancel(e),l.rowSelected=null,l.rowCreate=null,e&&t.showAlert(s(r.generalErrorTitle),s(e),s(r.btnAlertOk))},l.onSussces=function(e,t){(m.form||{}).onSussces&&m.form.onSussces(e,t),"create"==t&&l.table.rows.unshift(e),l.rowSelected=null,l.rowCreate=null},l.selectRow=function(e,t){l.rowSelected=e,l.formEditable=t};var p=function(e,t,n,i,a){e.formTitle=s(i[a.id]?e.formEditable?r.editTitle:r.detailTitle:r.createTitle),e.item=i,e.onCancelDialog=function(e){(a.form||{}).onCancel&&a.form.onCancel(e),t.cancel()},e.onSusscesDialog=function(e,n){(a.form||{}).onSussces&&a.form.onSussces(e,n),t.hide(e)},e.cancelDialog=function(){e.onCancelDialog(i)}}}var d={link:l,restrict:"EA",scope:{options:"="},templateUrl:"/views/crud.html"};return d}angular.module("mdCrudModule").directive("mdCrud",e),e.$inject=["mdCrudService","mdCrudToolsService","$mdDialog","$interpolate","$sce"]}(),function(){"use strict";function e(e,t,n){function i(n,i,l){var d=e.text;n.text=d;var o=e.options.translate;n.translate=o;var r=n.options;n.fields=r.fields,n.readonly=0==n.editable,n.ef=t.evalFunction,n.isLoading=!1;var s=n.ngModel[r.id];if(n.formTitle=s?n.editable?d.editTitle:d.detailTitle:d.createTitle,n.formType=s?n.editable?"edit":"detail":"create",n.fields=r.fields,n.item={},n.getContentUrl=function(e,t){return n.templateUrl||"/views/crudForm.html"},n.showTimePicker=function(e,t,n){a&&a(t[n],{targetEvent:e}).then(function(e){t[n]=e})},n.onOpen&&n.onOpen(n.item),s){n.isLoading=!0;var m=angular.copy(r.http);m.entity=r.entity,m.id=s,e.getById(m).then(function(e){n.item=e.data,n.onEdit&&n.onEdit(n.item),n.isLoading=!1},function(e){n.onError&&n.onError(e),n.cancel(e)})}n.save=function(){var t,i=angular.copy(r.http);i.entity=r.entity,i.data=n.item,s?(i.id=n.item[r.id],t=e.patch(i)):t=e.post(i),n.isLoading=!0,t.then(function(e){angular.copy(e.data,n.ngModel),n.onSussces&&n.onSussces(e.data,n.formType),n.isLoading=!1},function(e){e.details?n.errors=e.details:n.errors=[e.error],n.onError&&n.onError(e),n.isLoading=!1})},n.cancel=function(e){n.onCancel&&n.onCancel(e)},n.onMarkerDrag=function(e){n.item[this.data.lat]=e.latLng.lat(),n.item[this.data.lng]=e.latLng.lng()}}var a;try{a=n.get("$mdpTimePicker")}catch(e){}var l={link:i,restrict:"EA",scope:{options:"=",ngModel:"=",onOpen:"=",onEdit:"=",onCancel:"=",onSussces:"=",templateUrl:"
'};return l}angular.module("mdCrudModule").directive("mdCrudForm",e),e.$inject=["mdCrudService","mdCrudToolsService","$injector"]}(),function(){"use strict";function e(e,t,n,i){var a={rootApi:"/api",methodGet:"GET",methodPost:"POST",methodPatch:"PATCH",methodDelete:"DELETE",urlGet:"{{rootApi}}/{{entity}}",urlGetById:"{{rootApi}}/{{entity}}/{{id}}",urlPost:"{{rootApi}}/{{entity}}",urlPatch:"{{rootApi}}/{{entity}}/{{id}}",urlDelete:"{{rootApi}}/{{entity}}/{{id}}",functionHttp:function(i,l){return i.functionHttp?i.functionHttp(i):e(function(e,d){n({url:t(i.url)(i),method:i.method,params:i.params,data:i.data}).then(function(t){(i.functionData||a.functionData)(t,e,d,l)},function(e){d(e.data)})})},functionData:function(e,t,n,i){t(e)},formType:"inline",deleteConfirm:!0,tableLimit:10,limitOptions:[10,20,30],translate:function(e){return e}},l={editTitle:"Edit",detailTitle:"Detail",createTitle:"Create",deleteError:"Error while trying to delete row",deleteErrorTitle:"Error deleting",deleteConfirmTitle:"Delete",deleteConfirmMessage:"Are you sure you want to delete the row?",tablePaginationPage:"Page",tablePaginationRowsPerPage:"Rows per page:",tablePaginationOf:"of",createOption:"Create",btnConfirmOk:"Yes",btnConfirmCancel:"No",btnAlertOk:"Ok",generalErrorTitle:"Error",messageRequired:"Required",messageMinlength:"Min length",messageMaxlength:"Max length",messagePattern:"Invalid input format.",messageMin:"Min value",messageMax:"Max value",messageMimetype:"Invalid file type.",messageValid:"Invalid input format.",messageMindate:"Min date",messageMaxdate:"Max date",formCancel:"Cancel",formSubmit:"Save"};return{options:a,setDefaultOptions:function(e){angular.extend(a,i.removeNull(e))},text:l,setDefaultText:function(e){angular.extend(l,i.removeNull(e))},get:function(e){var t={url:e.urlGet||a.urlGet,method:e.methodGet||a.methodGet,rootApi:a.rootApi};return angular.extend(t,i.removeNull(e)),a.functionHttp(t,"get")},getById:function(e){var t={url:e.urlGetById||a.urlGetById,method:e.methodGet||a.methodGet,rootApi:a.rootApi};return angular.extend(t,i.removeNull(e)),a.functionHttp(t,"getById")},post:function(e){var t={url:e.urlPost||a.urlPost,method:e.methodPost||a.methodPost,rootApi:a.rootApi};return angular.extend(t,i.removeNull(e)),a.functionHttp(t,"post")},patch:function(e){var t={url:e.urlPatch||a.urlPatch,method:e.methodPatch||a.methodPatch,rootApi:a.rootApi};return angular.extend(t,i.removeNull(e)),a.functionHttp(t,"patch")},delete:function(e){var t={url:e.urlDelete||a.urlDelete,method:e.methodDelete||a.methodDelete,rootApi:a.rootApi};return angular.extend(t,i.removeNull(e)),a.functionHttp(t,"delete")}}}angular.module("mdCrudModule").service("mdCrudService",["$q","$interpolate","$http","mdCrudToolsService",e])}(),function(){"use strict";function e(e){return{showConfirm:function(t,n,i,a){i=i||"Yes",a=a||"No";var l=e.confirm().title(t).ariaLabel(t).textContent(n).ok(i).cancel(a);return e.show(l)},showAlert:function(t,n,i){i=i||"Ok",e.show(e.alert().clickOutsideToClose(!0).title(t).ariaLabel(t).textContent(n).ok(i))},getBase64:function(e){return $q(function(t,n){var i=new FileReader;i.readAsDataURL(e),i.onload=function(){t(i.result)},i.onerror=function(e){n(e)}})},removeNullRecursive:function(e){var t=function(e,n){var i=n[e];if(null===i||void 0===i)delete n[e];else if("object"==typeof i)for(var a in i)t(a,i)};for(var n in e)t(n,e);return e},removeNull:function(e){for(var t in e){var n=e[t];null!==n&&void 0!==n||delete e[t]}return e},evalFunction:function(e,t){return angular.isFunction(e)?e(t):e},evalDefined:function(e){for(var t in e)if(angular.isDefined(e[t]))return e[t]}}}angular.module("mdCrudModule").service("mdCrudToolsService",["$mdDialog",e])}(); \ No newline at end of file diff --git a/package.json b/package.json index 32a855b..fb61d9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "md-crud", - "version": "0.1.3", + "version": "0.1.4", "author": "Heli Perez ", "registry": "github", "repository": { diff --git a/src/directives/crud.js b/src/directives/crud.js index 5aa4576..eeace5e 100644 --- a/src/directives/crud.js +++ b/src/directives/crud.js @@ -5,9 +5,9 @@ .module('mdCrudModule') .directive('mdCrud', crudDirective); - crudDirective.$inject = ['mdCrudService', 'mdCrudToolsService', '$mdDialog', '$interpolate']; + crudDirective.$inject = ['mdCrudService', 'mdCrudToolsService', '$mdDialog', '$interpolate', '$sce']; - function crudDirective(crudService, tools, $mdDialog, $interpolate) { + function crudDirective(crudService, tools, $mdDialog, $interpolate, $sce) { var directive = { link: link, restrict: 'EA', @@ -32,6 +32,8 @@ var deleteConfirm = tools.evalDefined([attrs.deleteConfirm, options.deleteConfirm, crudService.options.deleteConfirm]); var autoRefresh = tools.evalDefined([attrs.autoRefresh, options.autoRefresh, crudService.options.autoRefresh]); var getParams = tools.evalDefined([attrs.getParams, options.getParams, {}]); + $scope.searchText = attrs.searchText || options.searchText || ""; + $scope.searchDelay = attrs.searchDelay || options.searchDelay || (options.serverSide ? 500 : 0); $scope.fields = options.fields; $scope.rowSelected = null; @@ -40,7 +42,7 @@ $scope.ef = tools.evalFunction; $scope.stringToHtml = function(str, data) { - return $interpolate(str)(data); + return $sce.trustAsHtml($interpolate(str)(data)); } $scope.isLoading = true; @@ -56,21 +58,32 @@ return row[field.name]; } + $scope.onSearchTextChange = function(text) { + $scope.searchText = text; + if(options.serverSide && options.serverSide.searchParam) { + $scope.table.page = 1; + options.refresh(); + } + } + $scope.table = { rows: [], refresh: function (params) { $scope.isLoading = true; - if (params) - getParams = params; - var optionsGet = {}; - angular.extend(optionsGet, options.http); + angular.extend(getParams, params); + var optionsGet = angular.copy(options.http); optionsGet.entity = options.entity; - optionsGet.params = getParams; + optionsGet.params = angular.copy(optionsGet.params || {}); + angular.extend(optionsGet.params, getParams); if(options.serverSide) { - optionsGet.params[options.serverSide.pageParam | 'page'] = $scope.table.page; - optionsGet.params[options.serverSide.limitParam | 'limit'] = $scope.table.limit; - optionsGet.params[options.serverSide.offsetParam | 'offset'] = $scope.table.page * $scope.table.limit; - optionsGet.params[options.serverSide.searchParam | 'search'] = $scope.searchText; + if(options.serverSide.pageParam) + optionsGet.params[options.serverSide.pageParam || 'page'] = $scope.table.page; + if(options.serverSide.offsetParam) + optionsGet.params[options.serverSide.offsetParam || 'offset'] = ($scope.table.page - 1) * $scope.table.limit; + if(options.serverSide.limitParam) + optionsGet.params[options.serverSide.limitParam || 'limit'] = $scope.table.limit; + if(options.serverSide.searchParam) + optionsGet.params[options.serverSide.searchParam || 'search'] = ($scope.searchText != "") ? $scope.searchText : undefined; } $scope.table.promise = crudService.get(optionsGet).then(function (response) { $scope.isLoading = false; @@ -125,12 +138,11 @@ var index = this.rows.findIndex(function (r) { return r[options.id] == rowId; }); - var optionsDelete = {}; - angular.extend(optionsDelete, options.http); - optionsDelete.entity = options.entity; - optionsDelete.id = rowId; + var optionsHttp = angular.copy(options.http); + optionsHttp.entity = options.entity; + optionsHttp.id = rowId; var deleteFunct = function () { - crudService.delete(optionsDelete).then(function (data) { + crudService.delete(optionsHttp).then(function (data) { t.rows.splice(index, 1); }, function (error) { if (!error) @@ -161,6 +173,10 @@ rowsPerPage: translate(text.tablePaginationRowsPerPage), of: translate(text.tablePaginationOf) } + }, + onPaginate: function() { + if(options.serverSide) + $scope.table.refresh(); } } diff --git a/src/directives/crudForm.js b/src/directives/crudForm.js index 0591a2e..05241c3 100644 --- a/src/directives/crudForm.js +++ b/src/directives/crudForm.js @@ -71,8 +71,7 @@ if (idValue) { $scope.isLoading = true; - var optionsHttp = {}; - angular.extend(optionsHttp, options.http); + var optionsHttp = angular.copy(options.http); optionsHttp.entity = options.entity; optionsHttp.id = idValue; crudService.getById(optionsHttp).then(function (response) { @@ -89,8 +88,7 @@ $scope.save = function () { var promise; - var optionsHttp = {}; - angular.extend(optionsHttp, options.http); + var optionsHttp = angular.copy(options.http); optionsHttp.entity = options.entity; optionsHttp.data = $scope.item; if (idValue) { diff --git a/src/services/crudService.js b/src/services/crudService.js index c7c2ee0..ae2c1b7 100644 --- a/src/services/crudService.js +++ b/src/services/crudService.js @@ -15,7 +15,7 @@ urlPost: '{{rootApi}}/{{entity}}', urlPatch: '{{rootApi}}/{{entity}}/{{id}}', urlDelete: '{{rootApi}}/{{entity}}/{{id}}', - functionHttp: function(options) { + functionHttp: function(options, method) { if(options.functionHttp) return options.functionHttp(options); return $q(function (resolve, reject) { @@ -25,13 +25,13 @@ params: options.params, data: options.data }).then(function (response) { - (options.functionData || defaultOptions.functionData)(response, resolve, reject); + (options.functionData || defaultOptions.functionData)(response, resolve, reject, method); }, function (response) { reject(response.data); }); }) }, - functionData: function(response, resolve, reject) { + functionData: function(response, resolve, reject, method) { resolve(response); }, formType: 'inline', @@ -89,7 +89,7 @@ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'get'); }, getById: function (options) { var httpOptions = { @@ -98,7 +98,7 @@ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'getById'); }, post: function (options) { var httpOptions = { @@ -107,7 +107,7 @@ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'post'); }, patch: function (options) { var httpOptions = { @@ -116,7 +116,7 @@ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'patch'); }, delete: function (options) { var httpOptions = { @@ -125,7 +125,7 @@ rootApi: defaultOptions.rootApi }; angular.extend(httpOptions, tools.removeNull(options)); - return defaultOptions.functionHttp(httpOptions); + return defaultOptions.functionHttp(httpOptions, 'delete'); }, }; } diff --git a/src/views/crud.html b/src/views/crud.html index 097638c..7844a55 100644 --- a/src/views/crud.html +++ b/src/views/crud.html @@ -8,7 +8,8 @@ - +
@@ -46,7 +47,7 @@ {{translate(row[field.name])}}
- +
@@ -75,7 +76,8 @@ md-total="{{options.serverSide ? table.total : (table.rows | filter:searchText).length}}" md-page-select md-label="{{table.labels()}}" - style="background-color: white"> + style="background-color: white" + md-on-paginate="table.onPaginate">