ng-weekday.js 13 KB

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