diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8371bd5..4298c74 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,3 +14,4 @@ _(ordered by first contribution)_ - [Michel Boudreau](https://github.com/mboudreau) - [Sam Milledge](https://github.com/smilledge) - [Phuong Nguyen](https://github.com/phuongnd08) +- [Mark Hamilton](https://github.com/thedarkcode) diff --git a/Gruntfile.js b/Gruntfile.js index 798a03c..612da22 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -15,7 +15,7 @@ module.exports = function (grunt) { 'use strict'; - var banner = '/*! <%= pkg.name %> (v<%= pkg.version %>) - Copyright: 2013 - 2014, <%= pkg.author %> - <%= pkg.license %> */\n'; + var banner = '/*! <%= pkg.name %> (v<%= pkg.version %>) - Copyright: 2013 - 2016, <%= pkg.author %> - <%= pkg.license %> */\n'; grunt.initConfig({ pkg: grunt.file.readJSON('bower.json'), @@ -72,4 +72,4 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-karma'); grunt.registerTask('test', ['jshint', 'karma:dist']); grunt.registerTask('default', ['test', 'concat', 'uglify']); -}; \ No newline at end of file +}; diff --git a/README.md b/README.md index 8635f5e..64d0cb0 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ Okay, we assume that you have a collection of photos and you want to display the * `source`: The collection of objects that should be passed into your _deckgrid_ (by reference. Object change will be reflected in the grid). * `cardTemplate`: The URL to the template which represents one single card in the _deckgrid_. +* `filter`: The filter to be applied to the source collection of objects. +* `order-by`: The orderBy filter to be applied to the source collection of objects. ### Alternative ways to provide the template * `cardTemplateString` attribute: You can provide this attribute *instead* of the `cardTemplate` attribute to use the attribute value directly as the template. Example: @@ -141,13 +143,21 @@ Do you use the `angular-deckgrid` and would like to be featured here? Just send - [theonegenerator.com](http://www.theonegenerator.com/): "This webapp is designed to any user in need of randomly generated data for testing cases, gaming and lottery spins." - [vazoo.de](https://vazoo.de/): "Vazoo - Der Beauty-Preisvergleich" - [vitaliator.com](https://vitaliator.com/): "Vitaliator - Das Fitnessnetzwerk" +- [dryverlessads.com](https://dryverlessads.com/): "Dryverless Ads Offer Wall" ## Changelog -### Version 0.6.0 (Future) +### Version 0.7.0 (Future) - Open: [Bugfix] We need a solution to prevent the model binding for `innerHTML` templates (e.g. `ngIf` not working) [#44](https://github.com/akoenig/angular-deckgrid/issues/44) +### Version 0.6.0 (20161011) + +- Add Filtering. [#88] (https://github.com/akoenig/angular-deckgrid/pull/88) +- Add Order By. [#91] (https://github.com/akoenig/angular-deckgrid/issues/91) +- Add Template Null check. [#94] (https://github.com/akoenig/angular-deckgrid/pull/94) +- Fix destroy of appropriate deckgrid. [#108] (https://github.com/akoenig/angular-deckgrid/pull/108) + ### Version 0.5.0 (20141031) - Upgraded AngularJS dependency in `bower.json` (v1.3.0). diff --git a/angular-deckgrid.js b/angular-deckgrid.js index e57bda8..e3f5f76 100644 --- a/angular-deckgrid.js +++ b/angular-deckgrid.js @@ -1,14 +1,14 @@ -/*! angular-deckgrid (v0.5.0) - Copyright: 2013 - 2014, André König (andre.koenig@posteo.de) - MIT */ +/*! angular-deckgrid (v0.6.0) - Copyright: 2013 - 2016, André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) - MIT */ /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -18,7 +18,7 @@ angular.module('akoenig.deckgrid').directive('deckgrid', [ 'DeckgridDescriptor', - function initialize (DeckgridDescriptor) { + function initialize(DeckgridDescriptor) { 'use strict'; @@ -28,13 +28,13 @@ angular.module('akoenig.deckgrid').directive('deckgrid', [ /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -43,7 +43,7 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ 'Deckgrid', '$templateCache', - function initialize (Deckgrid, $templateCache) { + function initialize(Deckgrid, $templateCache) { 'use strict'; @@ -52,7 +52,7 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ * directive description object. * */ - function Descriptor () { + function Descriptor() { this.restrict = 'AE'; this.template = '
' + @@ -60,7 +60,9 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ '
'; this.scope = { - 'model': '=source' + 'model': '=source', + 'filter': '=', + 'orderBy': '=' }; // @@ -75,35 +77,21 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ // Will be incremented if using inline templates. // this.$$templateKeyIndex = 0; - } - /** - * @private - * - * Cleanup method. Will be called when the - * deckgrid directive should be destroyed. - * - */ - Descriptor.prototype.$$destroy = function $$destroy () { - this.$$deckgrid.destroy(); - }; - /** * @private * * The deckgrid link method. Will instantiate the deckgrid. * */ - Descriptor.prototype.$$link = function $$link (scope, elem, attrs, nullController, transclude) { + Descriptor.prototype.$$link = function $$link(scope, elem, attrs, nullController, transclude) { var templateKey = 'deckgrid/innerHtmlTemplate' + (++this.$$templateKeyIndex) + '.html'; - scope.$on('$destroy', this.$$destroy.bind(this)); - if (angular.isUndefined(attrs.cardtemplate)) { if (angular.isUndefined(attrs.cardtemplatestring)) { // use the provided inner html as template - transclude(scope, function onTransclude (innerHTML) { + transclude(scope, function onTransclude(innerHTML) { var extractedInnerHTML = [], i = 0, len = innerHTML.length, @@ -136,26 +124,27 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ scope.mother = scope.$parent; this.$$deckgrid = Deckgrid.create(scope, elem[0]); + + scope.$on('$destroy', this.$$deckgrid.destroy.bind(this.$$deckgrid)); }; return { - create : function create () { + create: function create() { return new Descriptor(); } }; } ]); - /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -163,8 +152,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ '$window', '$log', + '$filter', - function initialize ($window, $log) { + function initialize($window, $log, $filter) { 'use strict'; @@ -172,9 +162,11 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * The deckgrid directive. * */ - function Deckgrid (scope, element) { + function Deckgrid(scope, element) { var self = this, watcher, + filterWatcher, + orderByWatcher, mql; this.$$elem = element; @@ -199,13 +191,18 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ this.$$watchers.push(watcher); + filterWatcher = this.$$scope.$watchCollection('filter', this.$$onModelChange.bind(this)); + orderByWatcher = this.$$scope.$watchCollection('orderBy', this.$$onModelChange.bind(this)); + this.$$watchers.push(filterWatcher); + this.$$watchers.push(orderByWatcher); + // // Register media query change events. // - angular.forEach(self.$$getMediaQueries(), function onIteration (rule) { + angular.forEach(self.$$getMediaQueries(), function onIteration(rule) { var handler = self.$$onMediaQueryChange.bind(self); - function onDestroy () { + function onDestroy() { rule.removeListener(handler); } @@ -213,7 +210,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ self.$$watchers.push(onDestroy); }); - + mql = $window.matchMedia('(orientation: portrait)'); mql.addListener(self.$$onMediaQueryChange.bind(self)); @@ -230,7 +227,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * @return {array} An array with all respective styles. * */ - Deckgrid.prototype.$$getMediaQueries = function $$getMediaQueries () { + Deckgrid.prototype.$$getMediaQueries = function $$getMediaQueries() { var stylesheets = [], mediaQueries = []; @@ -239,7 +236,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ Array.prototype.slice.call(document.querySelectorAll('link[rel=\'stylesheet\']')) ); - function extractRules (stylesheet) { + function extractRules(stylesheet) { try { return (stylesheet.sheet.cssRules || []); } catch (e) { @@ -247,9 +244,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ } } - function hasDeckgridStyles (rule) { - var regexe = /\[(\w*-)?deckgrid\]::?before/g, - i = 0, + function hasDeckgridStyles(rule) { + var regexe = /\[(\w*-)?deckgrid\]::?before/g, + i = 0, selector = ''; if (!rule.media || angular.isUndefined(rule.cssRules)) { @@ -269,10 +266,10 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ return false; } - angular.forEach(stylesheets, function onIteration (stylesheet) { + angular.forEach(stylesheets, function onIteration(stylesheet) { var rules = extractRules(stylesheet); - angular.forEach(rules, function inRuleIteration (rule) { + angular.forEach(rules, function inRuleIteration(rule) { if (hasDeckgridStyles(rule)) { mediaQueries.push($window.matchMedia(rule.media.mediaText)); } @@ -295,7 +292,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * NOTE that calling this method will trigger a complete template "redraw". * */ - Deckgrid.prototype.$$createColumns = function $$createColumns () { + Deckgrid.prototype.$$createColumns = function $$createColumns() { var self = this; if (!this.$$scope.layout) { @@ -303,9 +300,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ 'https://github.com/akoenig/angular-deckgrid#the-grid-configuration)'); } - this.$$scope.columns = []; + self.$$scope.columns = []; - angular.forEach(this.$$scope.model, function onIteration (card, index) { + angular.forEach($filter('orderBy')($filter('filter')(self.$$scope.model, self.$$scope.filter), self.$$scope.orderBy), function onIteration(card, index) { var column = (index % self.$$scope.layout.columns) | 0; if (!self.$$scope.columns[column]) { @@ -334,7 +331,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * You are responsible for defining the respective styles within your CSS. * */ - Deckgrid.prototype.$$getLayout = function $$getLayout () { + Deckgrid.prototype.$$getLayout = function $$getLayout() { var content = $window.getComputedStyle(this.$$elem, ':before').content, layout; @@ -359,7 +356,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * Event that will be triggered if a CSS media query changed. * */ - Deckgrid.prototype.$$onMediaQueryChange = function $$onMediaQueryChange () { + Deckgrid.prototype.$$onMediaQueryChange = function $$onMediaQueryChange() { var self = this, layout = this.$$getLayout(); @@ -367,10 +364,10 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ // Okay, the layout has changed. // Creating a new column structure is not avoidable. // - if (layout.columns !== this.$$scope.layout.columns) { + if (layout && layout.columns !== this.$$scope.layout.columns) { self.$$scope.layout = layout; - self.$$scope.$apply(function onApply () { + self.$$scope.$apply(function onApply() { self.$$createColumns(); }); } @@ -382,7 +379,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * Event that will be triggered when the source model has changed. * */ - Deckgrid.prototype.$$onModelChange = function $$onModelChange (newModel, oldModel) { + Deckgrid.prototype.$$onModelChange = function $$onModelChange(newModel, oldModel) { var self = this; newModel = newModel || []; @@ -398,7 +395,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * watchers and event handlers. * */ - Deckgrid.prototype.destroy = function destroy () { + Deckgrid.prototype.destroy = function destroy() { var i = this.$$watchers.length - 1; for (i; i >= 0; i = i - 1) { @@ -407,7 +404,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ }; return { - create : function create (scope, element) { + create: function create(scope, element) { return new Deckgrid(scope, element); } }; diff --git a/angular-deckgrid.min.js b/angular-deckgrid.min.js index 8ecf45e..147fb4e 100644 --- a/angular-deckgrid.min.js +++ b/angular-deckgrid.min.js @@ -1,2 +1,2 @@ -/*! angular-deckgrid (v0.5.0) - Copyright: 2013 - 2014, André König (andre.koenig@posteo.de) - MIT */ -angular.module("akoenig.deckgrid",[]),angular.module("akoenig.deckgrid").directive("deckgrid",["DeckgridDescriptor",function(a){"use strict";return a.create()}]),angular.module("akoenig.deckgrid").factory("DeckgridDescriptor",["Deckgrid","$templateCache",function(a,b){"use strict";function c(){this.restrict="AE",this.template='
',this.scope={model:"=source"},this.$$deckgrid=null,this.transclude=!0,this.link=this.$$link.bind(this),this.$$templateKeyIndex=0}return c.prototype.$$destroy=function(){this.$$deckgrid.destroy()},c.prototype.$$link=function(c,d,e,f,g){var h="deckgrid/innerHtmlTemplate"+ ++this.$$templateKeyIndex+".html";c.$on("$destroy",this.$$destroy.bind(this)),angular.isUndefined(e.cardtemplate)?(angular.isUndefined(e.cardtemplatestring)?g(c,function(a){var c,d=[],e=0,f=a.length;for(e;f>e;e+=1)c=a[e].outerHTML,angular.isDefined(c)&&d.push(c);b.put(h,d.join())}):b.put(h,d.attr("cardtemplatestring")),c.cardTemplate=h):c.cardTemplate=e.cardtemplate,c.mother=c.$parent,this.$$deckgrid=a.create(c,d[0])},{create:function(){return new c}}}]),angular.module("akoenig.deckgrid").factory("Deckgrid",["$window","$log",function(a,b){"use strict";function c(b,c){var d,e,f=this;this.$$elem=c,this.$$watchers=[],this.$$scope=b,this.$$scope.columns=[],this.$$scope.layout=this.$$getLayout(),this.$$createColumns(),d=this.$$scope.$watchCollection("model",this.$$onModelChange.bind(this)),this.$$watchers.push(d),angular.forEach(f.$$getMediaQueries(),function(a){function b(){a.removeListener(c)}var c=f.$$onMediaQueryChange.bind(f);a.addListener(c),f.$$watchers.push(b)}),e=a.matchMedia("(orientation: portrait)"),e.addListener(f.$$onMediaQueryChange.bind(f))}return c.prototype.$$getMediaQueries=function(){function b(a){try{return a.sheet.cssRules||[]}catch(b){return[]}}function c(a){var b=/\[(\w*-)?deckgrid\]::?before/g,c=0,d="";if(!a.media||angular.isUndefined(a.cssRules))return!1;for(c=a.cssRules.length-1;c>=0;c-=1)if(d=a.cssRules[c].selectorText,angular.isDefined(d)&&d.match(b))return!0;return!1}var d=[],e=[];return d=Array.prototype.concat.call(Array.prototype.slice.call(document.querySelectorAll("style[type='text/css']")),Array.prototype.slice.call(document.querySelectorAll("link[rel='stylesheet']"))),angular.forEach(d,function(d){var f=b(d);angular.forEach(f,function(b){c(b)&&e.push(a.matchMedia(b.media.mediaText))})}),e},c.prototype.$$createColumns=function(){var a=this;return this.$$scope.layout?(this.$$scope.columns=[],void angular.forEach(this.$$scope.model,function(b,c){var d=c%a.$$scope.layout.columns|0;a.$$scope.columns[d]||(a.$$scope.columns[d]=[]),b.$index=c,a.$$scope.columns[d].push(b)})):b.error("angular-deckgrid: No CSS configuration found (see https://github.com/akoenig/angular-deckgrid#the-grid-configuration)")},c.prototype.$$getLayout=function(){var b,c=a.getComputedStyle(this.$$elem,":before").content;return c&&(c=c.replace(/'/g,""),c=c.replace(/"/g,""),c=c.split(" "),2===c.length&&(b={},b.columns=0|c[0],b.classList=c[1].replace(/\./g," ").trim())),b},c.prototype.$$onMediaQueryChange=function(){var a=this,b=this.$$getLayout();b.columns!==this.$$scope.layout.columns&&(a.$$scope.layout=b,a.$$scope.$apply(function(){a.$$createColumns()}))},c.prototype.$$onModelChange=function(a,b){var c=this;a=a||[],b=b||[],angular.equals(b,a)||c.$$createColumns()},c.prototype.destroy=function(){var a=this.$$watchers.length-1;for(a;a>=0;a-=1)this.$$watchers[a]()},{create:function(a,b){return new c(a,b)}}}]); \ No newline at end of file +/*! angular-deckgrid (v0.6.0) - Copyright: 2013 - 2016, André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) - MIT */ +angular.module("akoenig.deckgrid",[]),angular.module("akoenig.deckgrid").directive("deckgrid",["DeckgridDescriptor",function(b){"use strict";return b.create()}]),angular.module("akoenig.deckgrid").factory("DeckgridDescriptor",["Deckgrid","$templateCache",function(b,c){"use strict";function d(){this.restrict="AE",this.template='
',this.scope={model:"=source",filter:"=",orderBy:"="},this.$$deckgrid=null,this.transclude=!0,this.link=this.$$link.bind(this),this.$$templateKeyIndex=0}return d.prototype.$$link=function(d,e,f,g,h){var i="deckgrid/innerHtmlTemplate"+ ++this.$$templateKeyIndex+".html";angular.isUndefined(f.cardtemplate)?(angular.isUndefined(f.cardtemplatestring)?h(d,function(b){var g,d=[],e=0,f=b.length;for(e;e=0;c-=1)if(d=a.cssRules[c].selectorText,angular.isDefined(d)&&d.match(b))return!0;return!1}var c=[],d=[];return c=Array.prototype.concat.call(Array.prototype.slice.call(document.querySelectorAll("style[type='text/css']")),Array.prototype.slice.call(document.querySelectorAll("link[rel='stylesheet']"))),angular.forEach(c,function(c){var g=e(c);angular.forEach(g,function(c){f(c)&&d.push(b.matchMedia(c.media.mediaText))})}),d},e.prototype.$$createColumns=function(){var b=this;return this.$$scope.layout?(b.$$scope.columns=[],void angular.forEach(d("orderBy")(d("filter")(b.$$scope.model,b.$$scope.filter),b.$$scope.orderBy),function(c,d){var e=d%b.$$scope.layout.columns|0;b.$$scope.columns[e]||(b.$$scope.columns[e]=[]),c.$index=d,b.$$scope.columns[e].push(c)})):c.error("angular-deckgrid: No CSS configuration found (see https://github.com/akoenig/angular-deckgrid#the-grid-configuration)")},e.prototype.$$getLayout=function(){var d,c=b.getComputedStyle(this.$$elem,":before").content;return c&&(c=c.replace(/'/g,""),c=c.replace(/"/g,""),c=c.split(" "),2===c.length&&(d={},d.columns=0|c[0],d.classList=c[1].replace(/\./g," ").trim())),d},e.prototype.$$onMediaQueryChange=function(){var b=this,c=this.$$getLayout();c&&c.columns!==this.$$scope.layout.columns&&(b.$$scope.layout=c,b.$$scope.$apply(function(){b.$$createColumns()}))},e.prototype.$$onModelChange=function(b,c){var d=this;b=b||[],c=c||[],angular.equals(c,b)||d.$$createColumns()},e.prototype.destroy=function(){var b=this.$$watchers.length-1;for(b;b>=0;b-=1)this.$$watchers[b]()},{create:function(b,c){return new e(b,c)}}}]); diff --git a/bower.json b/bower.json index 0f8720d..b9065d8 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-deckgrid", - "version": "0.5.0", - "author": "André König (andre.koenig@posteo.de)", + "version": "0.6.0", + "author": "André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com)", "description": "A lightweight masonry-like grid for AngularJS.", "license": "MIT", "repository": { diff --git a/package.json b/package.json index be547dc..65c7bbe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-deckgrid", - "version": "0.5.0", - "author": "André König (andre.koenig@posteo.de)", + "version": "0.6.0", + "author": "André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com)", "description": "A lightweight masonry-like grid for AngularJS.", "license": "MIT", "repository": { diff --git a/src/deckgrid.js b/src/deckgrid.js index 20b55c3..56430d3 100644 --- a/src/deckgrid.js +++ b/src/deckgrid.js @@ -1,13 +1,13 @@ /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -15,8 +15,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ '$window', '$log', + '$filter', - function initialize ($window, $log) { + function initialize($window, $log, $filter) { 'use strict'; @@ -24,9 +25,11 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * The deckgrid directive. * */ - function Deckgrid (scope, element) { + function Deckgrid(scope, element) { var self = this, watcher, + filterWatcher, + orderByWatcher, mql; this.$$elem = element; @@ -51,13 +54,18 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ this.$$watchers.push(watcher); + filterWatcher = this.$$scope.$watchCollection('filter', this.$$onModelChange.bind(this)); + orderByWatcher = this.$$scope.$watchCollection('orderBy', this.$$onModelChange.bind(this)); + this.$$watchers.push(filterWatcher); + this.$$watchers.push(orderByWatcher); + // // Register media query change events. // - angular.forEach(self.$$getMediaQueries(), function onIteration (rule) { + angular.forEach(self.$$getMediaQueries(), function onIteration(rule) { var handler = self.$$onMediaQueryChange.bind(self); - function onDestroy () { + function onDestroy() { rule.removeListener(handler); } @@ -65,7 +73,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ self.$$watchers.push(onDestroy); }); - + mql = $window.matchMedia('(orientation: portrait)'); mql.addListener(self.$$onMediaQueryChange.bind(self)); @@ -82,7 +90,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * @return {array} An array with all respective styles. * */ - Deckgrid.prototype.$$getMediaQueries = function $$getMediaQueries () { + Deckgrid.prototype.$$getMediaQueries = function $$getMediaQueries() { var stylesheets = [], mediaQueries = []; @@ -91,7 +99,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ Array.prototype.slice.call(document.querySelectorAll('link[rel=\'stylesheet\']')) ); - function extractRules (stylesheet) { + function extractRules(stylesheet) { try { return (stylesheet.sheet.cssRules || []); } catch (e) { @@ -99,9 +107,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ } } - function hasDeckgridStyles (rule) { - var regexe = /\[(\w*-)?deckgrid\]::?before/g, - i = 0, + function hasDeckgridStyles(rule) { + var regexe = /\[(\w*-)?deckgrid\]::?before/g, + i = 0, selector = ''; if (!rule.media || angular.isUndefined(rule.cssRules)) { @@ -121,10 +129,10 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ return false; } - angular.forEach(stylesheets, function onIteration (stylesheet) { + angular.forEach(stylesheets, function onIteration(stylesheet) { var rules = extractRules(stylesheet); - angular.forEach(rules, function inRuleIteration (rule) { + angular.forEach(rules, function inRuleIteration(rule) { if (hasDeckgridStyles(rule)) { mediaQueries.push($window.matchMedia(rule.media.mediaText)); } @@ -147,7 +155,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * NOTE that calling this method will trigger a complete template "redraw". * */ - Deckgrid.prototype.$$createColumns = function $$createColumns () { + Deckgrid.prototype.$$createColumns = function $$createColumns() { var self = this; if (!this.$$scope.layout) { @@ -155,9 +163,9 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ 'https://github.com/akoenig/angular-deckgrid#the-grid-configuration)'); } - this.$$scope.columns = []; + self.$$scope.columns = []; - angular.forEach(this.$$scope.model, function onIteration (card, index) { + angular.forEach($filter('orderBy')($filter('filter')(self.$$scope.model, self.$$scope.filter), self.$$scope.orderBy), function onIteration(card, index) { var column = (index % self.$$scope.layout.columns) | 0; if (!self.$$scope.columns[column]) { @@ -186,7 +194,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * You are responsible for defining the respective styles within your CSS. * */ - Deckgrid.prototype.$$getLayout = function $$getLayout () { + Deckgrid.prototype.$$getLayout = function $$getLayout() { var content = $window.getComputedStyle(this.$$elem, ':before').content, layout; @@ -211,7 +219,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * Event that will be triggered if a CSS media query changed. * */ - Deckgrid.prototype.$$onMediaQueryChange = function $$onMediaQueryChange () { + Deckgrid.prototype.$$onMediaQueryChange = function $$onMediaQueryChange() { var self = this, layout = this.$$getLayout(); @@ -219,10 +227,10 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ // Okay, the layout has changed. // Creating a new column structure is not avoidable. // - if (layout.columns !== this.$$scope.layout.columns) { + if (layout && layout.columns !== this.$$scope.layout.columns) { self.$$scope.layout = layout; - self.$$scope.$apply(function onApply () { + self.$$scope.$apply(function onApply() { self.$$createColumns(); }); } @@ -234,7 +242,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * Event that will be triggered when the source model has changed. * */ - Deckgrid.prototype.$$onModelChange = function $$onModelChange (newModel, oldModel) { + Deckgrid.prototype.$$onModelChange = function $$onModelChange(newModel, oldModel) { var self = this; newModel = newModel || []; @@ -250,7 +258,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ * watchers and event handlers. * */ - Deckgrid.prototype.destroy = function destroy () { + Deckgrid.prototype.destroy = function destroy() { var i = this.$$watchers.length - 1; for (i; i >= 0; i = i - 1) { @@ -259,7 +267,7 @@ angular.module('akoenig.deckgrid').factory('Deckgrid', [ }; return { - create : function create (scope, element) { + create: function create(scope, element) { return new Deckgrid(scope, element); } }; diff --git a/src/descriptor.js b/src/descriptor.js index 175b6f7..c23cbe6 100644 --- a/src/descriptor.js +++ b/src/descriptor.js @@ -1,13 +1,13 @@ /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -16,7 +16,7 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ 'Deckgrid', '$templateCache', - function initialize (Deckgrid, $templateCache) { + function initialize(Deckgrid, $templateCache) { 'use strict'; @@ -25,7 +25,7 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ * directive description object. * */ - function Descriptor () { + function Descriptor() { this.restrict = 'AE'; this.template = '
' + @@ -33,7 +33,9 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ '
'; this.scope = { - 'model': '=source' + 'model': '=source', + 'filter': '=', + 'orderBy': '=' }; // @@ -48,35 +50,21 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ // Will be incremented if using inline templates. // this.$$templateKeyIndex = 0; - } - /** - * @private - * - * Cleanup method. Will be called when the - * deckgrid directive should be destroyed. - * - */ - Descriptor.prototype.$$destroy = function $$destroy () { - this.$$deckgrid.destroy(); - }; - /** * @private * * The deckgrid link method. Will instantiate the deckgrid. * */ - Descriptor.prototype.$$link = function $$link (scope, elem, attrs, nullController, transclude) { + Descriptor.prototype.$$link = function $$link(scope, elem, attrs, nullController, transclude) { var templateKey = 'deckgrid/innerHtmlTemplate' + (++this.$$templateKeyIndex) + '.html'; - scope.$on('$destroy', this.$$destroy.bind(this)); - if (angular.isUndefined(attrs.cardtemplate)) { if (angular.isUndefined(attrs.cardtemplatestring)) { // use the provided inner html as template - transclude(scope, function onTransclude (innerHTML) { + transclude(scope, function onTransclude(innerHTML) { var extractedInnerHTML = [], i = 0, len = innerHTML.length, @@ -109,10 +97,12 @@ angular.module('akoenig.deckgrid').factory('DeckgridDescriptor', [ scope.mother = scope.$parent; this.$$deckgrid = Deckgrid.create(scope, elem[0]); + + scope.$on('$destroy', this.$$deckgrid.destroy.bind(this.$$deckgrid)); }; return { - create : function create () { + create: function create() { return new Descriptor(); } }; diff --git a/src/index.js b/src/index.js index 9dc6f52..923ec50 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,13 @@ /* * angular-deckgrid * - * Copyright(c) 2013-2014 André König + * Copyright(c) 2013-2016 André König / Mark Hamilton * MIT Licensed * */ /** - * @author André König (andre.koenig@posteo.de) + * @author André König (andre.koenig@posteo.de) / Mark Hamilton (mark@dryverless.com) * */ @@ -23,4 +23,4 @@ angular.module('akoenig.deckgrid').directive('deckgrid', [ return DeckgridDescriptor.create(); } -]); \ No newline at end of file +]);