123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- 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];
-
- 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);
- }
- });
- }
- /**
- * 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);
- });
- onChangeCallback();
- };
- /**
- * Remove css class from table and element from selected array
- * @param {jQuery DOM element} cell
- */
- function _removeCell (el) {
- el.removeClass(klass);
- 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);
- 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' +
- '<div class="calendar-md">\n' +
- ' <div class=\'layout-row subheader\'>\n' +
- ' <div class=\'subheader-day layout-size layout-padding\' ng-repeat=\'day in days\'>\n' +
- ' {{day.name}}\n' +
- ' </div>\n' +
- ' </div>\n' +
- '\n' +
- ' <div class=\'layout-row entity\'>\n' +
- ' <div class="layout-padding layout-row weekday" ng-repeat=\'weekday in weekdays track by $index\' data-time="{{year}}-{{weekday}}" data-cellIndex="{{weekday-1}}"> \n' +
- ' <div>{{weekday}}</div>\n' +
- ' <div class="layout-height"></div> \n' +
- ' </div>\n' +
- ' </div>\n' +
- '\n' +
- '\n' +
- ' <table border="0" cellspacing="0" cellpadding="0">\n' +
- ' <!--tr class="layout-row subheader">\n' +
- ' <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' +
- ' <span>{{day.name}}</span>ng-class=\'{"disabled" : isDisabled(day), "active": isActive(day), "has-events": hasEvents(day), "md-whiteframe-12dp": hover || focus }\'\n' +
- ' </th>\n' +
- ' </tr-->\n' +
- ' <tr>\n' +
- ' <td class="layout-padding flex" ng-repeat="weekday in weekdays" data-time="{{year}}-{{weekday}}"></td>\n' +
- ' </tr>\n' +
- ' </table>\n' +
- ' <!-- <button type="button" ng-click="reset()" ng-if="options.reset">Reset</button> -->\n' +
- '</div>');
- }]);
- })();
|