ui.bootstrap.pagination for list, cleanup
[angular-drzb] / app / js / directives.js
index 8ed47bb..20b1127 100644 (file)
@@ -1,5 +1,6 @@
 'use strict';
-/* http://docs-next.angularjs.org/api/angular.module.ng.$compileProvider.directive */
+
+/* Directives */
 
 
 angular.module('myApp.directives', []).
@@ -7,4 +8,187 @@ angular.module('myApp.directives', []).
     return function(scope, elm, attrs) {
       elm.text(version);
     };
-  }]);
+  }]).
+  directive('myInput', function() {
+    return {
+               restrict: 'C',
+               compile: function(element, attrs) {
+                       var my_class = attrs['class'] || '';
+                       my_class = my_class.replace(/ *my-input */,'');
+                       var my_type  = attrs['type']  || 'text';
+                       var html = '<div class="'+my_class+'">'
+                               +'<label for="'+attrs.ngModel+'">' + attrs.placeholder + '</label>'
+                               +'<input type="'+my_type+'" name="'+attrs.ngModel+'" ng-model="' + attrs.ngModel + '"'
+                               +' placeholder="'+attrs.placeholder+'" class="'+my_class+'"'
+                       ;
+                       if ( attrs.ngRequired ) html += ' ng-required="' + attrs.ngRequired + '"';
+                       if ( attrs.bsTypeahead )  html += ' bs-typeahead="'+attrs.bsTypeahead+'"';
+                       if ( attrs.dataItems )  html += ' data-items="'+attrs.dataItems+'"'; // for typeahead
+                       html += '/></div>';
+                       element.replaceWith(html);
+               }
+    };
+  }).
+
+directive('myLabelInput', function() {
+    return {
+               restrict: 'C',
+               compile: function(element, attrs) {
+                       var my_class = attrs['class'] || '';
+                       my_class = my_class.replace(/ *my-input */,'');
+                       var my_type  = attrs['type']  || 'text';
+                       var m = attrs.ngModel;
+                       var html =
+'  <div class="control-group">'+
+'    <label class="control-label" for="'+m+'">'+attrs.label+'</label>'+
+'    <div class="controls">'+
+'      <input type="'+my_type+'" id="'+m+'" ng-model="'+m+'"';
+                       ;
+                       if ( attrs.placeholder ) html += ' placeholder="' + attrs.placeholder + '"';
+                       if ( attrs.ngRequired )  html += ' ng-required="' + attrs.ngRequired + '"';
+                       if ( attrs.ngChange )    html += ' ng-change="' + attrs.ngChange + '"';
+                       html += '>'+
+'    </div>'+
+'  </div>';
+
+                       element.replaceWith(html);
+               }
+    };
+})
+
+.directive('myLabelSelect', function() {
+    return {
+               restrict: 'C',
+               compile: function(element, attrs) {
+                       var my_class = attrs['class'] || '';
+                       my_class = my_class.replace(/ *my-input */,'');
+                       var m = attrs.ngModel;
+                       var html =
+'  <div class="control-group">'+
+'    <label class="control-label" for="'+m+'">'+attrs.label+'</label>'+
+'    <div class="controls">'+
+'      <select id="'+m+'" ng-model="'+m+'"';
+                       ;
+                       if ( attrs.ngOptions  ) html += ' ng-options="' + attrs.ngOptions + '"';
+                       if ( attrs.ngChange )    html += ' ng-change="' + attrs.ngChange + '"';
+                       html += '></select>'+
+'    </div>'+
+'  </div>';
+
+                       element.replaceWith(html);
+               }
+    };
+})
+
+.directive('bsTypeahead', ['$parse', function($parse) {
+       'use strict';
+
+       return {
+               restrict: 'A',
+               require: '?ngModel',
+               link: function postLink(scope, element, attr, controller) {
+
+                       var getter = $parse(attr.bsTypeahead),
+                                       setter = getter.assign,
+                                       value = getter(scope);
+
+                       // Watch bsTypeahead for changes
+                       scope.$watch(attr.bsTypeahead, function(newValue, oldValue) {
+                               if(newValue !== oldValue) {
+                                       value = newValue;
+                               }
+                       });
+
+                       element.attr('data-provide', 'typeahead');
+                       element.typeahead({
+                               source: function(query) { return value; },
+                               items: attr.items,
+                               updater: function(value) {
+                                       // If we have a controller (i.e. ngModelController) then wire it up
+                                       if(controller) {
+                                               scope.$apply(function () {
+                                                       controller.$setViewValue(value);
+                                               });
+                                       }
+                                       return value;
+                               }
+                       });
+
+                       // add entered element into typeahead array for other fields
+                       element.bind('blur', function() {
+                               var new_value = element.val();
+                               if ( new_value.length > 1 && $.inArray( new_value, value ) === -1 ) { // IE doesn't have .indexOf
+                                       scope.$apply( function() {
+                                               value.unshift( element.val() );
+                                       });
+                               }
+                       });
+
+               }
+       };
+}])
+.directive('myPagination', function() { // modified ui.bootstrap.pagination
+  return {
+    restrict: 'E',
+    scope: {
+      numPages: '=',
+      currentPage: '=',
+      maxSize: '=',
+      onSelectPage: '&'
+    },
+    templateUrl: 'template/pagination/pagination.html',
+    replace: true,
+    link: function(scope) {
+      scope.$watch('numPages + currentPage + maxSize', function() {
+        scope.pages = [];
+
+        //set the default maxSize to numPages
+        var maxSize = ( scope.maxSize && scope.maxSize < scope.numPages ) ? scope.maxSize : scope.numPages;
+        var startPage = scope.currentPage - Math.floor(maxSize/2);
+        
+        //adjust the startPage within boundary
+        if(startPage < 1) {
+            startPage = 1;
+        }
+        if ((startPage + maxSize - 1) > scope.numPages) {
+            startPage = startPage - ((startPage + maxSize - 1) - scope.numPages );
+        }
+
+        for(var i=0; i < maxSize && i < scope.numPages ;i++) {
+          scope.pages.push(startPage + i);
+        }
+        if ( scope.currentPage > scope.numPages ) {
+          scope.selectPage(scope.numPages);
+        }
+      });
+      scope.noPrevious = function() {
+        return scope.currentPage === 1;
+      };
+      scope.noNext = function() {
+        return scope.currentPage === scope.numPages;
+      };
+      scope.isActive = function(page) {
+        return scope.currentPage === page;
+      };
+
+      scope.selectPage = function(page) {
+        if ( ! scope.isActive(page) ) {
+          scope.currentPage = page;
+          scope.onSelectPage({ page: page });
+        }
+      };
+
+      scope.selectPrevious = function() {
+        if ( !scope.noPrevious() ) {
+          scope.selectPage(scope.currentPage-1);
+        }
+      };
+      scope.selectNext = function() {
+        if ( !scope.noNext() ) {
+          scope.selectPage(scope.currentPage+1);
+        }
+      };
+    }
+  };
+})
+;