From a76380557649eedaeb907f27cd9431c7d5fd67f5 Mon Sep 17 00:00:00 2001 From: EugenDraytsev Date: Thu, 4 Feb 2016 00:33:29 +0300 Subject: [PATCH] Added multiselect support. Some code improvements --- demo/bootstrap/index.html | 3 +- demo/bootstrap/multiple.html | 6 ++- dist/dataGrid.js | 73 ++++++++++++++-------------------- dist/dataGrid.min.js | 2 +- src/js/dataGrid.js | 77 ++++++++++++++++-------------------- 5 files changed, 70 insertions(+), 91 deletions(-) diff --git a/demo/bootstrap/index.html b/demo/bootstrap/index.html index f716c1b..c2cf1d0 100644 --- a/demo/bootstrap/index.html +++ b/demo/bootstrap/index.html @@ -67,7 +67,6 @@

Additional Demos

class="form-control" uib-datepicker-popup="dd/MM/yyyy" placeholder="DD/MM/YYYY" - min-date="dateFrom" max-date="dateTo" close-text="Close" ng-model="dateFrom" @@ -117,7 +116,7 @@

Additional Demos

- Clear Dates + Clear Dates
diff --git a/demo/bootstrap/multiple.html b/demo/bootstrap/multiple.html index 5873f2a..a1bcaf7 100644 --- a/demo/bootstrap/multiple.html +++ b/demo/bootstrap/multiple.html @@ -37,6 +37,7 @@

First Grid

ng-change="gridActions1.filter()" ng-model="name" filter-by="name" + grid-id="grid1" filter-type="text"> @@ -130,7 +131,8 @@

Second Grid

@@ -224,7 +226,7 @@

Second Grid

