angular.module('angular-dayparts', []) .directive('angularDayparts', ['$window', '$document', '$timeout', function($window, $document, $timeout) { return { restrict: 'E', scope: { options: '=?' }, templateUrl: 'template.html', controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { $scope.options = $scope.options || {}; $scope.options.reset = ($scope.options.reset === undefined) ? true : $scope.options.reset; $scope.year = new Date().getFullYear(); $scope.days = [{ name: '星期一', position: 1 }, { name: '星期二', position: 2 }, { name: '星期三', position: 3 }, { name: '星期四', position: 4 }, { name: '星期五', position: 5 }, { name: '星期六', position: 6 }, { name: '星期日', position: 7 }]; //$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}]; $scope.weekdays = [1, 2, 3, 4, 5, 6, 7]; $scope.haveactive = [0, 0, 0, 0, 0, 0, 0]; function checkavtice(i, j) { if (j == 0) { $scope.haveactive[i] = 0; } else { $scope.haveactive[i] = 1; } } var klass = 'active'; var startCell = null; var isDragging = false; var selected = []; var isStartSelected = false; if ($scope.options.selected) { $timeout(function() { repopulate($scope.options.selected); }, 100); } /** * When user stop clicking make the callback with selected elements */ function mouseUp() { if (!isDragging) { return; } isDragging = false; onChangeCallback(); } /** * Call 'onChange' function from passed options */ function onChangeCallback() { if ($scope.options && $scope.options.onChange) { // Sort by day name and time var sortedSelected = []; selected.forEach(function(item) { var el = item.split('-'); var o = { year: el[0], time: parseInt(el[1]) }; sortedSelected.push(o); }); sortedSelected = _.sortBy(sortedSelected, function(item) { return item.time; }); selected = sortedSelected.map(function(item) { return item.year + '-' + item.time; }) $scope.options.onChange(selected); } } /** * User start to click * @param {jQuery DOM element} */ function mouseDown(el) { isDragging = true; setStartCell(el); setEndCell(el); } /** * User enter in a cell still triggering click * @param {jQuery DOM element} */ function mouseEnter(el) { if (!isDragging) { return; } setEndCell(el); } /** * Get the first cell clicked * @param {jQuery DOM element} */ function setStartCell(el) { startCell = el; isStartSelected = _.contains(selected, el.data('time')); } /** * Get the last cell * @param {jQuery DOM element} */ function setEndCell(el) { cellsBetween(startCell, el).each(function() { var el = angular.element(this); if (!isStartSelected) { if (!_.contains(selected, el.data('time'))) { _addCell($(el)); } } else { _removeCell(el); } }); } /** * Get all the cells between first and last * @param {jQuery DOM element} start cell * @param {jQuery DOM element} end cell * @return {jQuery DOM elements} cells between start and end */ function cellsBetween(start, end) { var coordsStart = getCoords(start); var coordsEnd = getCoords(end); var topLeft = { column: $window.Math.min(coordsStart.column, coordsEnd.column), row: $window.Math.min(coordsStart.row, coordsEnd.row), }; var bottomRight = { column: $window.Math.max(coordsStart.column, coordsEnd.column), row: $window.Math.max(coordsStart.row, coordsEnd.row), }; return $element.find('div.weekday').filter(function() { var el = angular.element(this); var coords = getCoords(el); return coords.column >= topLeft.column && coords.column <= bottomRight.column && coords.row >= topLeft.row && coords.row <= bottomRight.row; }); } /** * Get the coordinates of a given cell * @param {jQuery DOM element} * @return {object} */ function getCoords(cell) { //var row = cell.parents('layout-row'); // return { // column: cell[0].cellIndex, // row: cell.parent()[0].rowIndex // }; return { column: cell.data("cellindex") + 0, row: 0 }; } /** * Passing 'selected' property will make repopulate table */ function repopulate() { selected = _.clone($scope.options.selected); $element.find('div.weekday').each(function(i, el) { if (_.contains(selected, $(el).data('time'))) { // $(el).addClass(klass); checkavtice(i, 1) } }); } /** * Clicking on a day will select all hours * @param {object} day.name, day.position */ $scope.selectDay = function(day) { var numSelectedHours = selected.filter(function(item) { return item.split('-')[0] === day.name; }).length; $element.find('table tr:eq(' + day.position + ') td:not(:last-child)').each(function(i, el) { if (numSelectedHours === 24) { _removeCell($(el)); } else if (!_.contains(selected, $(el).data('time'))) { _addCell($(el)); } }); onChangeCallback(); }; /** * Clicking on a hour will select all days at that hour * @param {int} */ $scope.selectHour = function(hour) { var hour = hour - 1; // previous selected hour var numSelectedDays = $scope.days.filter(function(item) { return _.contains(selected, item.name + '-' + hour); }).length; $scope.days.forEach(function(day, i) { $element.find('table tr:eq(' + (i + 1) + ') td:eq(' + hour + ')').each(function(i, el) { if (numSelectedDays === 7) { _removeCell($(el)); } else if (!_.contains(selected, $(el).data('time'))) { _addCell($(el)); } }); }); onChangeCallback(); }; /** * Remove all selected hours */ $scope.reset = function() { selected = []; $element.find('td').each(function(i, el) { // $(el).removeClass(klass); checkavtice(i, 0) }); onChangeCallback(); }; /** * Remove css class from table and element from selected array * @param {jQuery DOM element} cell */ function _removeCell(el) { // el.removeClass(klass); checkavtice(parseInt(el.data('time').charAt(el.data('time').length - 1)) - 1, 0); selected = _.without(selected, el.data('time')); } /** * Add css class to table and element to selected array * @param {jQuery DOM element} cell */ function _addCell(el) { // el.addClass(klass); checkavtice(parseInt(el.data('time').charAt(el.data('time').length - 1)) - 1, 1); selected.push(el.data('time')); } function wrap(fn) { return function() { var el = angular.element(this); $scope.$apply(function() { fn(el); }); } } /** * Mouse events */ $element.delegate('div.weekday', 'mousedown', wrap(mouseDown)); //$element.delegate('div.weekday', 'mouseenter', wrap(mouseEnter)); $document.delegate('body', 'mouseup', wrap(mouseUp)); }] } }]); (function(module) { try { module = angular.module('angular-dayparts'); } catch (e) { module = angular.module('angular-dayparts', []); } module.run(['$templateCache', function($templateCache) { $templateCache.put('template.html', '\n' + '\n' + '\n' + '
\n' + '
\n' + '
\n' + ' {{day.name}}\n' + '
\n' + '
\n' + '\n' + '
\n' + '
\n' + '
{{weekday}}
\n' + '
\n' + '
\n' + '
\n' + '\n' + '\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
\n' + ' \n' + '
'); }]); })();