PageSourceSearch

https://oookagawa.org/js/calender.js

js oookagawa.org collected 2026-10-08 11:25:01 UTC 9,470 bytes, 385 lines download raw bytes

1/**
2 * jQuery.calendar
3 *
4 * @version  1.0.4
5 * @author   rew <[email protected]>
6 * @link     http://rewish.org/javascript/jquery_calendar
7 * @license  http://rewish.org/license/mit The MIT License
8 */
9(function($) {
10
11$.fn.calendar = function(option) {
12	return this.each(function() {
13		(new Calendar).init($(this), option).build().show();
14	});
15};
16
17var _weekName = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
18var _today = new Date;
19
20function Calendar() {}
21
22Calendar.prototype = $.extend({
23	init: function(elem, option) {
24		this.setOption(option);
25		this.elem = $('<div/>')
26			.addClass(this.option.cssClass)
27			.css('z-index', 2);
28		this.wrap = $('<div/>')
29			.append(this.elem)
30			.css({
31				position: 'relative',
32				overflow: 'hidden'
33			});
34		elem.append(this.wrap);
35		this.view = {};
36		this.preloadEvents = {};
37		return this
38			.buildNavi()
39			.buildTable()
40			.buildCaption()
41			.buildTodayLink();
42	},
43
44	setOption: function(option) {
45		if (this.option && !option) {
46			return this;
47		}
48		if (this.option) {
49			$.extend(this.option, option);
50			return this;
51		}
52		this.option = $.extend({
53			lang : 'ja',
54			year : _today.getFullYear(),
55			month: _today.getMonth() + 1,
56			week: {
57				en: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
58				ja: ['\u65e5', '\u6708', '\u706b', '\u6c34', '\u6728', '\u91d1', '\u571f']
59			},
60			caption: {
61				en: '%Y-%M',
62				ja: '%Y\u5e74%M\u6708'
63			},
64			navi: {
65				en: ['Prev', 'Next'],
66				ja: ['\u524d\u306e\u6708', '\u6b21\u306e\u6708']
67			},
68			todayLink: {
69				en: 'Today [%Y-%M-%D]',
70				ja: '\u4eca\u65e5 [%Y\u5e74%M\u6708%D\u65e5]'
71			},
72			moveTime : 700,
73			events   : {},
74			hideOther: false,
75			cssClass : 'jqueryCalendar',
76			// Callback functions
77			addDay  : function() {},
78			addEvent: function(td, evt) {
79				var elem = typeof evt.url !== 'undefined'
80					? $('<a/>').attr('href', evt.url) : $('<span/>');
81				if (evt.id) {
82					elem.attr('id', 'event-' + evt.id);
83				}
84				if (evt.title) {
85					elem.attr('title', evt.title);
86				}
87				if (evt.isNotMine) {
88          elem.css('background', "#ccc");
89        }
90				elem.text(td.text());
91				td.text('').append(elem).addClass('event');
92			},
93			beforeMove  : function() {},
94			afterMove   : function() {},
95			preloadEvent: function() {}
96		}, option);
97		return this;
98	},
99
100	buildNavi: function() {
101		if (!this.option.navi) {
102			return this;
103		}
104		var self = this;
105		var list = function(className, number, text) {
106			var date = new Date(self.option.year, (self.option.month + number) - 1, 1);
107			var link = $('<a/>')
108				.text(text)
109				.attr('href', 'javascript:void(0)')
110				.click(function() {
111					self.move(number);
112					return false;
113				});
114			return $('<li/>').addClass(className).append(link);
115		};
116		var text = typeof this.option.navi === 'object'
117			? this.option.navi[this.option.lang] : this.option.navi;
118		this.elem.append(
119			$('<ul/>')
120				.addClass('navi')
121				.append(list('prev', -1, text[0]),
122				        list('next',  1, text[1]))
123		);
124		return this;
125	},
126
127	buildTable: function() {
128		this.tr = $('<tr/>');
129		this.td = $('<td/>');
130		// table
131		this.table = $('<table/>');
132		// thead
133		var week = [];
134		var weekName = this.option.week[this.option.lang] || this.option.week;
135		for (var i = 0, w; w = weekName[i]; i++) {
136			week[week.length] = '<th class="'+ _weekName[i] +'">'+ w +'</th>';
137		}
138		this.thead = $('<thead/>').append(this.tr.clone().html(week.join('')))
139		// tbody
140		this.tbody = $('<tbody/>');
141		this.elem.append(
142			$('<div/>')
143				.addClass('main')
144				.append(
145					this.table
146						.addClass('calendar')
147						.append(this.thead)
148						.append(this.tbody)
149				)
150		);
151		return this;
152	},
153
154	buildCaption: function() {
155		if (this.option.caption && !this.caption) {
156			this.caption = $('<div/>').addClass('caption');
157			this.table.before(this.caption);
158		}
159		return this;
160	},
161
162	buildTodayLink: function() {
163		var date = this.getKey(_today).split('-');
164		var linkText = typeof this.option.todayLink === 'object'
165			? this.option.todayLink[this.option.lang] : this.option.todayLink;
166		var self = this;
167		this.table.after(
168			$('<div/>').addClass('todayLink').append(
169				$('<a/>')
170					.text(
171						linkText
172							.replace(/%Y/i, date[0])
173							.replace(/%M/i, date[1])
174							.replace(/%D/i, date[2])
175					)
176					.attr('href', 'javascript:void(0)')
177					.click(function() {
178						self.option.year  = _today.getFullYear();
179						self.option.month = _today.getMonth() + 1;
180						self.rebuild().show().resetWrap();
181					})
182			)
183		);
184		return this;
185	},
186
187	build: function() {
188		this.prevFill();
189		this.current = new Date(this.option.year, this.option.month - 1, 1);
190		var last = new Date(this.option.year, this.option.month, 0).getDate();
191		for (var day = 1; day <= last; day++) {
192			this.current.setDate(day);
193			this.option.day = day;
194			this.option.addDay(this.addDay(this.current, 'currentMonth'));
195		}
196		this.option.day = null;
197		this.nextFill();
198		this.addEvent();
199		return this;
200	},
201
202	rebuild: function() {
203		this.tbody.empty();
204		this.view = {};
205		return this.build();
206	},
207
208	prevFill: function() {
209		var
210			prev = new Date(this.option.year, this.option.month - 1, 0),
211			last = prev.getDate(),
212			day  = last - prev.getDay();
213		if (last - day >= 6) return this;
214		for (; day <= last; day++) {
215			prev.setDate(day);
216			this.addDay(prev, 'otherMonth', this.option.hideOther);
217		}
218		return this;
219	},
220
221	nextFill: function() {
222		var
223			next = new Date(this.option.year, this.option.month, 1),
224			last = 7 - next.getDay();
225		if (last >= 7) return this;
226		for (var day = 1; day <= last; day++) {
227			next.setDate(day);
228			this.addDay(next, 'otherMonth', this.option.hideOther);
229		}
230		return this;
231	},
232
233	addDay: function(date, className, hide) {
234		var key = className === 'otherMonth'
235		        ? className + this.getKey(date)
236		        : this.getKey(date);
237		this.view[key] = this.td.clone()
238			.addClass(className)
239			.addClass(_weekName[date.getDay()]);
240		// White space for (IE <= 7) "empty-cells" fix
241		this.view[key].text(hide ? ' ' : date.getDate());
242		if (key !== 'otherMonth') {
243			this.view[key].attr('id', ['calendar', this.getKey(date)].join('-'));
244		}
245		return this.view[key];
246	},
247
248	getKey: function(date, returnArray) {
249		if (typeof date === 'string') {
250			date = date.split('-');
251		}
252		var key = [
253			date[0] || date.getFullYear(),
254			('0' + (date[1] || date.getMonth() + 1)).slice(-2),
255			('0' + (date[2] || date.getDate())).slice(-2)
256		];
257		if (returnArray === true) {
258			return key;
259		}
260		return key.join('-')
261	},
262
263	addEvent: function() {
264		var self = this;
265		$.each(self.option.events, function(date, event) {
266			var td = self.view[self.getKey(date)];
267			try {
268				self.option.addEvent(td, event);
269			} catch(e) {}
270		});
271		return this;
272	},
273
274	show: function() {
275		var today = this.getKey(_today), tr, count = 0, self = this;
276		$.each(self.view, function(key) {
277			if (count % 7 === 0 || count === 0) {
278				tr = count % 2 === 0
279				   ? self.tr.clone().addClass('even')
280				   : self.tr.clone().addClass('odd');
281				self.tbody.append(tr);
282			}
283			if (key === today && !key.match('otherMonth')) {
284				this.addClass('today');
285			}
286			tr.append(this);
287			count++;
288		});
289		this.setCaption();
290		try {
291			var date = this.getKey(this.current).split('-');
292			this.preloadEvents = this.option.preloadEvent(date[0], date[1]);
293		} catch(e) {}
294		return this;
295	},
296
297	setCaption: function() {
298		if (!this.option.caption) {
299			return this;
300		}
301		this.caption.text(this.getCaption(this.current));
302		return this;
303	},
304
305	getCaption: function(date) {
306		date = this.getKey(date).split('-');
307		var caption = typeof this.option.caption === 'object'
308			? this.option.caption[this.option.lang] : this.option.caption;
309		return caption
310			.replace(/%Y/i, date[0])
311			.replace(/%M/i, date[1])
312	},
313
314	move: function(number) {
315		var width = this.elem.innerWidth();
316		var pos   = this.elem.position();
317		var clone = this.elem.clone().css({
318			position: 'absolute',
319			top: pos.top + 'px',
320			left: pos.left + 'px',
321			zIndex: 1
322		});
323		this.resetWrap();
324		this.wrap.append(clone);
325
326		// Changing month
327		this.option.month = this.option.month + number;
328
329		// Before callback
330		var date = new Date(this.option.year, this.option.month - 1, 1);
331		date = this.getKey(date, true);
332		this.option.beforeMove(this.option, date[0], date[1]);
333
334		// Set Event
335		this.setPreloadEvent(number);
336		this.rebuild().show();
337
338		// Moving animation
339		var time = this.option.moveTime;
340		this.wrap.animate({height: this.elem.innerHeight()}, time);
341
342		// Next moving
343		if ((number + '').charAt(0) !== '-') {
344			clone.animate({marginLeft: '-' + width + 'px'}, time, function() {
345				clone.remove();
346			});
347
348		// Prev moving
349		} else {
350			this.elem.css({
351				position: 'absolute',
352				marginLeft: '-' + width + 'px'
353			});
354			var self = this;
355			this.elem.animate({marginLeft: 0}, time, function() {
356				clone.remove();
357				self.elem.css('position', 'static');
358			});
359		}
360		this.option.afterMove(this.option, date[0], date[1]); // Callback
361	},
362
363	resetWrap: function() {
364		this.wrap.css({
365			width : this.elem.innerWidth()  + 'px',
366			height: this.elem.innerHeight() + 'px'
367		});
368		return this;
369	},
370
371	setPreloadEvent: function(number) {
372		var type = number === 1 ? 'next' : 'prev';
373		try {
374			if (typeof this.preloadEvents[type] === 'object') {
375				return this.option.events = this.preloadEvents[type];
376			}
377			if (typeof this.preloadEvents === 'object') {
378				return this.option.events = this.preloadEvents;
379			}
380		} catch(e) {}
381	}
382
383}, Calendar.prototype);
384
385})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.