angular-listview
Version:
simple, flexible, angular list view -- select, add, edit, remove
1 lines • 3.84 kB
JavaScript
!function(e){"use strict";var t=e.$$minErr("listview");e.module("listview",["ngAnimate"]).factory("listViewParser",["$parse",function(e){var i=/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/,n=/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/;return{parse:function(s){var r=s.match(i);if(!r)throw t("iexp","Expected expression in form of '_item_ in _collection_ (track by _id_)?' but got '{0}'.",s);var o=r[2],l=r[1];if(r=l.match(n),!r)throw t("iidexp","'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.",l);return{collection:e(o),key:e(r[2]),item:e(r[1])}}}}]).controller("ListViewCtrl",["$animate","listViewParser",function(e,i){this.$element=null,this.expression="",this.selectMode="none";var n,s=[],r=!1;this.registerSelectElement=function(e){return s.push(e),function(){var t=s.indexOf(e);t>-1&&s.splice(t,1)}},this.select=function(t){if("none"!=this.selectMode&&~s.indexOf(t)){if(~["single","active"].indexOf(this.selectMode))for(var i=0,n=s.length;n>i;i++)e.removeClass(s[i],"selected");e.addClass(t,"selected"),"active"==this.selectMode&&e.addClass(t,"active")}},this.deselect=function(t){e.removeClass(t,"active"),e.removeClass(t,"selected")},this.toggleEditMode=function(){return r=!r,e[r?"addClass":"removeClass"](this.$element,"list-view-edit"),r},this.add=function(e,s,r){n||(n=i.parse(this.expression)),r||(r=s,s=null);var o=n.collection(r);if(Array.isArray(o))o.push(e);else{if(!s)throw t("nokey","Argument 'key' is required when list is an object");o[s]=e}},this.remove=function(e){n||(n=i.parse(this.expression));var s=n.collection(e),r=n.key(e),o=r?s[r]:n.item(e);if(Array.isArray(s))s.splice(s.indexOf(o),1);else{if(!r)throw t("nokey","The expression used to iterate over an object must specify (_key_, _value_), but got '{0}'",this.expression);delete s[r]}}}]).directive("listView",function(){function e(e){return e.tagName&&(e.hasAttribute("list-item")||e.hasAttribute("data-list-item")||"list-item"===e.tagName.toLowerCase()||"data-list-item"===e.tagName.toLowerCase())}var t={single:"single",multi:"multi",active:"active",none:"none"};return{restrict:"EA",controller:"ListViewCtrl",scope:!0,compile:function(i,n){for(var s,r=i.contents(),o=0,l=r.length;l>o;o++)if(e(r[o])){s=r.eq(o);break}return s.attr("ng-repeat",n.list),function(e,i,n,s){s.selectMode=t[n.selectMode]||"none",s.expression=n.list||"",s.$element=i}}}}).directive("listEditToggle",["$q",function(e){return{restrict:"EA",require:"^listView",link:function(t,i,n,s){var r=n.toggleIf||n.listEditToggle||!0,o=n.toggleOn||"click";i.on(o,function(i){i.stopPropagation();var n=!s.$element.hasClass("list-view-edit");e.when(t.$eval(r,{$event:i,$toEditMode:n})).then(function(e){e!==!1&&(t.$editMode=s.toggleEditMode())})})}}}]).directive("listAdd",["$q",function(e){return{restrict:"EA",require:"^listView",link:function(t,i,n,s){var r=n.add||n.listAdd,o=n.addOn||"click";r&&i.on(o,function(i){i.stopPropagation(),e.when(t.$eval(r,{$event:i})).then(function(e){if(e){var i=e.$key;delete e.$key,s.add(e,i,t)}})})}}}]).directive("listItem",["$q","$timeout",function(e,t){return{restrict:"EA",require:"^listView",link:function(i,n,s,r){var o="none"==r.selectMode?null:s.selectOn||"click",l=s.selectIf||!0,c=null;o&&(i.$on("$destroy",r.registerSelectElement(n)),n.on(o,function(s){var a=!0;if(s.stopPropagation(),"click"==o&&(a=!c,t.cancel(c),c=t(function(){c=null},300)),a){if(n.hasClass("selected"))return r.deselect(n);e.when(i.$eval(l,{$event:s})).then(function(e){e!==!1&&r.select(n)})}}))}}}]).directive("listItemEdit",function(){return{restrict:"EA",require:"^listView",link:function(e,t,i,n){var s=i.edit||i.listItemEdit,r=i.editOn||"click";s&&t.on(r,function(t){t.stopPropagation(),e.$apply(function(){return"remove"==s?n.remove(e):void e.$eval(s,{$event:t})})})}}})}(angular);