ng-weekday_1.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. app.directive('Daypart', ['$window', '$document', '$timeout', function ($window, $document, $timeout) {
  2. return {
  3. restrict: 'E',
  4. scope: {
  5. options: '=?'
  6. },
  7. templateUrl: 'template.html',
  8. controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
  9. console.log($scope)
  10. $scope.options = $scope.options || {};
  11. $scope.options.reset = ($scope.options.reset === undefined) ? true : $scope.options.reset;
  12. $scope.year = new Date().getFullYear();
  13. $scope.days = [{name:'星期一', position: 1}, {name:'星期二', position: 2}, {name:'星期三', position: 3}, {name: '星期四', position: 4}, {name: '星期五', position: 5}, {name: '星期六', position: 6}, {name: '星期日', position: 7}];
  14. //$scope.days = [{name: 'monday', position: 1}, {name: 'tuesday', position: 2}, {name: 'wednesday', position: 3}, {name: 'thursday', position: 4}, {name: 'friday', position: 5}, {name: 'saturday', position: 6}, {name: 'sunday', position: 7}];
  15. $scope.weekdays = [1,2,3,4,5,6,7];
  16. var klass = 'active';
  17. var startCell = null;
  18. var isDragging = false;
  19. var selected = [];
  20. var isStartSelected = false;
  21. if ($scope.options.selected) {
  22. $timeout(function(){
  23. repopulate($scope.options.selected);
  24. }, 100);
  25. }
  26. /**
  27. * When user stop clicking make the callback with selected elements
  28. */
  29. function mouseUp() {
  30. if (!isDragging) {
  31. return;
  32. }
  33. isDragging = false;
  34. onChangeCallback();
  35. }
  36. /**
  37. * Call 'onChange' function from passed options
  38. */
  39. function onChangeCallback () {
  40. if ($scope.options && $scope.options.onChange) {
  41. // Sort by day name and time
  42. var sortedSelected = [];
  43. selected.forEach(function(item){
  44. var el = item.split('-');
  45. var o = {year: el[0], time: parseInt(el[1])};
  46. sortedSelected.push(o);
  47. });
  48. sortedSelected = _.sortBy(sortedSelected, function(item){
  49. return item.time;
  50. });
  51. selected = sortedSelected.map(function(item){
  52. return item.year + '-' + item.time;
  53. })
  54. $scope.options.onChange(selected);
  55. }
  56. }
  57. /**
  58. * User start to click
  59. * @param {jQuery DOM element}
  60. */
  61. function mouseDown(el) {
  62. isDragging = true;
  63. setStartCell(el);
  64. setEndCell(el);
  65. }
  66. /**
  67. * User enter in a cell still triggering click
  68. * @param {jQuery DOM element}
  69. */
  70. function mouseEnter(el) {
  71. if (!isDragging) {
  72. return;
  73. }
  74. setEndCell(el);
  75. }
  76. /**
  77. * Get the first cell clicked
  78. * @param {jQuery DOM element}
  79. */
  80. function setStartCell(el) {
  81. startCell = el;
  82. isStartSelected = _.contains(selected, el.data('time'));
  83. }
  84. /**
  85. * Get the last cell
  86. * @param {jQuery DOM element}
  87. */
  88. function setEndCell(el) {
  89. cellsBetween(startCell, el).each(function() {
  90. var el = angular.element(this);
  91. if (!isStartSelected) {
  92. if (!_.contains(selected, el.data('time'))) {
  93. _addCell($(el));
  94. }
  95. } else {
  96. _removeCell(el);
  97. }
  98. });
  99. }
  100. /**
  101. * Get all the cells between first and last
  102. * @param {jQuery DOM element} start cell
  103. * @param {jQuery DOM element} end cell
  104. * @return {jQuery DOM elements} cells between start and end
  105. */
  106. function cellsBetween(start, end) {
  107. var coordsStart = getCoords(start);
  108. var coordsEnd = getCoords(end);
  109. var topLeft = {
  110. column: $window.Math.min(coordsStart.column, coordsEnd.column),
  111. row: $window.Math.min(coordsStart.row, coordsEnd.row),
  112. };
  113. var bottomRight = {
  114. column: $window.Math.max(coordsStart.column, coordsEnd.column),
  115. row: $window.Math.max(coordsStart.row, coordsEnd.row),
  116. };
  117. return $element.find('div.weekday').filter(function() {
  118. var el = angular.element(this);
  119. var coords = getCoords(el);
  120. return coords.column >= topLeft.column
  121. && coords.column <= bottomRight.column
  122. && coords.row >= topLeft.row
  123. && coords.row <= bottomRight.row;
  124. });
  125. }
  126. /**
  127. * Get the coordinates of a given cell
  128. * @param {jQuery DOM element}
  129. * @return {object}
  130. */
  131. function getCoords(cell) {
  132. //var row = cell.parents('layout-row');
  133. // return {
  134. // column: cell[0].cellIndex,
  135. // row: cell.parent()[0].rowIndex
  136. // };
  137. return {
  138. column: cell.data("cellindex")+0,
  139. row: 0
  140. };
  141. }
  142. /**
  143. * Passing 'selected' property will make repopulate table
  144. */
  145. function repopulate () {
  146. selected = _.clone($scope.options.selected);
  147. $element.find('div.weekday').each(function(i, el){
  148. if (_.contains(selected, $(el).data('time'))) {
  149. $(el).addClass(klass);
  150. }
  151. });
  152. }
  153. /**
  154. * Clicking on a day will select all hours
  155. * @param {object} day.name, day.position
  156. */
  157. $scope.selectDay = function(day) {
  158. var numSelectedHours = selected.filter(function(item){
  159. return item.split('-')[0] === day.name;
  160. }).length;
  161. $element.find('table tr:eq(' + day.position + ') td:not(:last-child)').each(function(i, el) {
  162. if (numSelectedHours === 24) {
  163. _removeCell($(el));
  164. } else if (!_.contains(selected, $(el).data('time'))) {
  165. _addCell($(el));
  166. }
  167. });
  168. onChangeCallback();
  169. };
  170. /**
  171. * Clicking on a hour will select all days at that hour
  172. * @param {int}
  173. */
  174. $scope.selectHour = function(hour) {
  175. var hour = hour - 1; // previous selected hour
  176. var numSelectedDays = $scope.days.filter(function(item){
  177. return _.contains(selected, item.name + '-' + hour);
  178. }).length;
  179. $scope.days.forEach(function(day, i){
  180. $element.find('table tr:eq(' + (i + 1) + ') td:eq(' + hour + ')').each(function(i, el) {
  181. if (numSelectedDays === 7) {
  182. _removeCell($(el));
  183. } else if (!_.contains(selected, $(el).data('time'))) {
  184. _addCell($(el));
  185. }
  186. });
  187. });
  188. onChangeCallback();
  189. };
  190. /**
  191. * Remove all selected hours
  192. */
  193. $scope.reset = function () {
  194. selected = [];
  195. $element.find('td').each(function(i, el){
  196. $(el).removeClass(klass);
  197. });
  198. onChangeCallback();
  199. };
  200. /**
  201. * Remove css class from table and element from selected array
  202. * @param {jQuery DOM element} cell
  203. */
  204. function _removeCell (el) {
  205. el.removeClass(klass);
  206. selected = _.without(selected, el.data('time'));
  207. }
  208. /**
  209. * Add css class to table and element to selected array
  210. * @param {jQuery DOM element} cell
  211. */
  212. function _addCell (el) {
  213. el.addClass(klass);
  214. selected.push(el.data('time'));
  215. }
  216. function wrap(fn) {
  217. return function() {
  218. var el = angular.element(this);
  219. $scope.$apply(function() {
  220. fn(el);
  221. });
  222. }
  223. }
  224. /**
  225. * Mouse events
  226. */
  227. $element.delegate('div.weekday', 'mousedown', wrap(mouseDown));
  228. //$element.delegate('div.weekday', 'mouseenter', wrap(mouseEnter));
  229. $document.delegate('body', 'mouseup', wrap(mouseUp));
  230. }]
  231. }
  232. }]);
  233. app.run(['$templateCache', function($templateCache) {
  234. $templateCache.put('template.html',
  235. '\n' +
  236. '\n' +
  237. '\n' +
  238. '<div class="calendar-md">\n' +
  239. ' <div class=\'layout-row subheader\'>\n' +
  240. ' <div class=\'subheader-day layout-size layout-padding\' ng-repeat=\'day in days\'>\n' +
  241. ' {{day.name}}\n' +
  242. ' </div>\n' +
  243. ' </div>\n' +
  244. '\n' +'11111'+
  245. ' <div class=\'layout-row entity\'>\n' +
  246. ' <div class="layout-padding layout-row weekday" ng-repeat=\'weekday in weekdays track by $index\' data-time="{{year}}-{{weekday}}" data-cellIndex="{{weekday-1}}"> \n' +
  247. ' <div>{{weekday}}</div>\n' +
  248. ' <div class="layout-height"></div> \n' +
  249. ' </div>\n' +
  250. ' </div>\n' +
  251. '\n' +
  252. '\n' +
  253. ' <table border="0" cellspacing="0" cellpadding="0">\n' +
  254. ' <!--tr class="layout-row subheader">\n' +
  255. ' <th ng-repeat="day in days" class=\'subheader-day layout-padding flex\' ng-focus=\'focus = true;\' ng-blur=\'focus = false;\' ng-mouseleave="hover = false" ng-mouseenter="hover = true">\n' +
  256. ' <span>{{day.name}}</span>ng-class=\'{"disabled" : isDisabled(day), "active": isActive(day), "has-events": hasEvents(day), "md-whiteframe-12dp": hover || focus }\'\n' +
  257. ' </th>\n' +
  258. ' </tr-->\n' +
  259. ' <tr>\n' +
  260. ' <td class="layout-padding flex" ng-repeat="weekday in weekdays" data-time="{{year}}-{{weekday}}"></td>\n' +
  261. ' </tr>\n' +
  262. ' </table>\n' +
  263. ' <!-- <button type="button" ng-click="reset()" ng-if="options.reset">Reset</button> -->\n' +
  264. '</div>');
  265. }]);