OSDN Git Service

43f514bb86dab88f7c232c73429a1be7a4c7953f
[cloudmanganw/git_repo.git] / war / WEB-INF / classes / jp / sourceforge / manganetwork / page / javascripts / spinelz / datepicker.js
1 // Copyright (c) 2005 spinelz.org (http://script.spinelz.org/)\r
2 // \r
3 // Permission is hereby granted, free of charge, to any person obtaining\r
4 // a copy of this software and associated documentation files (the\r
5 // "Software"), to deal in the Software without restriction, including\r
6 // without limitation the rights to use, copy, modify, merge, publish,\r
7 // distribute, sublicense, and/or sell copies of the Software, and to\r
8 // permit persons to whom the Software is furnished to do so, subject to\r
9 // the following conditions:\r
10 // \r
11 // The above copyright notice and this permission notice shall be\r
12 // included in all copies or substantial portions of the Software.\r
13 //\r
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21 \r
22 var DatePicker = Class.create();\r
23 DatePicker.className = {\r
24   container:     'datepicker',\r
25   header:        'datepicker_header',\r
26   footer:        'datepicker_footer',\r
27   preYears:      'datepicker_preYears',\r
28   nextYears:     'datepicker_nextYears',\r
29   years:         'datepicker_years',\r
30   calendar:      'datepicker_calendar',\r
31   date:          'datepicker_date',\r
32   holiday:       'datepicker_holiday',\r
33   ym:            'datepicker_ym',\r
34   table:         'datepicker_table',\r
35   tableTh:       'datepicker_tableTh',\r
36   nextMonthMark: 'datepicker_nextMonthMark',\r
37   nextYearMark:  'datepicker_nextYearMark',\r
38   preMonthMark:  'datepicker_preMonthMark',\r
39   preYearMark:   'datepicker_preYearMark',\r
40   zIndex:        null\r
41 }\r
42 DatePicker.prototype = {\r
43   \r
44   initialize: function(element, target, trigger) {\r
45     this.element = $(element);\r
46     Element.setStyle(this.element, {visibility: 'hidden'});\r
47     this.target = $(target);\r
48     this.date = new Date();\r
49 \r
50     this.options = Object.extend({\r
51       month:        this.date.getMonth() + 1,\r
52       date:         this.date.getDate(),\r
53       year:         this.date.getFullYear(),\r
54       format:       DateUtil.toLocaleDateString,\r
55       cssPrefix:    'custom_',\r
56       callBack:     Prototype.emptyFunction,\r
57       standTo:      false,\r
58       beforeShow:   Prototype.emptyFunction,\r
59       headerFormat: null,\r
60       dayOfWeek:    DateUtil.dayOfWeek\r
61     }, arguments[3] || {});\r
62     \r
63     var customCss = CssUtil.appendPrefix(this.options.cssPrefix, DatePicker.className);\r
64     this.classNames = new CssUtil([DatePicker.className, customCss]);\r
65     \r
66     this.format = this.options.format;\r
67     this.callBack = this.options.callBack;\r
68     \r
69     this.date.setMonth(this.options.month - 1);\r
70     this.date.setDate(this.options.date);\r
71     this.date.setFullYear(this.options.year);\r
72     \r
73     this.calendar = this.build();\r
74     this.element.appendChild(this.calendar);\r
75     this.cover = new IECover(this.element);\r
76     \r
77     this.doclistener = this.hide.bindAsEventListener(this);\r
78     Event.observe($(trigger), "click", this.show.bindAsEventListener(this));\r
79     this.hide();\r
80     Element.setStyle(this.element, {visibility: 'visible'});\r
81   },\r
82   \r
83   build: function() {\r
84     var node = \r
85       Builder.node(\r
86         'DIV', \r
87         {className: this.classNames.joinClassNames('container')},\r
88         [\r
89           this.buildHeader(),\r
90           this.buildCalendar(),\r
91           this.buildFooter()\r
92         ]);\r
93     \r
94     return node;\r
95   },\r
96   \r
97   buildHeader: function() {\r
98     var headerNodes = Builder.node('TR');\r
99     headerNodes.appendChild(this.buildHeaderLeft());\r
100     headerNodes.appendChild(this.buildHeaderCenter());\r
101     headerNodes.appendChild(this.buildHeaderRight());\r
102     \r
103     className = this.classNames.joinClassNames('header');\r
104     var tbody = Builder.node('TBODY', [headerNodes]);\r
105     return Builder.node('TABLE', {className: className}, [tbody]);\r
106   },\r
107 \r
108   buildFooter: function() {\r
109     var footer = Builder.node('DIV');\r
110     this.classNames.addClassNames(footer, 'footer');\r
111     return footer;\r
112   },\r
113 \r
114   buildHeaderLeft: function() {\r
115     var container = Builder.node('TD');\r
116     this.classNames.addClassNames(container, 'preYears');\r
117 \r
118     var id = this.element.id.appendSuffix('preYear');\r
119     var node = Builder.node('DIV', {id: id});\r
120     this.classNames.addClassNames(node, 'preYearMark');\r
121     Event.observe(node, "click", this.changeCalendar.bindAsEventListener(this));\r
122     container.appendChild(node);\r
123 \r
124     id = this.element.id.appendSuffix('preMonth');\r
125     node = Builder.node('DIV', {id: id});\r
126     this.classNames.addClassNames(node, 'preMonthMark');\r
127     Event.observe(node, "click", this.changeCalendar.bindAsEventListener(this));\r
128     container.appendChild(node);\r
129 \r
130     return container;\r
131   },\r
132 \r
133   buildHeaderCenter: function() {\r
134     var contents = [];\r
135     var yearMonth = this.getHeaderYearMonth();\r
136 \r
137     var id = this.element.id.appendSuffix('nextMonth');\r
138     var node = Builder.node('SPAN', {id: id}, [yearMonth[0]]);\r
139     this.classNames.addClassNames(node, 'ym');\r
140     contents.push(node);\r
141 \r
142     id = this.element.id.appendSuffix('nextYear');\r
143     node = Builder.node('SPAN', {id: id}, [yearMonth[1]]);\r
144     this.classNames.addClassNames(node, 'ym');\r
145     contents.push(node);\r
146 \r
147     var container = Builder.node('TD', contents);\r
148     this.classNames.addClassNames(container, 'years');\r
149 \r
150     return container;\r
151   },\r
152 \r
153   getHeaderYearMonth: function() {\r
154     if (this.options.headerFormat) {\r
155       var tmpl = new Template(this.options.headerFormat);\r
156       return [tmpl.evaluate({year: this.date.getFullYear(), month: this.date.getMonth() + 1}), ' '];\r
157     }\r
158     return [DateUtil.months[this.date.getMonth()], this.date.getFullYear()];\r
159   },\r
160 \r
161   buildHeaderRight: function() {\r
162     var container = Builder.node('TD');\r
163     this.classNames.addClassNames(container, 'nextYears');\r
164 \r
165     var id = this.element.id.appendSuffix('nextMonth');\r
166     var node = Builder.node('DIV', {id: id});\r
167     this.classNames.addClassNames(node, 'nextMonthMark');\r
168     Event.observe(node, "click", this.changeCalendar.bindAsEventListener(this));\r
169     container.appendChild(node);\r
170 \r
171     id = this.element.id.appendSuffix('nextYear');\r
172     node = Builder.node('DIV', {id: id});\r
173     this.classNames.addClassNames(node, 'nextYearMark');\r
174     Event.observe(node, "click", this.changeCalendar.bindAsEventListener(this));\r
175     container.appendChild(node);\r
176 \r
177     return container;\r
178   },\r
179   \r
180   multiBuild: function(tagType, params, className, hover, clickEvent) {\r
181     var children = [];\r
182     for (var i = 0; i < params.length; i++) {\r
183       var node;\r
184       \r
185       node = Builder.node(tagType, [params[i]]);\r
186       if (className)\r
187         this.classNames.addClassNames(node, className);\r
188         \r
189       if (hover)\r
190         new Hover(node);\r
191         \r
192       if (clickEvent)\r
193         Event.observe(node, "click", clickEvent.bindAsEventListener(this));\r
194         \r
195       children.push(node);\r
196     }\r
197     \r
198     return children;\r
199   },\r
200   \r
201   buildCalendar: function() {\r
202     var className = this.classNames.joinClassNames('table');\r
203     var node = Builder.node('TBODY', [this.buildTableHeader(), this.buildTableData()]);\r
204     var table = Builder.node('TABLE', {className: className}, [node]);\r
205                   \r
206     className = this.classNames.joinClassNames('calendar');\r
207     return Builder.node('DIV', {className: className}, [table]);\r
208   },\r
209   \r
210   buildTableHeader: function() {\r
211     var weekArray = new Array();\r
212     var className = this.classNames.joinClassNames('tableTh');\r
213     for (var i = 0; i < DateUtil.dayOfWeek.length; i++) {\r
214       weekArray.push(\r
215         Builder.node('TH', {className: className}, [this.options.dayOfWeek[i]]));\r
216     }\r
217     \r
218     return Builder.node('TR', weekArray);\r
219   },\r
220   \r
221   buildTableData: function() {\r
222     var length = DateUtil.dayOfWeek.length * 6;\r
223     var year = this.date.getFullYear();\r
224     var month = this.date.getMonth();\r
225     var firstDay = DateUtil.getFirstDate(year, month).getDay();\r
226     var lastDate = DateUtil.getLastDate(year, month).getDate();\r
227     var trs = new Array();\r
228     var tds = new Array();\r
229     \r
230     for (var i = 0, day = 1; i <= length; i++) {\r
231       if ((i < firstDay) || day > lastDate) {\r
232         tds.push(Builder.node('TD'));\r
233       \r
234       } else {\r
235         var className;\r
236         if ((i % 7 == 0) || ((i+1) % 7 == 0))\r
237           className = 'holiday';\r
238         else\r
239           className = 'date';\r
240           \r
241         var defaultClass = this.classNames.joinClassNames(className);\r
242         node = Builder.node('TD', {className: defaultClass}, [day]);\r
243         new Hover(node);\r
244         Event.observe(node, "click", this.selectDate.bindAsEventListener(this));\r
245         tds.push(node);\r
246         day++;\r
247       }\r
248       \r
249       if ((i + 1) % 7 == 0) {\r
250         trs.push(Builder.node('TR', tds));\r
251         tds = new Array();\r
252       }\r
253     }\r
254     \r
255     return trs;\r
256   },\r
257   \r
258   refresh: function() {\r
259     this.element.innerHTML = '';\r
260     this.calendar = this.build();\r
261     this.element.appendChild(this.calendar);\r
262     new IECover(this.element);\r
263   },\r
264   \r
265   getMonth: function() {\r
266     return  DateUtil.months[this.date.getMonth()];\r
267   },\r
268   \r
269   changeCalendar: function(event) {\r
270     var element = Event.element(event);\r
271     if (Element.hasClassName(element, DatePicker.className.preYearMark)) {\r
272       this.date.setFullYear(this.date.getFullYear() - 1);\r
273     } else if (Element.hasClassName(element, DatePicker.className.nextYearMark)) {\r
274       this.date.setFullYear(this.date.getFullYear() + 1);\r
275     } else if (Element.hasClassName(element, DatePicker.className.preMonthMark)) {\r
276       var pre = this.date.getMonth() - 1;\r
277       if (pre < 0) {\r
278         pre = 11;\r
279         this.date.setFullYear(this.date.getFullYear() - 1);\r
280       }\r
281       this.date.setMonth(pre);\r
282     } else if (Element.hasClassName(element, DatePicker.className.nextMonthMark)) {\r
283       var next = this.date.getMonth() + 1;\r
284       if (next > 11) {\r
285         next = 0;\r
286         this.date.setFullYear(this.date.getFullYear() + 1);\r
287       }\r
288       this.date.setMonth(next);\r
289     }\r
290     \r
291     this.refresh();\r
292     if (event) Event.stop(event);\r
293   },\r
294   \r
295   selectDate: function(event) {\r
296     var src = Event.element(event);\r
297     var text = Element.getTextNodes(src)[0];\r
298 \r
299     this.date.setDate(text.nodeValue);\r
300     var value = this.formatDateString();\r
301     \r
302     if (this.target.value || this.target.value == '') {\r
303       this.target.value = value;\r
304     } else {\r
305       this.target.innerHTML = value;\r
306     }\r
307     \r
308     this.hide();\r
309     this.classNames.refreshClassNames(src, 'date');\r
310     \r
311     this.callBack(this);\r
312   },\r
313   \r
314   show: function(event) {\r
315     var styles = $H({zIndex: ZindexManager.getIndex(this.options.zIndex)});\r
316     if (this.options.standTo) {\r
317       this.defaultParent = this.element.parentNode;\r
318       document.body.appendChild(this.element);\r
319       styles = styles.merge({ \r
320         position: 'absolute',\r
321         left:     Event.pointerX(event) + 'px',\r
322         top:      Event.pointerY(event) + 'px'\r
323       });\r
324     }\r
325 \r
326     Element.setStyle(this.element, styles);\r
327     Element.show(this.element);\r
328     this.cover.resetSize();\r
329     Event.observe(document, "click", this.doclistener);\r
330     if (event) {\r
331       Event.stop(event);\r
332     }\r
333   },\r
334   \r
335   hide: function() {\r
336     Event.stopObserving(document, "click", this.doclistener);\r
337     Element.hide(this.element);\r
338     if (this.defaultParent) {\r
339       this.defaultParent.appendChild(this.element);\r
340     }\r
341   },\r
342   \r
343   addTrigger: function(trigger) {\r
344     Event.observe($(trigger), 'click', this.show.bindAsEventListener(this));\r
345   },\r
346   \r
347   changeTarget: function(target) {\r
348     this.target = $(target);\r
349   },\r
350 \r
351   formatDateString: function() {\r
352     var string = '';\r
353     if (this.format.constructor == Function) {\r
354       string = this.format(this.date);\r
355     } else if (this.format.constructor == String) {\r
356       string = this.date.strftime(this.format);\r
357     }\r
358     return string;\r
359   }\r
360 }\r