- + \ No newline at end of file diff --git a/dist/dataGrid.js b/dist/dataGrid.js index 7f1a0e3..94666e8 100644 --- a/dist/dataGrid.js +++ b/dist/dataGrid.js @@ -14,17 +14,19 @@ }) .controller('gridController', ['$scope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $element, $filter, $location, filtersFactory) { // values by default - $scope._gridOptions = deepFind($scope, $element.attr('grid-options')); - $scope._gridActions = deepFind($scope, $element.attr('grid-actions')); + $scope._gridOptions = $scope.$eval($element.attr('grid-options')); + $scope._gridActions = $scope.$eval($element.attr('grid-actions')); $scope.serverPagination = $element.attr('server-pagination') === 'true'; $scope.getDataDelay = $element.attr('get-delay') || 350; if (!$scope._gridActions) { - $scope.$parent[$element.attr('grid-actions')] = {}; - $scope._gridActions = $scope.$parent[$element.attr('grid-actions')]; + $scope.$parent.$eval($element.attr('grid-actions') + '= {}'); + $scope._gridActions = $scope.$parent.$eval($element.attr('grid-actions')); } - $scope.filtered = angular.copy($scope._gridOptions.data); + $scope._gridOptions.grid = $scope; + + $scope.filtered = $scope._gridOptions.data.slice(); $scope.paginationOptions = $scope._gridOptions.pagination ? angular.copy($scope._gridOptions.pagination) : {}; $scope.defaultsPaginationOptions = { itemsPerPage: $scope.paginationOptions.itemsPerPage || '10', @@ -105,7 +107,7 @@ //custom filters $scope.filters.forEach(function (filter) { var urlName = filter.model, - value = $scope[urlName]; + value = $scope.$eval(urlName); if (filter.disableUrl) { needApplyFilters = true; @@ -152,29 +154,35 @@ //custom filters $scope.filters.forEach(function (filter) { var urlName = filter.model, - value = customParams[urlName], - scope = $scope; + value = customParams[urlName]; if (filter.disableUrl) { return; } - if (~filter.filterType.toLowerCase().indexOf('date') && value) { - scope[urlName] = new Date(value); + //datepicker-specific + if (~filter.filterType.toLowerCase().indexOf('date')) { + $scope.$parent.__evaltmp = value ? new Date(value) : null; + $scope.$parent.$eval(urlName + '=__evaltmp'); return; } + if (filter.filterType === 'select' && !value) { - value = ""; + value = ''; } - scope[urlName] = value; + if (value) { + $scope.__evaltmp = value; + $scope.$eval(urlName + '=__evaltmp'); + } }); if (!$scope.serverPagination) { applyCustomFilters(); } + //pagination options $scope.paginationOptions.itemsPerPage = $scope.defaultsPaginationOptions.itemsPerPage; $scope.paginationOptions.currentPage = $scope.defaultsPaginationOptions.currentPage; @@ -252,7 +260,7 @@ $scope.filters.forEach(function (filter) { var predicate = filter.filterBy, urlName = filter.model, - value = $scope[urlName], + value = $scope.$eval(urlName), type = filter.filterType; if ($scope.customFilters[urlName]) { $scope.filtered = $scope.customFilters[urlName]($scope.filtered, value, predicate); @@ -265,24 +273,19 @@ }); } }]) - .directive('gridData', ['$compile', '$animate', function ($compile, $animate) { + .directive('gridData', ['$compile', '$animate', function ($compile) { return { restrict: 'EA', - transclude: true, - replace: true, + scope: true, controller: 'gridController', - link: function ($scope, $element, attrs, controller, $transclude) { + link: function ($scope, $element, attrs) { var sorting = [], filters = [], rows = [], - childScope = $scope.$new(), directiveElement = $element.parent(), gridId = attrs.id, serverPagination = attrs.serverPagination === 'true'; - $transclude($scope, function (clone) { - $animate.enter(clone, $element); - }); angular.forEach(angular.element(directiveElement[0].querySelectorAll('[sortable]')), function (sortable) { var element = angular.element(sortable), @@ -292,7 +295,7 @@ predicate + "' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '" + predicate + "' && sortOptions.direction === 'desc'}"); element.attr('ng-click', "sort('" + predicate + "')"); - $compile(element)(childScope); + $compile(element)($scope); }); angular.forEach(angular.element(document.querySelectorAll('[filter-by]')), function (filter) { @@ -309,20 +312,18 @@ if (filterType !== 'select') { } else { - $scope[urlName + 'Options'] = generateOptions(deepFind($scope, $element.attr('grid-options') + '.data'), predicate); + $scope[urlName + 'Options'] = generateOptions($scope.$eval($element.attr('grid-options') + '.data'), predicate); } if (~filterType.indexOf('date') && !element.attr('ng-focus') && !element.attr('ng-blur')) { element.attr('ng-focus', "filter('{" + urlName + " : " + "this." + urlName + "}')"); element.attr('ng-blur', "filter('{" + urlName + " : " + "this." + urlName + "}')"); - $compile(element)($scope); } if (!urlName) { urlName = predicate; element.attr('ng-model', predicate); element.attr('ng-change', 'filter()'); - $compile(element)($scope); } filters.push({ @@ -332,6 +333,8 @@ filterType: filterType, disableUrl: disableUrl }); + + $compile(element)($scope); }); angular.forEach(angular.element(directiveElement[0].querySelectorAll('[grid-item]')), function (row) { @@ -342,7 +345,7 @@ } else { element.attr('ng-repeat', "item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"); } - $compile(element)(childScope); + $compile(element)($scope); }); $scope.sorting = sorting; @@ -360,7 +363,7 @@ function textFilter(items, value, predicate) { return items.filter(function (item) { - return value && item[predicate] ? ~(item[predicate] + '').toLowerCase().indexOf(value.toLowerCase()) : true; + return value && item[predicate] ? ~(item[predicate] + '').toLowerCase().indexOf((value + '').toLowerCase()) : true; }); } @@ -406,22 +409,6 @@ } }); - function deepFind(obj, path) { - var paths = path.split('.'), - current = obj, - i; - - for (i = 0; i < paths.length; ++i) { - if (current[paths[i]] == undefined) { - return undefined; - } else { - current = current[paths[i]]; - } - } - return current; - } - - function generateOptions(values, predicate) { var array = []; if (values) { diff --git a/dist/dataGrid.min.js b/dist/dataGrid.min.js index 742af5b..f745d92 100644 --- a/dist/dataGrid.min.js +++ b/dist/dataGrid.min.js @@ -1 +1 @@ -!function(){"use strict";function t(t,e){var i,r=e.split("."),n=t;for(i=0;ii.filtered.length?i.paginationOptions.currentPage=1:i.paginationOptions.currentPage=e.page),e.sort){var n=e.sort.split("-");i.sortOptions.predicate=decodeURIComponent(n[0]),i.sortOptions.direction=decodeURIComponent(n[1])}i.serverPagination||p()}function l(){var t=a.path().slice(1);i._gridOptions.getData("?"+t,function(t,e){i.filtered=t,i.paginationOptions.totalItems=e})}function p(){var t=Date.now(),e=!1;i._time={},i.sortOptions.predicate&&i.sortCache&&i.sortCache.predicate===i.sortOptions.predicate&&i.sortCache.direction===i.sortOptions.direction?(i.filtered=i.sortCache.data.slice(),e=!0):i.filtered=i._gridOptions.data.slice(),i._time.copy=Date.now()-t;var r=Date.now();g(),i._time.filters=Date.now()-r;var a=Date.now();i.sortOptions.predicate&&!e&&(i.filtered=n("orderBy")(i.filtered,i.sortOptions.predicate,"desc"===i.sortOptions.direction),i.sortCache={data:i.filtered.slice(),predicate:i.sortOptions.predicate,direction:i.sortOptions.direction}),i._time.sort=Date.now()-a,i._time.all=Date.now()-t,i.paginationOptions.totalItems=i.filtered.length}function g(){i.filters.forEach(function(t){var e=t.filterBy,r=t.model,n=i[r],a=t.filterType;if(i.customFilters[r])i.filtered=i.customFilters[r](i.filtered,n,e);else if(n&&a){var s=o.getFilterByType(a);s&&(i.filtered=s(i.filtered,n,e))}})}i._gridOptions=t(i,r.attr("grid-options")),i._gridActions=t(i,r.attr("grid-actions")),i.serverPagination="true"===r.attr("server-pagination"),i.getDataDelay=r.attr("get-delay")||350,i._gridActions||(i.$parent[r.attr("grid-actions")]={},i._gridActions=i.$parent[r.attr("grid-actions")]),i.filtered=angular.copy(i._gridOptions.data),i.paginationOptions=i._gridOptions.pagination?angular.copy(i._gridOptions.pagination):{},i.defaultsPaginationOptions={itemsPerPage:i.paginationOptions.itemsPerPage||"10",currentPage:i.paginationOptions.currentPage||1},i.paginationOptions=angular.copy(i.defaultsPaginationOptions),i.sortOptions=i._gridOptions.sort?angular.copy(i._gridOptions.sort):{},i.customFilters=i._gridOptions.customFilters?angular.copy(i._gridOptions.customFilters):{},i.urlSync=i._gridOptions.urlSync,i.$watch("_gridOptions.data",function(t){t&&t.length&&(i.sortCache={},i.filtered=i._gridOptions.data.slice(),i.filters.forEach(function(t){"select"===t.filterType&&(i[t.model+"Options"]=e(i.filtered,t.filterBy))}),i.urlSync?c(a.path()):p())}),i.sort=function(t){var e=i.sortOptions.predicate===t&&"desc"===i.sortOptions.direction?"asc":"desc";i.sortOptions.predicate=t,i.sortOptions.direction=e,i.paginationOptions.currentPage=1,i.reloadGrid()},i.filter=function(){i.paginationOptions.currentPage=1,i.reloadGrid()},i.$on("$locationChangeSuccess",function(){(i.urlSync||i.serverPagination)&&(i.serverPagination&&(clearTimeout(i.getDataTimeout),i.getDataTimeout=setTimeout(l,i.getDataDelay)),i.filtered&&c(a.path()))}),i.reloadGrid=function(){i.urlSync||i.serverPagination?s():p()},i._gridActions.refresh=i.reloadGrid,i._gridActions.filter=i.filter,i._gridActions.sort=i.sort}]).directive("gridData",["$compile","$animate",function(i,r){return{restrict:"EA",transclude:!0,replace:!0,controller:"gridController",link:function(n,a,o,s,c){var l=[],p=[],g=[],d=n.$new(),u=a.parent(),f=o.id,m="true"===o.serverPagination;c(n,function(t){r.enter(t,a)}),angular.forEach(angular.element(u[0].querySelectorAll("[sortable]")),function(t){var e=angular.element(t),r=e.attr("sortable");l.push(e),e.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+r+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+r+"' && sortOptions.direction === 'desc'}"),e.attr("ng-click","sort('"+r+"')"),i(e)(d)}),angular.forEach(angular.element(document.querySelectorAll("[filter-by]")),function(r){var o=angular.element(r),s=u.find(o).length>0,c=o.attr("filter-by"),l=o.attr("filter-type")||"",g=o.attr("ng-model"),d=o.attr("disable-url");f&&o.attr("grid-id")&&f!=o.attr("grid-id")||("select"!==l||(n[g+"Options"]=e(t(n,a.attr("grid-options")+".data"),c)),!~l.indexOf("date")||o.attr("ng-focus")||o.attr("ng-blur")||(o.attr("ng-focus","filter('{"+g+" : this."+g+"}')"),o.attr("ng-blur","filter('{"+g+" : this."+g+"}')"),i(o)(n)),g||(g=c,o.attr("ng-model",c),o.attr("ng-change","filter()"),i(o)(n)),p.push({model:g,isInScope:s,filterBy:c,filterType:l,disableUrl:d}))}),angular.forEach(angular.element(u[0].querySelectorAll("[grid-item]")),function(t){var e=angular.element(t);g.push(e),m?e.attr("ng-repeat","item in filtered"):e.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),i(e)(d)}),n.sorting=l,n.rows=g,n.filters=p}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return e&&t[i]?t[i]===e:!0})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf(e.toLowerCase()):!0})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]<=e+86399999:!0})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]>=e:!0})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file +!function(){"use strict";function t(t,e){var i=[];return t?(t.forEach(function(t){~i.indexOf(t[e])||i.push(t[e])}),i.map(function(t){return{text:t,value:t}})):void 0}angular.module("dataGrid",[]).filter("startFrom",function(){return function(t,e){return t?(e=+e,t.slice(e)):[]}}).controller("gridController",["$scope","$element","$filter","$location","filtersFactory",function(e,i,r,n,a){function o(){var t,i=!1;t="page="+e.paginationOptions.currentPage,e.paginationOptions.itemsPerPage!==e.defaultsPaginationOptions.itemsPerPage&&(t+="&itemsPerPage="+e.paginationOptions.itemsPerPage),e.sortOptions.predicate&&(t+="&sort="+encodeURIComponent(e.sortOptions.predicate+"-"+e.sortOptions.direction)),e.filters.forEach(function(r){var n=r.model,a=e.$eval(n);if(r.disableUrl)return void(i=!0);if(a){var o;if(a instanceof Date){if(isNaN(a.getTime()))return;o=a.getFullYear()+"-",o+=a.getMonth()<9?"0"+(a.getMonth()+1)+"-":a.getMonth()+1+"-",o+=a.getDate()<10?"0"+a.getDate():a.getDate(),a=o}t+="&"+encodeURIComponent(n)+"="+encodeURIComponent(a)}}),i&&c(),n.path(t)}function s(){var t=n.path().slice(1),i={},r={};if(e.params=i,t.split("&").forEach(function(t){var e=t.split("=");i[e[0]]=e[1],"page"!==e[0]&&"sort"!==e[0]&&"itemsPerPage"!==e[0]&&(r[decodeURIComponent(e[0])]=decodeURIComponent(e[1]))}),e.filters.forEach(function(t){var i=t.model,n=r[i];if(!t.disableUrl){if(~t.filterType.toLowerCase().indexOf("date"))return e.$parent.__evaltmp=n?new Date(n):null,void e.$parent.$eval(i+"=__evaltmp");"select"!==t.filterType||n||(n=""),n&&(e.__evaltmp=n,e.$eval(i+"=__evaltmp"))}}),e.serverPagination||p(),e.paginationOptions.itemsPerPage=e.defaultsPaginationOptions.itemsPerPage,e.paginationOptions.currentPage=e.defaultsPaginationOptions.currentPage,i.itemsPerPage&&(e.paginationOptions.itemsPerPage=i.itemsPerPage),i.page&&(!e.serverPagination&&(i.page-1)*e.paginationOptions.itemsPerPage>e.filtered.length?e.paginationOptions.currentPage=1:e.paginationOptions.currentPage=i.page),i.sort){var a=i.sort.split("-");e.sortOptions.predicate=decodeURIComponent(a[0]),e.sortOptions.direction=decodeURIComponent(a[1])}e.serverPagination||c()}function l(){var t=n.path().slice(1);e._gridOptions.getData("?"+t,function(t,i){e.filtered=t,e.paginationOptions.totalItems=i})}function c(){var t=Date.now(),i=!1;e._time={},e.sortOptions.predicate&&e.sortCache&&e.sortCache.predicate===e.sortOptions.predicate&&e.sortCache.direction===e.sortOptions.direction?(e.filtered=e.sortCache.data.slice(),i=!0):e.filtered=e._gridOptions.data.slice(),e._time.copy=Date.now()-t;var n=Date.now();p(),e._time.filters=Date.now()-n;var a=Date.now();e.sortOptions.predicate&&!i&&(e.filtered=r("orderBy")(e.filtered,e.sortOptions.predicate,"desc"===e.sortOptions.direction),e.sortCache={data:e.filtered.slice(),predicate:e.sortOptions.predicate,direction:e.sortOptions.direction}),e._time.sort=Date.now()-a,e._time.all=Date.now()-t,e.paginationOptions.totalItems=e.filtered.length}function p(){e.filters.forEach(function(t){var i=t.filterBy,r=t.model,n=e.$eval(r),o=t.filterType;if(e.customFilters[r])e.filtered=e.customFilters[r](e.filtered,n,i);else if(n&&o){var s=a.getFilterByType(o);s&&(e.filtered=s(e.filtered,n,i))}})}e._gridOptions=e.$eval(i.attr("grid-options")),e._gridActions=e.$eval(i.attr("grid-actions")),e.serverPagination="true"===i.attr("server-pagination"),e.getDataDelay=i.attr("get-delay")||350,e._gridActions||(e.$parent.$eval(i.attr("grid-actions")+"= {}"),e._gridActions=e.$parent.$eval(i.attr("grid-actions"))),e._gridOptions.grid=e,e.filtered=e._gridOptions.data.slice(),e.paginationOptions=e._gridOptions.pagination?angular.copy(e._gridOptions.pagination):{},e.defaultsPaginationOptions={itemsPerPage:e.paginationOptions.itemsPerPage||"10",currentPage:e.paginationOptions.currentPage||1},e.paginationOptions=angular.copy(e.defaultsPaginationOptions),e.sortOptions=e._gridOptions.sort?angular.copy(e._gridOptions.sort):{},e.customFilters=e._gridOptions.customFilters?angular.copy(e._gridOptions.customFilters):{},e.urlSync=e._gridOptions.urlSync,e.$watch("_gridOptions.data",function(i){i&&i.length&&(e.sortCache={},e.filtered=e._gridOptions.data.slice(),e.filters.forEach(function(i){"select"===i.filterType&&(e[i.model+"Options"]=t(e.filtered,i.filterBy))}),e.urlSync?s(n.path()):c())}),e.sort=function(t){var i=e.sortOptions.predicate===t&&"desc"===e.sortOptions.direction?"asc":"desc";e.sortOptions.predicate=t,e.sortOptions.direction=i,e.paginationOptions.currentPage=1,e.reloadGrid()},e.filter=function(){e.paginationOptions.currentPage=1,e.reloadGrid()},e.$on("$locationChangeSuccess",function(){(e.urlSync||e.serverPagination)&&(e.serverPagination&&(clearTimeout(e.getDataTimeout),e.getDataTimeout=setTimeout(l,e.getDataDelay)),e.filtered&&s(n.path()))}),e.reloadGrid=function(){e.urlSync||e.serverPagination?o():c()},e._gridActions.refresh=e.reloadGrid,e._gridActions.filter=e.filter,e._gridActions.sort=e.sort}]).directive("gridData",["$compile","$animate",function(e){return{restrict:"EA",scope:!0,controller:"gridController",link:function(i,r,n){var a=[],o=[],s=[],l=r.parent(),c=n.id,p="true"===n.serverPagination;angular.forEach(angular.element(l[0].querySelectorAll("[sortable]")),function(t){var r=angular.element(t),n=r.attr("sortable");a.push(r),r.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+n+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+n+"' && sortOptions.direction === 'desc'}"),r.attr("ng-click","sort('"+n+"')"),e(r)(i)}),angular.forEach(angular.element(document.querySelectorAll("[filter-by]")),function(n){var a=angular.element(n),s=l.find(a).length>0,p=a.attr("filter-by"),g=a.attr("filter-type")||"",d=a.attr("ng-model"),u=a.attr("disable-url");c&&a.attr("grid-id")&&c!=a.attr("grid-id")||("select"!==g||(i[d+"Options"]=t(i.$eval(r.attr("grid-options")+".data"),p)),!~g.indexOf("date")||a.attr("ng-focus")||a.attr("ng-blur")||(a.attr("ng-focus","filter('{"+d+" : this."+d+"}')"),a.attr("ng-blur","filter('{"+d+" : this."+d+"}')")),d||(d=p,a.attr("ng-model",p),a.attr("ng-change","filter()")),o.push({model:d,isInScope:s,filterBy:p,filterType:g,disableUrl:u}),e(a)(i))}),angular.forEach(angular.element(l[0].querySelectorAll("[grid-item]")),function(t){var r=angular.element(t);s.push(r),p?r.attr("ng-repeat","item in filtered"):r.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),e(r)(i)}),i.sorting=a,i.rows=s,i.filters=o}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return e&&t[i]?t[i]===e:!0})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf((e+"").toLowerCase()):!0})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]<=e+86399999:!0})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]>=e:!0})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file diff --git a/src/js/dataGrid.js b/src/js/dataGrid.js index 7f1a0e3..89bccc4 100644 --- a/src/js/dataGrid.js +++ b/src/js/dataGrid.js @@ -14,17 +14,19 @@ }) .controller('gridController', ['$scope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $element, $filter, $location, filtersFactory) { // values by default - $scope._gridOptions = deepFind($scope, $element.attr('grid-options')); - $scope._gridActions = deepFind($scope, $element.attr('grid-actions')); + $scope._gridOptions = $scope.$eval($element.attr('grid-options')); + $scope._gridActions = $scope.$eval($element.attr('grid-actions')); $scope.serverPagination = $element.attr('server-pagination') === 'true'; $scope.getDataDelay = $element.attr('get-delay') || 350; if (!$scope._gridActions) { - $scope.$parent[$element.attr('grid-actions')] = {}; - $scope._gridActions = $scope.$parent[$element.attr('grid-actions')]; + $scope.$parent.$eval($element.attr('grid-actions') + '= {}'); + $scope._gridActions = $scope.$parent.$eval($element.attr('grid-actions')); } - $scope.filtered = angular.copy($scope._gridOptions.data); + $scope._gridOptions.grid = $scope; + + $scope.filtered = $scope._gridOptions.data.slice(); $scope.paginationOptions = $scope._gridOptions.pagination ? angular.copy($scope._gridOptions.pagination) : {}; $scope.defaultsPaginationOptions = { itemsPerPage: $scope.paginationOptions.itemsPerPage || '10', @@ -105,7 +107,7 @@ //custom filters $scope.filters.forEach(function (filter) { var urlName = filter.model, - value = $scope[urlName]; + value = $scope.$eval(urlName); if (filter.disableUrl) { needApplyFilters = true; @@ -152,29 +154,35 @@ //custom filters $scope.filters.forEach(function (filter) { var urlName = filter.model, - value = customParams[urlName], - scope = $scope; + value = customParams[urlName]; if (filter.disableUrl) { return; } - if (~filter.filterType.toLowerCase().indexOf('date') && value) { - scope[urlName] = new Date(value); + //datepicker-specific + if (~filter.filterType.toLowerCase().indexOf('date')) { + $scope.$parent.__evaltmp = value ? new Date(value) : null; + $scope.$parent.$eval(urlName + '=__evaltmp'); return; } + if (filter.filterType === 'select' && !value) { - value = ""; + value = ''; } - scope[urlName] = value; + if (value) { + $scope.__evaltmp = value; + $scope.$eval(urlName + '=__evaltmp'); + } }); if (!$scope.serverPagination) { applyCustomFilters(); } + //pagination options $scope.paginationOptions.itemsPerPage = $scope.defaultsPaginationOptions.itemsPerPage; $scope.paginationOptions.currentPage = $scope.defaultsPaginationOptions.currentPage; @@ -252,7 +260,7 @@ $scope.filters.forEach(function (filter) { var predicate = filter.filterBy, urlName = filter.model, - value = $scope[urlName], + value = $scope.$eval(urlName), type = filter.filterType; if ($scope.customFilters[urlName]) { $scope.filtered = $scope.customFilters[urlName]($scope.filtered, value, predicate); @@ -265,24 +273,21 @@ }); } }]) - .directive('gridData', ['$compile', '$animate', function ($compile, $animate) { + .directive('gridData', ['$compile', '$animate', function ($compile) { return { restrict: 'EA', - transclude: true, - replace: true, + //transclude: true, + //replace: true, + scope: true, controller: 'gridController', - link: function ($scope, $element, attrs, controller, $transclude) { + link: function ($scope, $element, attrs) { var sorting = [], filters = [], rows = [], - childScope = $scope.$new(), directiveElement = $element.parent(), gridId = attrs.id, serverPagination = attrs.serverPagination === 'true'; - $transclude($scope, function (clone) { - $animate.enter(clone, $element); - }); angular.forEach(angular.element(directiveElement[0].querySelectorAll('[sortable]')), function (sortable) { var element = angular.element(sortable), @@ -292,7 +297,7 @@ predicate + "' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '" + predicate + "' && sortOptions.direction === 'desc'}"); element.attr('ng-click', "sort('" + predicate + "')"); - $compile(element)(childScope); + $compile(element)($scope); }); angular.forEach(angular.element(document.querySelectorAll('[filter-by]')), function (filter) { @@ -309,20 +314,20 @@ if (filterType !== 'select') { } else { - $scope[urlName + 'Options'] = generateOptions(deepFind($scope, $element.attr('grid-options') + '.data'), predicate); + $scope[urlName + 'Options'] = generateOptions($scope.$eval($element.attr('grid-options') + '.data'), predicate); } if (~filterType.indexOf('date') && !element.attr('ng-focus') && !element.attr('ng-blur')) { element.attr('ng-focus', "filter('{" + urlName + " : " + "this." + urlName + "}')"); element.attr('ng-blur', "filter('{" + urlName + " : " + "this." + urlName + "}')"); - $compile(element)($scope); + //$compile(element)($scope); } if (!urlName) { urlName = predicate; element.attr('ng-model', predicate); element.attr('ng-change', 'filter()'); - $compile(element)($scope); + //$compile(element)($scope); } filters.push({ @@ -332,6 +337,8 @@ filterType: filterType, disableUrl: disableUrl }); + + $compile(element)($scope); }); angular.forEach(angular.element(directiveElement[0].querySelectorAll('[grid-item]')), function (row) { @@ -342,7 +349,7 @@ } else { element.attr('ng-repeat', "item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"); } - $compile(element)(childScope); + $compile(element)($scope); }); $scope.sorting = sorting; @@ -360,7 +367,7 @@ function textFilter(items, value, predicate) { return items.filter(function (item) { - return value && item[predicate] ? ~(item[predicate] + '').toLowerCase().indexOf(value.toLowerCase()) : true; + return value && item[predicate] ? ~(item[predicate] + '').toLowerCase().indexOf((value + '').toLowerCase()) : true; }); } @@ -406,22 +413,6 @@ } }); - function deepFind(obj, path) { - var paths = path.split('.'), - current = obj, - i; - - for (i = 0; i < paths.length; ++i) { - if (current[paths[i]] == undefined) { - return undefined; - } else { - current = current[paths[i]]; - } - } - return current; - } - - function generateOptions(values, predicate) { var array = []; if (values) {