;(function() { $.fn.spacecalendar = function(options) { var pluginName = 'spacecalendar'; // Find the plugin attached to the element var instance = this.data(pluginName); // If the instance wasn't found, create it... if(!instance) { // Return the element being bound to return this.each(function() { return $(this).data(pluginName, new spacecalendar(this, options)); }); } // ...otherwise if the user passes true to the plugin (on the second call), // then return the instance of the plugin itself return (options === true) ? instance : this; }; // Default options $.fn.spacecalendar.defaults = { // The house id houseId: 0, // 开始时间 startDate: null, // 房源配置数组 spaceData: [], // 是否可以编辑 isEditable: true, // The date that will be treated as 'today'. todayDate: function(){ var today = new Date(); return today._clear(); }, // The date that will appear selected when the spacecalendar renders. // By default it will be set to todayDate. selectedDate: null, // Names of the month that will be shown in the title. // Will default to 1月, 2月,...,12月 monthNames: null, // Names of the days of the Week that will be shown below the title. // Will default to 周一, 周二,...,周日 dowNames: null, // The day of the week to start the spacecalendar on. 0 is Sunday, 1 is Monday and so on. dowOffset: 1, // First date of the month. firstDate: null }; // Our plugin object var spacecalendar = (function() { // Main entry point. Initialize the plugin function spacecalendar(element, userOptions) { // Grab handle to this var self = this; // Save bound element to el self.el = $(element); var el = self.el; // Merge user options into default options self.options = $.extend(true, {}, $.fn.spacecalendar.defaults, userOptions); var options = self.options; // Find the spacecalendar element if the user provided one self.spacecalendar = $($.find('[gldp-el=' + el.attr('gldp-id') + ' ]')); if(!(el.attr('gldp-id') || '').length) { el.attr('gldp-id', 'gldp-' + Math.round(Math.random() * 1e10)) } el.addClass('gldp-el'); // Render spacecalendar self.render(); // self.show(); }; // Public methods spacecalendar.prototype = { // Render the spacecalendar render: function(renderCalback) { var self = this; var el = self.el; var options = self.options; var spacecalendar = self.spacecalendar; // Build a core class (with border) that every element would have var coreClass = ' core border '; var cssName = 'gldp-default'; // Get today var todayVal = options.todayDate()._val(); var todayTime = todayVal.time/1000; // Constants var maxRow = 6; var maxCol = 7; var dowNames = options.dowNames || [ '周日', '周一', '周二', '周三', '周四', '周五', '周六' ]; var monthNames = options.monthNames || [ ' 1 月', ' 2 月', ' 3 月', ' 4 月', ' 5 月', ' 6 月', ' 7 月', ' 8 月', ' 9 月', ' 10 月', ' 11 月', ' 12 月' ]; // Create container width based on el size var containerWidth = el.outerWidth(); // Create cell width based on container size var cellWidth = containerWidth / maxCol; // If spacecalendar doesn't exist, create it and re-assign it to self if(!spacecalendar.length) { self.spacecalendar = spacecalendar = $('
') .attr('gldp-el', el.attr('gldp-id')) .css( { width: containerWidth + 'px' }); $(el).append(spacecalendar); } // Add core classes and remove spacecalendar's children spacecalendar.removeClass() .addClass(cssName) .children().remove(); // Helper function to setDate (function() { var _firstDate = new Date(options.startDate); if(_firstDate.getDate() != 1){ _firstDate.setDate(1); _firstDate.setMonth(_firstDate.getMonth() + 1); } options.firstDate = _firstDate; })(); var getStartEndDate = function(_offset) { // Create start date as the first date of the month var _firstDate = new Date(options.firstDate); // Default to no offset _offset = _offset || 0; // Adjust date for month offset _firstDate.setMonth(_firstDate.getMonth() + _offset); var startOffset = _firstDate.getDay() - options.dowOffset; startOffset = startOffset < 1 ? -7 - startOffset : -startOffset; var _startDate = _firstDate._add(startOffset)/1000, _endDate = _firstDate._add(7*6-1)/1000; return {startDate: _startDate, endDate: _endDate}; }; // Get the previous, next start/end dates var prevDateObj = getStartEndDate(-1), nextDateObj = getStartEndDate(1); var prevStartDate = prevDateObj.startDate, prevEndDate = prevDateObj.endDate; var nextStartDate = nextDateObj.startDate, nextEndDate = nextDateObj.endDate; // Get the first date for the current month being rendered var firstDateVal = options.firstDate._val(); var firstDateMonth = firstDateVal.month; var firstDateYear = firstDateVal.year; var prevCell = $('') .addClass("title") .append( $('') .addClass('prev-arrow') .attr("src", "/public/img/prev.png") ) .mousedown(function() { return false; }) .click(function(e) { window.location.href = "/spaces/index?house_id=" + options.houseId + "&startDate=" + prevStartDate + "&endDate=" + prevEndDate; }); var titleCell = $('').addClass('title'); var nextCell = $('') .addClass("title") .append( $('') .addClass('next-arrow') .attr("src", "/public/img/next.png") ) .mousedown(function() { return false; }) .click(function(e) { window.location.href = "/spaces/index?house_id=" + options.houseId + "&startDate=" + nextStartDate + "&endDate=" + nextEndDate; }); // Add cells for prev/title/next spacecalendar .append(prevCell) .append(titleCell) .append(nextCell) .append($('')); // Add all the cells to the spacecalendar for(var row = 0, cellIndex = 0; row < maxRow + 1; row++) { for(var col = 0; col < maxCol; col++, cellIndex++) { var cellDate = new Date(options.startDate); var cellClass = 'day'; var cell = $(''); var cellCSS = {width: cellWidth + 'px'}; if(!row) { cellClass = 'core dow'; cell.html(dowNames[col]); cellDate = null; // Assign other properties to the cell cell.addClass(cellClass) .css(cellCSS); if(col == maxCol-2){ cell.addClass("sat"); }else if(col == maxCol-1){ cell.addClass("sun"); } } else { // Get the new date for this cell cellDate._add(col + ((row - 1) * maxCol)); // Get value for this date var cellDateVal = cellDate._val(); var cellDateTime = cellDateVal.time/1000; // Assign date for the cell var daySpan = $(""); daySpan.addClass("day").html(cellDateVal.date + "日"); cell.append(daySpan); // 房源配置信息 var spaceDiv = $(""); if(options.spaceData.length == 0){ if(todayTime <= cellDateTime){ spaceDiv.addClass("opening countDiv").html("等待开放预约"); }else{ spaceDiv.addClass("unopened countDiv").html("未开放预约"); } }else{ var isFind = false; for(var i = 0, len = options.spaceData.length; i < len; i++){ var spaceData = options.spaceData[i]; if(spaceData.useDate == cellDateTime){ var slashSpan = $('').html(" / "); var useSpan = $(''); useSpan.addClass("useCount").html(spaceData.useCount); var totalSpan = $(''); totalSpan.addClass("totalCount").html(spaceData.totalCount); spaceDiv .addClass("opened countDiv") .append(useSpan) .append(slashSpan) .append(totalSpan); cell.data('spaceData', spaceData); isFind = true; break; } } if(!isFind){ if(todayTime <= cellDateTime){ spaceDiv.addClass("opening countDiv").html("等待开放预约"); }else{ spaceDiv.addClass("unopened countDiv").html("未开放预约"); } } } cell.append(spaceDiv); // Handle active dates and weekends cellClass = ([ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ])[cellDateVal.day]; // Handle today or selected dates if(cellDateVal.month != firstDateMonth) { cellClass += ' outMonth'; } if(cellDateTime < todayTime) { cellClass += ' prevDay'; } if(cellDateTime == todayTime) { cellClass = 'today';} // Update the css for the cell if(col == 0){ $.extend(cellCSS, { borderLeftWidth: 0 }); }else if(col == 6){ $.extend(cellCSS, { borderRightWidth: 0 }); } // Assign other properties to the cell cell .data('useDate', cellDateTime) .addClass(coreClass + cellClass) .css(cellCSS); // 加入popover if(options.isEditable){ if(cellDateTime >= todayTime) { cell.spacepopover("init", {id: cellDateTime, idName: "spacePopover"}); } } } // Add cell to spacecalendar spacecalendar.append(cell); } } // Render the month / year title // Build month label var monthText = $('') .html(monthNames[firstDateMonth]); // Build year label var yearText = $('') .html(firstDateYear + " 年 "); var titleYearMonth = $('') .append(yearText) .append(monthText); // Add to title titleCell.children().remove(); titleCell.append(titleYearMonth); // Run the callback signaling end of the render renderCalback = renderCalback || (function() {}); renderCalback(); } }; // Return the plugin return spacecalendar; })(); // One time initialization of useful prototypes (function() { Date.prototype._clear = function() { this.setHours(8); this.setMinutes(0); this.setSeconds(0); this.setMilliseconds(0); return this; }; Date.prototype._add = function(days) { return this.setDate(this.getDate() + days); }; Date.prototype._val = function() { return { year: this.getFullYear(), month: this.getMonth(), date: this.getDate(), time: this.getTime(), day: this.getDay() }; }; })(); })();