rails_admin_content 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +38 -0
  3. data/Rakefile +7 -0
  4. data/app/assets/javascripts/develop/manages.js.coffee +96 -0
  5. data/app/assets/javascripts/rails_admin_content.js +22 -0
  6. data/app/assets/stylesheets/develop/manages.css.scss +38 -0
  7. data/app/assets/stylesheets/rails_admin_content.css +19 -0
  8. data/app/assets/stylesheets/site.css +479 -0
  9. data/app/controllers/application_controller.rb +3 -0
  10. data/app/controllers/rails_admin_content/develop/application_controller.rb +5 -0
  11. data/app/controllers/rails_admin_content/develop/manages_controller.rb +77 -0
  12. data/app/views/layouts/rails_admin_content/admin.html.slim +58 -0
  13. data/app/views/rails_admin_content/develop/manages/_content.html.slim +21 -0
  14. data/app/views/rails_admin_content/develop/manages/_filter.html.slim +25 -0
  15. data/app/views/rails_admin_content/develop/manages/_form.html.slim +5 -0
  16. data/app/views/rails_admin_content/develop/manages/_menv.html.slim +8 -0
  17. data/app/views/rails_admin_content/develop/manages/_navbar.html.slim +34 -0
  18. data/app/views/rails_admin_content/develop/manages/details.html.slim +18 -0
  19. data/app/views/rails_admin_content/develop/manages/edit.html.slim +16 -0
  20. data/app/views/rails_admin_content/develop/manages/edit_column.html.slim +30 -0
  21. data/app/views/rails_admin_content/develop/manages/index.html.slim +2 -0
  22. data/app/views/rails_admin_content/develop/manages/new.html.slim +10 -0
  23. data/app/views/rails_admin_content/develop/manages/query.html.slim +24 -0
  24. data/app/views/rails_admin_content/develop/manages/show.html.slim +27 -0
  25. data/config/routes.rb +12 -0
  26. data/lib/assets/codemirror/charisma-app.css +501 -0
  27. data/lib/assets/codemirror/codemirror.css +249 -0
  28. data/lib/assets/codemirror/codemirror.js +5637 -0
  29. data/lib/assets/codemirror/javascript.js +471 -0
  30. data/lib/assets/codemirror/matchbrackets.js +82 -0
  31. data/lib/assets/codemirror/midnight.css +52 -0
  32. data/lib/assets/codemirror/solarized.css +207 -0
  33. data/lib/assets/codemirror/sql.js +267 -0
  34. data/lib/assets/codemirror/twilight.css +26 -0
  35. data/lib/assets/images/add.png +0 -0
  36. data/lib/assets/images/column.png +0 -0
  37. data/lib/assets/images/content.png +0 -0
  38. data/lib/assets/images/details.png +0 -0
  39. data/lib/assets/images/file.png +0 -0
  40. data/lib/assets/images/home.png +0 -0
  41. data/lib/assets/images/search.png +0 -0
  42. data/lib/assets/images/setting.png +0 -0
  43. data/lib/assets/images/user.png +0 -0
  44. data/lib/assets/javascripts/bootstrap/bootstrap-alert.js +100 -0
  45. data/lib/assets/javascripts/jquery/dyndatetime/calendar_zh.js +128 -0
  46. data/lib/assets/javascripts/jquery/dyndatetime/dynDateTime.js +2011 -0
  47. data/lib/assets/javascripts/jquery/editable.js +31 -0
  48. data/lib/assets/javascripts/jquery/jquery.jeditable.js +543 -0
  49. data/lib/assets/stylesheets/bootstrap/bootstrap-app.css +5255 -0
  50. data/lib/assets/stylesheets/dyndatetime/calendar-system.css +251 -0
  51. data/lib/assets/stylesheets/dyndatetime/skins/aqua/active-bg.gif +0 -0
  52. data/lib/assets/stylesheets/dyndatetime/skins/aqua/dark-bg.gif +0 -0
  53. data/lib/assets/stylesheets/dyndatetime/skins/aqua/hover-bg.gif +0 -0
  54. data/lib/assets/stylesheets/dyndatetime/skins/aqua/menuarrow.gif +0 -0
  55. data/lib/assets/stylesheets/dyndatetime/skins/aqua/normal-bg.gif +0 -0
  56. data/lib/assets/stylesheets/dyndatetime/skins/aqua/rowhover-bg.gif +0 -0
  57. data/lib/assets/stylesheets/dyndatetime/skins/aqua/status-bg.gif +0 -0
  58. data/lib/assets/stylesheets/dyndatetime/skins/aqua/theme.css +236 -0
  59. data/lib/assets/stylesheets/dyndatetime/skins/aqua/title-bg.gif +0 -0
  60. data/lib/assets/stylesheets/dyndatetime/skins/aqua/today-bg.gif +0 -0
  61. data/lib/rails_admin_content/client.rb +93 -0
  62. data/lib/rails_admin_content/engine.rb +12 -0
  63. data/lib/rails_admin_content/helper.rb +65 -0
  64. data/lib/rails_admin_content/mysql/adapters/client.rb +18 -0
  65. data/lib/rails_admin_content/paginate.rb +53 -0
  66. data/lib/rails_admin_content/version.rb +3 -0
  67. data/lib/rails_admin_content.rb +5 -0
  68. metadata +180 -0
@@ -0,0 +1,26 @@
1
+ .cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/
2
+ .cm-s-twilight .CodeMirror-selected { background: #323232 !important; } /**/
3
+
4
+ .cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; }
5
+ .cm-s-twilight .CodeMirror-linenumber { color: #aaa; }
6
+ .cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white !important; }
7
+
8
+ .cm-s-twilight .cm-keyword { color: #f9ee98; } /**/
9
+ .cm-s-twilight .cm-atom { color: #FC0; }
10
+ .cm-s-twilight .cm-number { color: #ca7841; } /**/
11
+ .cm-s-twilight .cm-def { color: #8DA6CE; }
12
+ .cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/
13
+ .cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def { color: #607392; } /**/
14
+ .cm-s-twilight .cm-operator { color: #cda869; } /**/
15
+ .cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/
16
+ .cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
17
+ .cm-s-twilight .cm-string-2 { color:#bd6b18 } /*?*/
18
+ .cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/
19
+ .cm-s-twilight .cm-error { border-bottom: 1px solid red; }
20
+ .cm-s-twilight .cm-builtin { color: #cda869; } /*?*/
21
+ .cm-s-twilight .cm-tag { color: #997643; } /**/
22
+ .cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/
23
+ .cm-s-twilight .cm-header { color: #FF6400; }
24
+ .cm-s-twilight .cm-hr { color: #AEAEAE; }
25
+ .cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/
26
+
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,100 @@
1
+ /* ==========================================================
2
+ * bootstrap-alert.js v2.3.1
3
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
4
+ * ==========================================================
5
+ * Copyright 2012 Twitter, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ========================================================== */
19
+
20
+
21
+
22
+ !function ($) {
23
+
24
+ "use strict"; // jshint ;_;
25
+
26
+
27
+ /* ALERT CLASS DEFINITION
28
+ * ====================== */
29
+
30
+ var dismiss = '[data-dismiss="alert"]'
31
+ , Alert = function (el) {
32
+ $(el).on('click', dismiss, this.close)
33
+ }
34
+
35
+ Alert.prototype.close = function (e) {
36
+ var $this = $(this)
37
+ , selector = $this.attr('data-target')
38
+ , $parent
39
+
40
+ if (!selector) {
41
+ selector = $this.attr('href')
42
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
43
+ }
44
+
45
+ $parent = $(selector)
46
+
47
+ e && e.preventDefault()
48
+
49
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
50
+
51
+ $parent.trigger(e = $.Event('close'))
52
+
53
+ if (e.isDefaultPrevented()) return
54
+
55
+ $parent.removeClass('in')
56
+
57
+ function removeElement() {
58
+ $parent
59
+ .trigger('closed')
60
+ .remove()
61
+ }
62
+
63
+ $.support.transition && $parent.hasClass('fade') ?
64
+ $parent.on($.support.transition.end, removeElement) :
65
+ removeElement()
66
+ }
67
+
68
+
69
+ /* ALERT PLUGIN DEFINITION
70
+ * ======================= */
71
+
72
+ var old = $.fn.alert
73
+
74
+ $.fn.alert = function (option) {
75
+ return this.each(function () {
76
+ var $this = $(this)
77
+ , data = $this.data('alert')
78
+ if (!data) $this.data('alert', (data = new Alert(this)))
79
+ if (typeof option == 'string') data[option].call($this)
80
+ })
81
+ }
82
+
83
+ $.fn.alert.Constructor = Alert
84
+
85
+
86
+ /* ALERT NO CONFLICT
87
+ * ================= */
88
+
89
+ $.fn.alert.noConflict = function () {
90
+ $.fn.alert = old
91
+ return this
92
+ }
93
+
94
+
95
+ /* ALERT DATA-API
96
+ * ============== */
97
+
98
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
99
+
100
+ }(window.jQuery);
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Calendar EN language
3
+ * Author: Mihai Bazon, <mihai_bazon@yahoo.com>
4
+ */
5
+
6
+ // Encoding: any
7
+ // Distributed under the same terms as the calendar itself.
8
+
9
+ // For translators: please use UTF-8 if possible. We strongly believe that
10
+ // Unicode is the answer to a real internationalized world. Also please
11
+ // include your contact information in the header, as can be seen above.
12
+
13
+ // full day names
14
+ Calendar._DN = new Array
15
+ ("星期天",
16
+ "星期一",
17
+ "星期二",
18
+ "星期三",
19
+ "星期四",
20
+ "星期五",
21
+ "星期六",
22
+ "星期天");
23
+
24
+ // Please note that the following array of short day names (and the same goes
25
+ // for short month names, _SMN) isn't absolutely necessary. We give it here
26
+ // for exemplification on how one can customize the short day names, but if
27
+ // they are simply the first N letters of the full name you can simply say:
28
+ //
29
+ // Calendar._SDN_len = N; // short day name length
30
+ // Calendar._SMN_len = N; // short month name length
31
+ //
32
+ // If N = 3 then this is not needed either since we assume a value of 3 if not
33
+ // present, to be compatible with translation files that were written before
34
+ // this feature.
35
+
36
+ // short day names
37
+ Calendar._SDN = new Array
38
+ ("日",
39
+ "一",
40
+ "二",
41
+ "三",
42
+ "四",
43
+ "五",
44
+ "六",
45
+ "日");
46
+
47
+ // First day of the week. "0" means display Sunday first, "1" means display
48
+ // Monday first, etc.
49
+ Calendar._FD = 0;
50
+
51
+ // full month names
52
+ Calendar._MN = new Array
53
+ ("一月",
54
+ "二月",
55
+ "三月",
56
+ "四月",
57
+ "五月",
58
+ "六月",
59
+ "七月",
60
+ "八月",
61
+ "九月",
62
+ "十月",
63
+ "十一月",
64
+ "十二月");
65
+
66
+ // short month names
67
+ Calendar._SMN = new Array
68
+ ("一月",
69
+ "二月",
70
+ "三月",
71
+ "四月",
72
+ "五月",
73
+ "六月",
74
+ "七月",
75
+ "八月",
76
+ "九月",
77
+ "十月",
78
+ "十一月",
79
+ "十二月");
80
+
81
+ // tooltips
82
+ Calendar._TT = {};
83
+ Calendar._TT["INFO"] = "关于日历";
84
+
85
+ Calendar._TT["ABOUT"] =
86
+ "DHTML Date/Time Selector\n" +
87
+ "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
88
+ "For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
89
+ "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
90
+ "\n\n" +
91
+ "Date selection:\n" +
92
+ "- Use the \xab, \xbb buttons to select year\n" +
93
+ "- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
94
+ "- Hold mouse button on any of the above buttons for faster selection.";
95
+ Calendar._TT["ABOUT_TIME"] = "\n\n" +
96
+ "Time selection:\n" +
97
+ "- Click on any of the time parts to increase it\n" +
98
+ "- or Shift-click to decrease it\n" +
99
+ "- or click and drag for faster selection.";
100
+
101
+ Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
102
+ Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
103
+ Calendar._TT["GO_TODAY"] = "Go Today";
104
+ Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
105
+ Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
106
+ Calendar._TT["SEL_DATE"] = "Select date";
107
+ Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
108
+ Calendar._TT["PART_TODAY"] = " (today)";
109
+
110
+ // the following is to inform that "%s" is to be the first day of week
111
+ // %s will be replaced with the day name.
112
+ Calendar._TT["DAY_FIRST"] = "Display %s first";
113
+
114
+ // This may be locale-dependent. It specifies the week-end days, as an array
115
+ // of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
116
+ // means Monday, etc.
117
+ Calendar._TT["WEEKEND"] = "0,6";
118
+
119
+ Calendar._TT["CLOSE"] = "关闭";
120
+ Calendar._TT["TODAY"] = "今天";
121
+ Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
122
+
123
+ // date formats
124
+ Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
125
+ Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
126
+
127
+ Calendar._TT["WK"] = "周";
128
+ Calendar._TT["TIME"] = "Time:";
@@ -0,0 +1,2011 @@
1
+ /*
2
+ dynDateTime @VERSION
3
+
4
+ A jQuery date time picker.
5
+
6
+ Author: Toolman
7
+ Version: @VERSION
8
+ Website: http://code.google.com/p/dyndatetime/
9
+
10
+ */
11
+
12
+
13
+ (function($) {
14
+
15
+ $.fn.dynDateTime = function(options) {
16
+
17
+ // plugin defaults
18
+ $.fn.dynDateTime.defaults = {
19
+ displayArea: null,
20
+ button: null,
21
+ eventName: "click",
22
+ ifFormat: "%Y-%m-%d %H:%M:%S",
23
+ daFormat: "%Y-%m-%d %H:%M:%S",
24
+ singleClick: true,
25
+ dateStatusFunc: null,
26
+ dateText: null,
27
+ firstDay: null,
28
+ align: "Br",
29
+ range: [1900, 2999],
30
+ weekNumbers: true,
31
+ flat: null,
32
+ flatCallback: null,
33
+ onSelect: null,
34
+ onClose: null,
35
+ onUpdate: null,
36
+ date: null,
37
+ showsTime: true,
38
+ timeFormat: "24",
39
+ electric: true,
40
+ step: 2,
41
+ position: null,
42
+ position_css: 'absolute',
43
+ cache: false,
44
+ showOthers: true,
45
+ multiple: null,
46
+ debug: false
47
+ };
48
+
49
+ var opts = $.extend({}, $.fn.dynDateTime.defaults, options);
50
+
51
+ return this.each(function() {
52
+
53
+ //opts are shared per jQuery call; create per inputField closures of non-shared values for each instance
54
+ var this_inputField = this;
55
+ var this_displayArea = null;
56
+ var this_button = null;
57
+ var this_flat = null;
58
+ if(opts.displayArea) {
59
+ try {
60
+ this_displayArea = eval("jQuery(this)" + opts.displayArea + ".get(0);");
61
+ } catch (err) {
62
+ opts.displayArea = null;
63
+ }
64
+ }
65
+ if(opts.button) {
66
+ try {
67
+ this_button = eval("jQuery(this)" + opts.button + ".get(0);");
68
+ } catch (err) {
69
+ opts.button = null;
70
+ }
71
+ }
72
+ if(opts.flat) {
73
+ try {
74
+ this_flat = eval("jQuery(this)" + opts.flat + ".get(0);");
75
+ } catch (err) {
76
+ opts.flat = null;
77
+ }
78
+ }
79
+
80
+ if (!(this_flat || opts.multiple || this_inputField || this_displayArea || this_button)) {
81
+ log("opts");
82
+ //nothing to do
83
+ return;
84
+ }
85
+
86
+ //default onSelect
87
+ function onSelect(cal) {
88
+ var p = cal.opts;
89
+ var update = (cal.dateClicked || p.electric);
90
+ if (update && this_inputField) {
91
+ this_inputField.value = cal.date.print(p.ifFormat);
92
+ if (typeof this_inputField.onchange == "function")
93
+ this_inputField.onchange();
94
+ }
95
+ if (update && this_displayArea)
96
+ this_displayArea.innerHTML = cal.date.print(p.daFormat);
97
+ if (update && typeof p.onUpdate == "function")
98
+ p.onUpdate(cal);
99
+ if (update && p.flat) {
100
+ if (typeof p.flatCallback == "function")
101
+ p.flatCallback(cal);
102
+ }
103
+ if (update && p.singleClick && cal.dateClicked)
104
+ cal.callCloseHandler();
105
+ };
106
+
107
+ //flat setup
108
+ if (this_flat != null) {
109
+
110
+ var cal = new Calendar(opts.firstDay, opts.date, opts.onSelect || onSelect);
111
+ cal.showsOtherMonths = opts.showOthers;
112
+ cal.showsTime = opts.showsTime;
113
+ cal.time24 = (opts.timeFormat == "24");
114
+ cal.opts = opts;
115
+ cal.weekNumbers = opts.weekNumbers;
116
+ cal.setRange(opts.range[0], opts.range[1]);
117
+ cal.setDateStatusHandler(opts.dateStatusFunc);
118
+ cal.getDateText = opts.dateText;
119
+ if (opts.ifFormat) {
120
+ cal.setDateFormat(opts.ifFormat);
121
+ }
122
+ if (this_inputField && typeof this_inputField.value == "string") {
123
+ //cal.parseDate(this_inputField.value);
124
+ log("rar");
125
+ }
126
+ cal.create(this_flat);
127
+ cal.show();
128
+ return;
129
+ }
130
+
131
+ //find the element to mount show/hide event
132
+ var triggerEl = this_button || this_displayArea || this_inputField ;
133
+
134
+ //bolt on event
135
+ triggerEl["on" + opts.eventName] = function() {
136
+ log("clicked");
137
+ var dateEl = this_inputField || this_displayArea;
138
+ var dateFmt = this_inputField ? opts.ifFormat : opts.daFormat;
139
+ var mustCreate = false;
140
+ var cal = window.calendar;
141
+ if (dateEl) {
142
+ var datevalue = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
143
+ if (datevalue != NaN) {
144
+ opts.date = datevalue;
145
+ }
146
+ }
147
+
148
+ if (!(cal && opts.cache)) {
149
+ window.calendar = cal = new Calendar(opts.firstDay,
150
+ opts.date,
151
+ opts.onSelect || onSelect,
152
+ opts.onClose || function(cal) { cal.hide(); });
153
+ cal.showsTime = opts.showsTime;
154
+ cal.time24 = (opts.timeFormat == "24");
155
+ cal.weekNumbers = opts.weekNumbers;
156
+ mustCreate = true;
157
+ } else {
158
+ if (opts.date)
159
+ cal.setDate(opts.date);
160
+ cal.hide();
161
+ }
162
+ if (opts.multiple) {
163
+ cal.multiple = {};
164
+ for (var i = opts.multiple.length; --i >= 0;) {
165
+ var d = opts.multiple[i];
166
+ var ds = d.print("%Y%m%d");
167
+ cal.multiple[ds] = d;
168
+ }
169
+ }
170
+ cal.showsOtherMonths = opts.showOthers;
171
+ cal.yearStep = opts.step;
172
+ cal.setRange(opts.range[0], opts.range[1]);
173
+ cal.opts = opts;
174
+ cal.setDateStatusHandler(opts.dateStatusFunc);
175
+ cal.getDateText = opts.dateText;
176
+ cal.setDateFormat(dateFmt);
177
+ if (mustCreate)
178
+ cal.create();
179
+ cal.refresh();
180
+ if (!opts.position)
181
+ cal.showAtElement(this_button || this_displayArea || this_inputField, opts.align);
182
+ else
183
+ cal.showAt(opts.position[0], opts.position[1]);
184
+ return false;
185
+ };
186
+ });
187
+
188
+ // private function for debugging
189
+ function log(msg) {
190
+ if(opts.debug) {
191
+ window.loadFirebugConsole(); // file:// based access seems to disable this for me!
192
+ if (window.console && window.console.log ) window.console.log("dynDateTime: " + msg);
193
+ }
194
+ };
195
+ };
196
+ })(jQuery);
197
+
198
+ // Begin old dynarch code
199
+
200
+ /* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo
201
+ * -----------------------------------------------------------
202
+ *
203
+ * The DHTML Calendar, version 1.0 "It is happening again"
204
+ *
205
+ * Details and latest version at:
206
+ * www.dynarch.com/projects/calendar
207
+ *
208
+ * This script is developed by Dynarch.com. Visit us at www.dynarch.com.
209
+ *
210
+ * This script is distributed under the GNU Lesser General Public License.
211
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
212
+ */
213
+
214
+ // $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $
215
+
216
+ /** The Calendar object constructor. */
217
+ Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
218
+ // member variables
219
+ this.activeDiv = null;
220
+ this.currentDateEl = null;
221
+ this.getDateStatus = null;
222
+ this.getDateToolTip = null;
223
+ this.getDateText = null;
224
+ this.timeout = null;
225
+ this.onSelected = onSelected || null;
226
+ this.onClose = onClose || null;
227
+ this.dragging = false;
228
+ this.hidden = false;
229
+ this.minYear = 1970;
230
+ this.maxYear = 2050;
231
+ this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
232
+ this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
233
+ this.isPopup = true;
234
+ this.weekNumbers = true;
235
+ this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : (Calendar._FD ? Calendar._FD : 0 ); // 0 for Sunday, 1 for Monday, etc.
236
+ this.showsOtherMonths = false;
237
+ this.dateStr = dateStr;
238
+ this.ar_days = null;
239
+ this.showsTime = false;
240
+ this.time24 = true;
241
+ this.yearStep = 2;
242
+ this.hiliteToday = true;
243
+ this.multiple = null;
244
+ // HTML elements
245
+ this.table = null;
246
+ this.element = null;
247
+ this.tbody = null;
248
+ this.firstdayname = null;
249
+ // Combo boxes
250
+ this.monthsCombo = null;
251
+ this.yearsCombo = null;
252
+ this.hilitedMonth = null;
253
+ this.activeMonth = null;
254
+ this.hilitedYear = null;
255
+ this.activeYear = null;
256
+ // Information
257
+ this.dateClicked = false;
258
+
259
+ // one-time initializations
260
+ if (typeof Calendar._SDN == "undefined") {
261
+ // table of short day names
262
+ if (typeof Calendar._SDN_len == "undefined")
263
+ Calendar._SDN_len = 3;
264
+ var ar = new Array();
265
+ for (var i = 8; i > 0;) {
266
+ ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
267
+ }
268
+ Calendar._SDN = ar;
269
+ // table of short month names
270
+ if (typeof Calendar._SMN_len == "undefined")
271
+ Calendar._SMN_len = 3;
272
+ ar = new Array();
273
+ for (var i = 12; i > 0;) {
274
+ ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
275
+ }
276
+ Calendar._SMN = ar;
277
+ }
278
+ };
279
+
280
+ // ** constants
281
+
282
+ /// "static", needed for event handlers.
283
+ Calendar._C = null;
284
+
285
+ /// detect a special case of "web browser"
286
+ Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
287
+ !/opera/i.test(navigator.userAgent) );
288
+
289
+ Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
290
+
291
+ /// detect Opera browser
292
+ Calendar.is_opera = /opera/i.test(navigator.userAgent);
293
+
294
+ /// detect KHTML-based browsers
295
+ Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
296
+
297
+ // BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
298
+ // library, at some point.
299
+
300
+ Calendar.getAbsolutePos = function(el) {
301
+ var SL = 0, ST = 0;
302
+ var is_div = /^div$/i.test(el.tagName);
303
+ if (is_div && el.scrollLeft)
304
+
305
+ SL = el.scrollLeft;
306
+ if (is_div && el.scrollTop)
307
+ ST = el.scrollTop;
308
+ var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
309
+ if (el.offsetParent) {
310
+ var tmp = this.getAbsolutePos(el.offsetParent);
311
+ r.x += tmp.x;
312
+ r.y += tmp.y;
313
+ }
314
+ return r;
315
+ };
316
+
317
+ Calendar.isRelated = function (el, evt) {
318
+ var related = evt.relatedTarget;
319
+ if (!related) {
320
+ var type = evt.type;
321
+ if (type == "mouseover") {
322
+ related = evt.fromElement;
323
+ } else if (type == "mouseout") {
324
+ related = evt.toElement;
325
+ }
326
+ }
327
+ while (related) {
328
+ if (related == el) {
329
+ return true;
330
+ }
331
+ related = related.parentNode;
332
+ }
333
+ return false;
334
+ };
335
+
336
+ Calendar.removeClass = function(el, className) {
337
+ if (!(el && el.className)) {
338
+ return;
339
+ }
340
+ var cls = el.className.split(" ");
341
+ var ar = new Array();
342
+ for (var i = cls.length; i > 0;) {
343
+ if (cls[--i] != className) {
344
+ ar[ar.length] = cls[i];
345
+ }
346
+ }
347
+ el.className = ar.join(" ");
348
+ };
349
+
350
+ Calendar.addClass = function(el, className) {
351
+ Calendar.removeClass(el, className);
352
+ el.className += " " + className;
353
+ };
354
+
355
+ // FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
356
+ Calendar.getElement = function(ev) {
357
+ var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
358
+ while (f.nodeType != 1 || /^div$/i.test(f.tagName))
359
+ f = f.parentNode;
360
+ return f;
361
+ };
362
+
363
+ Calendar.getTargetElement = function(ev) {
364
+ var f = Calendar.is_ie ? window.event.srcElement : ev.target;
365
+ while (f.nodeType != 1)
366
+ f = f.parentNode;
367
+ return f;
368
+ };
369
+
370
+ Calendar.stopEvent = function(ev) {
371
+ ev || (ev = window.event);
372
+ if (Calendar.is_ie) {
373
+ ev.cancelBubble = true;
374
+ ev.returnValue = false;
375
+ } else {
376
+ ev.preventDefault();
377
+ ev.stopPropagation();
378
+ }
379
+ return false;
380
+ };
381
+
382
+ Calendar.addEvent = function(el, evname, func) {
383
+ if (el.attachEvent) { // IE
384
+ el.attachEvent("on" + evname, func);
385
+ } else if (el.addEventListener) { // Gecko / W3C
386
+ el.addEventListener(evname, func, true);
387
+ } else {
388
+ el["on" + evname] = func;
389
+ }
390
+ };
391
+
392
+ Calendar.removeEvent = function(el, evname, func) {
393
+ if (el.detachEvent) { // IE
394
+ el.detachEvent("on" + evname, func);
395
+ } else if (el.removeEventListener) { // Gecko / W3C
396
+ el.removeEventListener(evname, func, true);
397
+ } else {
398
+ el["on" + evname] = null;
399
+ }
400
+ };
401
+
402
+ Calendar.createElement = function(type, parent) {
403
+ var el = null;
404
+ if (document.createElementNS) {
405
+ // use the XHTML namespace; IE won't normally get here unless
406
+ // _they_ "fix" the DOM2 implementation.
407
+ el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
408
+ } else {
409
+ el = document.createElement(type);
410
+ }
411
+ if (typeof parent != "undefined") {
412
+ parent.appendChild(el);
413
+ }
414
+ return el;
415
+ };
416
+
417
+ // END: UTILITY FUNCTIONS
418
+
419
+ // BEGIN: CALENDAR STATIC FUNCTIONS
420
+
421
+ /** Internal -- adds a set of events to make some element behave like a button. */
422
+ Calendar._add_evs = function(el) {
423
+ with (Calendar) {
424
+ addEvent(el, "mouseover", dayMouseOver);
425
+ addEvent(el, "mousedown", dayMouseDown);
426
+ addEvent(el, "mouseout", dayMouseOut);
427
+ if (is_ie) {
428
+ addEvent(el, "dblclick", dayMouseDblClick);
429
+ el.setAttribute("unselectable", true);
430
+ }
431
+ }
432
+ };
433
+
434
+ Calendar.findMonth = function(el) {
435
+ if (typeof el.month != "undefined") {
436
+ return el;
437
+ } else if (typeof el.parentNode.month != "undefined") {
438
+ return el.parentNode;
439
+ }
440
+ return null;
441
+ };
442
+
443
+ Calendar.findYear = function(el) {
444
+ if (typeof el.year != "undefined") {
445
+ return el;
446
+ } else if (typeof el.parentNode.year != "undefined") {
447
+ return el.parentNode;
448
+ }
449
+ return null;
450
+ };
451
+
452
+ Calendar.showMonthsCombo = function () {
453
+ var cal = Calendar._C;
454
+ if (!cal) {
455
+ return false;
456
+ }
457
+ var cal = cal;
458
+ var cd = cal.activeDiv;
459
+ var mc = cal.monthsCombo;
460
+ if (cal.hilitedMonth) {
461
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
462
+ }
463
+ if (cal.activeMonth) {
464
+ Calendar.removeClass(cal.activeMonth, "active");
465
+ }
466
+ var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
467
+ Calendar.addClass(mon, "active");
468
+ cal.activeMonth = mon;
469
+ var s = mc.style;
470
+ s.display = "block";
471
+ if (cd.navtype < 0)
472
+ s.left = cd.offsetLeft + "px";
473
+ else {
474
+ var mcw = mc.offsetWidth;
475
+ if (typeof mcw == "undefined")
476
+ // Konqueror brain-dead techniques
477
+ mcw = 50;
478
+ s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
479
+ }
480
+ s.top = (cd.offsetTop + cd.offsetHeight) + "px";
481
+ };
482
+
483
+ Calendar.showYearsCombo = function (fwd) {
484
+ var cal = Calendar._C;
485
+ if (!cal) {
486
+ return false;
487
+ }
488
+ var cal = cal;
489
+ var cd = cal.activeDiv;
490
+ var yc = cal.yearsCombo;
491
+ if (cal.hilitedYear) {
492
+ Calendar.removeClass(cal.hilitedYear, "hilite");
493
+ }
494
+ if (cal.activeYear) {
495
+ Calendar.removeClass(cal.activeYear, "active");
496
+ }
497
+ cal.activeYear = null;
498
+ var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
499
+ var yr = yc.firstChild;
500
+ var show = false;
501
+ for (var i = 12; i > 0; --i) {
502
+ if (Y >= cal.minYear && Y <= cal.maxYear) {
503
+ yr.innerHTML = Y;
504
+ yr.year = Y;
505
+ yr.style.display = "block";
506
+ show = true;
507
+ } else {
508
+ yr.style.display = "none";
509
+ }
510
+ yr = yr.nextSibling;
511
+ Y += fwd ? cal.yearStep : -cal.yearStep;
512
+ }
513
+ if (show) {
514
+ var s = yc.style;
515
+ s.display = "block";
516
+ if (cd.navtype < 0)
517
+ s.left = cd.offsetLeft + "px";
518
+ else {
519
+ var ycw = yc.offsetWidth;
520
+ if (typeof ycw == "undefined")
521
+ // Konqueror brain-dead techniques
522
+ ycw = 50;
523
+ s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
524
+ }
525
+ s.top = (cd.offsetTop + cd.offsetHeight) + "px";
526
+ }
527
+ };
528
+
529
+ // event handlers
530
+
531
+ Calendar.tableMouseUp = function(ev) {
532
+ var cal = Calendar._C;
533
+ if (!cal) {
534
+ return false;
535
+ }
536
+ if (cal.timeout) {
537
+ clearTimeout(cal.timeout);
538
+ }
539
+ var el = cal.activeDiv;
540
+ if (!el) {
541
+ return false;
542
+ }
543
+ var target = Calendar.getTargetElement(ev);
544
+ ev || (ev = window.event);
545
+ Calendar.removeClass(el, "active");
546
+ if (target == el || target.parentNode == el) {
547
+ Calendar.cellClick(el, ev);
548
+ }
549
+ var mon = Calendar.findMonth(target);
550
+ var date = null;
551
+ if (mon) {
552
+ date = new Date(cal.date);
553
+ if (mon.month != date.getMonth()) {
554
+ date.setMonth(mon.month);
555
+ cal.setDate(date);
556
+ cal.dateClicked = false;
557
+ cal.callHandler();
558
+ }
559
+ } else {
560
+ var year = Calendar.findYear(target);
561
+ if (year) {
562
+ date = new Date(cal.date);
563
+ if (year.year != date.getFullYear()) {
564
+ date.setFullYear(year.year);
565
+ cal.setDate(date);
566
+ cal.dateClicked = false;
567
+ cal.callHandler();
568
+ }
569
+ }
570
+ }
571
+ with (Calendar) {
572
+ removeEvent(document, "mouseup", tableMouseUp);
573
+ removeEvent(document, "mouseover", tableMouseOver);
574
+ removeEvent(document, "mousemove", tableMouseOver);
575
+ cal._hideCombos();
576
+ _C = null;
577
+ return stopEvent(ev);
578
+ }
579
+ };
580
+
581
+ Calendar.tableMouseOver = function (ev) {
582
+ var cal = Calendar._C;
583
+ if (!cal) {
584
+ return;
585
+ }
586
+ var el = cal.activeDiv;
587
+ var target = Calendar.getTargetElement(ev);
588
+ if (target == el || target.parentNode == el) {
589
+ Calendar.addClass(el, "hilite active");
590
+ Calendar.addClass(el.parentNode, "rowhilite");
591
+ } else {
592
+ if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
593
+ Calendar.removeClass(el, "active");
594
+ Calendar.removeClass(el, "hilite");
595
+ Calendar.removeClass(el.parentNode, "rowhilite");
596
+ }
597
+ ev || (ev = window.event);
598
+ if (el.navtype == 50 && target != el) {
599
+ var pos = Calendar.getAbsolutePos(el);
600
+ var w = el.offsetWidth;
601
+ var x = ev.clientX;
602
+ var dx;
603
+ var decrease = true;
604
+ if (x > pos.x + w) {
605
+ dx = x - pos.x - w;
606
+ decrease = false;
607
+ } else
608
+ dx = pos.x - x;
609
+
610
+ if (dx < 0) dx = 0;
611
+ var range = el._range;
612
+ var current = el._current;
613
+ var count = Math.floor(dx / 10) % range.length;
614
+ for (var i = range.length; --i >= 0;)
615
+ if (range[i] == current)
616
+ break;
617
+ while (count-- > 0)
618
+ if (decrease) {
619
+ if (--i < 0)
620
+ i = range.length - 1;
621
+ } else if ( ++i >= range.length )
622
+ i = 0;
623
+ var newval = range[i];
624
+ el.innerHTML = newval;
625
+
626
+ cal.onUpdateTime();
627
+ }
628
+ var mon = Calendar.findMonth(target);
629
+ if (mon) {
630
+ if (mon.month != cal.date.getMonth()) {
631
+ if (cal.hilitedMonth) {
632
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
633
+ }
634
+ Calendar.addClass(mon, "hilite");
635
+ cal.hilitedMonth = mon;
636
+ } else if (cal.hilitedMonth) {
637
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
638
+ }
639
+ } else {
640
+ if (cal.hilitedMonth) {
641
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
642
+ }
643
+ var year = Calendar.findYear(target);
644
+ if (year) {
645
+ if (year.year != cal.date.getFullYear()) {
646
+ if (cal.hilitedYear) {
647
+ Calendar.removeClass(cal.hilitedYear, "hilite");
648
+ }
649
+ Calendar.addClass(year, "hilite");
650
+ cal.hilitedYear = year;
651
+ } else if (cal.hilitedYear) {
652
+ Calendar.removeClass(cal.hilitedYear, "hilite");
653
+ }
654
+ } else if (cal.hilitedYear) {
655
+ Calendar.removeClass(cal.hilitedYear, "hilite");
656
+ }
657
+ }
658
+ return Calendar.stopEvent(ev);
659
+ };
660
+
661
+ Calendar.tableMouseDown = function (ev) {
662
+ if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
663
+ return Calendar.stopEvent(ev);
664
+ }
665
+ };
666
+
667
+ Calendar.calDragIt = function (ev) {
668
+ var cal = Calendar._C;
669
+ if (!(cal && cal.dragging)) {
670
+ return false;
671
+ }
672
+ var posX;
673
+ var posY;
674
+ if (Calendar.is_ie) {
675
+ posY = window.event.clientY + document.body.scrollTop;
676
+ posX = window.event.clientX + document.body.scrollLeft;
677
+ } else {
678
+ posX = ev.pageX;
679
+ posY = ev.pageY;
680
+ }
681
+ cal.hideShowCovered();
682
+ var st = cal.element.style;
683
+ st.left = (posX - cal.xOffs) + "px";
684
+ st.top = (posY - cal.yOffs) + "px";
685
+ return Calendar.stopEvent(ev);
686
+ };
687
+
688
+ Calendar.calDragEnd = function (ev) {
689
+ var cal = Calendar._C;
690
+ if (!cal) {
691
+ return false;
692
+ }
693
+ cal.dragging = false;
694
+ with (Calendar) {
695
+ removeEvent(document, "mousemove", calDragIt);
696
+ removeEvent(document, "mouseup", calDragEnd);
697
+ tableMouseUp(ev);
698
+ }
699
+ cal.hideShowCovered();
700
+ };
701
+
702
+ Calendar.dayMouseDown = function(ev) {
703
+ var el = Calendar.getElement(ev);
704
+ if (el.disabled) {
705
+ return false;
706
+ }
707
+ var cal = el.calendar;
708
+ cal.activeDiv = el;
709
+ Calendar._C = cal;
710
+ if (el.navtype != 300) with (Calendar) {
711
+ if (el.navtype == 50) {
712
+ el._current = el.innerHTML;
713
+ addEvent(document, "mousemove", tableMouseOver);
714
+ } else
715
+ addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
716
+ addClass(el, "hilite active");
717
+ addEvent(document, "mouseup", tableMouseUp);
718
+ } else if (cal.isPopup) {
719
+ cal._dragStart(ev);
720
+ }
721
+ if (el.navtype == -1 || el.navtype == 1) {
722
+ if (cal.timeout) clearTimeout(cal.timeout);
723
+ cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
724
+ } else if (el.navtype == -2 || el.navtype == 2) {
725
+ if (cal.timeout) clearTimeout(cal.timeout);
726
+ cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
727
+ } else {
728
+ cal.timeout = null;
729
+ }
730
+ return Calendar.stopEvent(ev);
731
+ };
732
+
733
+ Calendar.dayMouseDblClick = function(ev) {
734
+ Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
735
+ if (Calendar.is_ie) {
736
+ document.selection.empty();
737
+ }
738
+ };
739
+
740
+ Calendar.dayMouseOver = function(ev) {
741
+ var el = Calendar.getElement(ev);
742
+ if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
743
+ return false;
744
+ }
745
+ if (el.ttip) {
746
+ if (el.ttip.substr(0, 1) == "_") {
747
+ el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
748
+ }
749
+ el.calendar.tooltips.innerHTML = el.ttip;
750
+ }
751
+ if (el.navtype != 300) {
752
+ Calendar.addClass(el, "hilite");
753
+ if (el.caldate) {
754
+ Calendar.addClass(el.parentNode, "rowhilite");
755
+ }
756
+ }
757
+ return Calendar.stopEvent(ev);
758
+ };
759
+
760
+ Calendar.dayMouseOut = function(ev) {
761
+ with (Calendar) {
762
+ var el = getElement(ev);
763
+ if (isRelated(el, ev) || _C || el.disabled)
764
+ return false;
765
+ removeClass(el, "hilite");
766
+ if (el.caldate)
767
+ removeClass(el.parentNode, "rowhilite");
768
+ if (el.calendar)
769
+ el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
770
+ return stopEvent(ev);
771
+ }
772
+ };
773
+
774
+ /**
775
+ * A generic "click" handler :) handles all types of buttons defined in this
776
+ * calendar.
777
+ */
778
+ Calendar.cellClick = function(el, ev) {
779
+ var cal = el.calendar;
780
+ var closing = false;
781
+ var newdate = false;
782
+ var date = null;
783
+ if (typeof el.navtype == "undefined") {
784
+ if (cal.currentDateEl) {
785
+ Calendar.removeClass(cal.currentDateEl, "selected");
786
+ Calendar.addClass(el, "selected");
787
+ closing = (cal.currentDateEl == el);
788
+ if (!closing) {
789
+ cal.currentDateEl = el;
790
+ }
791
+ }
792
+ cal.date.setDateOnly(el.caldate);
793
+ date = cal.date;
794
+ var other_month = !(cal.dateClicked = !el.otherMonth);
795
+ if (!other_month && !cal.currentDateEl)
796
+ cal._toggleMultipleDate(new Date(date));
797
+ else
798
+ newdate = !el.disabled;
799
+ // a date was clicked
800
+ if (other_month)
801
+ cal._init(cal.firstDayOfWeek, date);
802
+ } else {
803
+ if (el.navtype == 200) {
804
+ Calendar.removeClass(el, "hilite");
805
+ cal.callCloseHandler();
806
+ return;
807
+ }
808
+ date = new Date(cal.date);
809
+ if (el.navtype == 0)
810
+ date.setDateOnly(new Date()); // TODAY
811
+ // unless "today" was clicked, we assume no date was clicked so
812
+ // the selected handler will know not to close the calenar when
813
+ // in single-click mode.
814
+ // cal.dateClicked = (el.navtype == 0);
815
+ cal.dateClicked = false;
816
+ var year = date.getFullYear();
817
+ var mon = date.getMonth();
818
+ function setMonth(m) {
819
+ var day = date.getDate();
820
+ var max = date.getMonthDays(m);
821
+ if (day > max) {
822
+ date.setDate(max);
823
+ }
824
+ date.setMonth(m);
825
+ };
826
+ switch (el.navtype) {
827
+ case 400:
828
+ Calendar.removeClass(el, "hilite");
829
+ var text = Calendar._TT["ABOUT"];
830
+ if (typeof text != "undefined") {
831
+ text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
832
+ } else {
833
+ // FIXME: this should be removed as soon as lang files get updated!
834
+ text = "Help and about box text is not translated into this language.\n" +
835
+ "If you know this language and you feel generous please update\n" +
836
+ "the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
837
+ "and send it back to <mihai_bazon@yahoo.com> to get it into the distribution ;-)\n\n" +
838
+ "Thank you!\n" +
839
+ "http://dynarch.com/mishoo/calendar.epl\n";
840
+ }
841
+ alert(text);
842
+ return;
843
+ case -2:
844
+ if (year > cal.minYear) {
845
+ date.setFullYear(year - 1);
846
+ }
847
+ break;
848
+ case -1:
849
+ if (mon > 0) {
850
+ setMonth(mon - 1);
851
+ } else if (year-- > cal.minYear) {
852
+ date.setFullYear(year);
853
+ setMonth(11);
854
+ }
855
+ break;
856
+ case 1:
857
+ if (mon < 11) {
858
+ setMonth(mon + 1);
859
+ } else if (year < cal.maxYear) {
860
+ date.setFullYear(year + 1);
861
+ setMonth(0);
862
+ }
863
+ break;
864
+ case 2:
865
+ if (year < cal.maxYear) {
866
+ date.setFullYear(year + 1);
867
+ }
868
+ break;
869
+ case 100:
870
+ cal.setFirstDayOfWeek(el.fdow);
871
+ return;
872
+ case 50:
873
+ var range = el._range;
874
+ var current = el.innerHTML;
875
+ for (var i = range.length; --i >= 0;)
876
+ if (range[i] == current)
877
+ break;
878
+ if (ev && ev.shiftKey) {
879
+ if (--i < 0)
880
+ i = range.length - 1;
881
+ } else if ( ++i >= range.length )
882
+ i = 0;
883
+ var newval = range[i];
884
+ el.innerHTML = newval;
885
+ cal.onUpdateTime();
886
+ return;
887
+ case 0:
888
+ // TODAY will bring us here
889
+ if ((typeof cal.getDateStatus == "function") &&
890
+ cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
891
+ return false;
892
+ }
893
+ break;
894
+ }
895
+ if (!date.equalsTo(cal.date)) {
896
+ cal.setDate(date);
897
+ newdate = true;
898
+ } else if (el.navtype == 0)
899
+ newdate = closing = true;
900
+ }
901
+ if (newdate) {
902
+ ev && cal.callHandler();
903
+ }
904
+ if (closing) {
905
+ Calendar.removeClass(el, "hilite");
906
+ ev && cal.callCloseHandler();
907
+ }
908
+ };
909
+
910
+ // END: CALENDAR STATIC FUNCTIONS
911
+
912
+ // BEGIN: CALENDAR OBJECT FUNCTIONS
913
+
914
+ /**
915
+ * This function creates the calendar inside the given parent. If _par is
916
+ * null than it creates a popup calendar inside the BODY element. If _par is
917
+ * an element, be it BODY, then it creates a non-popup calendar (still
918
+ * hidden). Some properties need to be set before calling this function.
919
+ */
920
+ Calendar.prototype.create = function (_par) {
921
+ var parent = null;
922
+ if (! _par) {
923
+ // default parent is the document body, in which case we create
924
+ // a popup calendar.
925
+ parent = document.getElementsByTagName("body")[0];
926
+ this.isPopup = true;
927
+ } else {
928
+ parent = _par;
929
+ this.isPopup = false;
930
+ }
931
+ this.date = this.dateStr ? new Date(this.dateStr) : new Date();
932
+
933
+ var table = Calendar.createElement("table");
934
+ this.table = table;
935
+ table.cellSpacing = 0;
936
+ table.cellPadding = 0;
937
+ table.calendar = this;
938
+ Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
939
+
940
+ var div = Calendar.createElement("div");
941
+ this.element = div;
942
+ div.className = "calendar";
943
+ if (this.isPopup) {
944
+ div.style.position = this.opts.position_css;
945
+ div.style.display = "none";
946
+ div.style.zIndex = 10001;
947
+ }
948
+ div.appendChild(table);
949
+
950
+ var thead = Calendar.createElement("thead", table);
951
+ var cell = null;
952
+ var row = null;
953
+
954
+ var cal = this;
955
+ var hh = function (text, cs, navtype) {
956
+ cell = Calendar.createElement("td", row);
957
+ cell.colSpan = cs;
958
+ cell.className = "button";
959
+ if (navtype != 0 && Math.abs(navtype) <= 2)
960
+ cell.className += " nav";
961
+ Calendar._add_evs(cell);
962
+ cell.calendar = cal;
963
+ cell.navtype = navtype;
964
+ cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
965
+ return cell;
966
+ };
967
+
968
+ row = Calendar.createElement("tr", thead);
969
+ var title_length = 6;
970
+ (this.isPopup) && --title_length;
971
+ (this.weekNumbers) && ++title_length;
972
+
973
+ hh("?", 1, 400).ttip = Calendar._TT["INFO"];
974
+ this.title = hh("", title_length, 300);
975
+ this.title.className = "title";
976
+ if (this.isPopup) {
977
+ this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
978
+ this.title.style.cursor = "move";
979
+ hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
980
+ }
981
+
982
+ row = Calendar.createElement("tr", thead);
983
+ row.className = "headrow";
984
+
985
+ this._nav_py = hh("&#x00ab;", 1, -2);
986
+ this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
987
+
988
+ this._nav_pm = hh("&#x2039;", 1, -1);
989
+ this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
990
+
991
+ this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
992
+ this._nav_now.ttip = Calendar._TT["GO_TODAY"];
993
+
994
+ this._nav_nm = hh("&#x203a;", 1, 1);
995
+ this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
996
+
997
+ this._nav_ny = hh("&#x00bb;", 1, 2);
998
+ this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
999
+
1000
+ // day names
1001
+ row = Calendar.createElement("tr", thead);
1002
+ row.className = "daynames";
1003
+ if (this.weekNumbers) {
1004
+ cell = Calendar.createElement("td", row);
1005
+ cell.className = "name wn";
1006
+ cell.innerHTML = Calendar._TT["WK"];
1007
+ }
1008
+ for (var i = 7; i > 0; --i) {
1009
+ cell = Calendar.createElement("td", row);
1010
+ if (!i) {
1011
+ cell.navtype = 100;
1012
+ cell.calendar = this;
1013
+ Calendar._add_evs(cell);
1014
+ }
1015
+ }
1016
+ this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
1017
+ this._displayWeekdays();
1018
+
1019
+ var tbody = Calendar.createElement("tbody", table);
1020
+ this.tbody = tbody;
1021
+
1022
+ for (i = 6; i > 0; --i) {
1023
+ row = Calendar.createElement("tr", tbody);
1024
+ if (this.weekNumbers) {
1025
+ cell = Calendar.createElement("td", row);
1026
+ }
1027
+ for (var j = 7; j > 0; --j) {
1028
+ cell = Calendar.createElement("td", row);
1029
+ cell.calendar = this;
1030
+ Calendar._add_evs(cell);
1031
+ }
1032
+ }
1033
+
1034
+ if (this.showsTime) {
1035
+ row = Calendar.createElement("tr", tbody);
1036
+ row.className = "time";
1037
+
1038
+ cell = Calendar.createElement("td", row);
1039
+ cell.className = "time";
1040
+ cell.colSpan = 2;
1041
+ cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";
1042
+
1043
+ cell = Calendar.createElement("td", row);
1044
+ cell.className = "time";
1045
+ cell.colSpan = this.weekNumbers ? 4 : 3;
1046
+
1047
+ (function(){
1048
+ function makeTimePart(className, init, range_start, range_end) {
1049
+ var part = Calendar.createElement("span", cell);
1050
+ part.className = className;
1051
+ part.innerHTML = init;
1052
+ part.calendar = cal;
1053
+ part.ttip = Calendar._TT["TIME_PART"];
1054
+ part.navtype = 50;
1055
+ part._range = [];
1056
+ if (typeof range_start != "number")
1057
+ part._range = range_start;
1058
+ else {
1059
+ for (var i = range_start; i <= range_end; ++i) {
1060
+ var txt;
1061
+ if (i < 10 && range_end >= 10) txt = '0' + i;
1062
+ else txt = '' + i;
1063
+ part._range[part._range.length] = txt;
1064
+ }
1065
+ }
1066
+ Calendar._add_evs(part);
1067
+ return part;
1068
+ };
1069
+ var hrs = cal.date.getHours();
1070
+ var mins = cal.date.getMinutes();
1071
+ var t12 = !cal.time24;
1072
+ var pm = (hrs > 12);
1073
+ if (t12 && pm) hrs -= 12;
1074
+ var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
1075
+ var span = Calendar.createElement("span", cell);
1076
+ span.innerHTML = ":";
1077
+ span.className = "colon";
1078
+ var M = makeTimePart("minute", mins, 0, 59);
1079
+ var AP = null;
1080
+ cell = Calendar.createElement("td", row);
1081
+ cell.className = "time";
1082
+ cell.colSpan = 2;
1083
+ if (t12)
1084
+ AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
1085
+ else
1086
+ cell.innerHTML = "&nbsp;";
1087
+
1088
+ cal.onSetTime = function() {
1089
+ var pm, hrs = this.date.getHours(),
1090
+ mins = this.date.getMinutes();
1091
+ if (t12) {
1092
+ pm = (hrs >= 12);
1093
+ if (pm) hrs -= 12;
1094
+ if (hrs == 0) hrs = 12;
1095
+ AP.innerHTML = pm ? "pm" : "am";
1096
+ }
1097
+ H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
1098
+ M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
1099
+ };
1100
+
1101
+ cal.onUpdateTime = function() {
1102
+ var date = this.date;
1103
+ var h = parseInt(H.innerHTML, 10);
1104
+ if (t12) {
1105
+ if (/pm/i.test(AP.innerHTML) && h < 12)
1106
+ h += 12;
1107
+ else if (/am/i.test(AP.innerHTML) && h == 12)
1108
+ h = 0;
1109
+ }
1110
+ var d = date.getDate();
1111
+ var m = date.getMonth();
1112
+ var y = date.getFullYear();
1113
+ date.setHours(h);
1114
+ date.setMinutes(parseInt(M.innerHTML, 10));
1115
+ date.setFullYear(y);
1116
+ date.setMonth(m);
1117
+ date.setDate(d);
1118
+ this.dateClicked = false;
1119
+ this.callHandler();
1120
+ };
1121
+ })();
1122
+ } else {
1123
+ this.onSetTime = this.onUpdateTime = function() {};
1124
+ }
1125
+
1126
+ var tfoot = Calendar.createElement("tfoot", table);
1127
+
1128
+ row = Calendar.createElement("tr", tfoot);
1129
+ row.className = "footrow";
1130
+
1131
+ cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
1132
+ cell.className = "ttip";
1133
+ if (this.isPopup) {
1134
+ cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
1135
+ cell.style.cursor = "move";
1136
+ }
1137
+ this.tooltips = cell;
1138
+
1139
+ div = Calendar.createElement("div", this.element);
1140
+ this.monthsCombo = div;
1141
+ div.className = "combo";
1142
+ for (i = 0; i < Calendar._MN.length; ++i) {
1143
+ var mn = Calendar.createElement("div");
1144
+ mn.className = Calendar.is_ie ? "label-IEfix" : "label";
1145
+ mn.month = i;
1146
+ mn.innerHTML = Calendar._SMN[i];
1147
+ div.appendChild(mn);
1148
+ }
1149
+
1150
+ div = Calendar.createElement("div", this.element);
1151
+ this.yearsCombo = div;
1152
+ div.className = "combo";
1153
+ for (i = 12; i > 0; --i) {
1154
+ var yr = Calendar.createElement("div");
1155
+ yr.className = Calendar.is_ie ? "label-IEfix" : "label";
1156
+ div.appendChild(yr);
1157
+ }
1158
+
1159
+ this._init(this.firstDayOfWeek, this.date);
1160
+ parent.appendChild(this.element);
1161
+ };
1162
+
1163
+ /** keyboard navigation, only for popup calendars */
1164
+ Calendar._keyEvent = function(ev) {
1165
+ var cal = window._dynarch_popupCalendar;
1166
+ if (!cal || cal.multiple)
1167
+ return false;
1168
+ (Calendar.is_ie) && (ev = window.event);
1169
+ var act = (Calendar.is_ie || ev.type == "keypress"),
1170
+ K = ev.keyCode;
1171
+ if (ev.ctrlKey) {
1172
+ switch (K) {
1173
+ case 37: // KEY left
1174
+ act && Calendar.cellClick(cal._nav_pm);
1175
+ break;
1176
+ case 38: // KEY up
1177
+ act && Calendar.cellClick(cal._nav_py);
1178
+ break;
1179
+ case 39: // KEY right
1180
+ act && Calendar.cellClick(cal._nav_nm);
1181
+ break;
1182
+ case 40: // KEY down
1183
+ act && Calendar.cellClick(cal._nav_ny);
1184
+ break;
1185
+ default:
1186
+ return false;
1187
+ }
1188
+ } else switch (K) {
1189
+ case 32: // KEY space (now)
1190
+ Calendar.cellClick(cal._nav_now);
1191
+ break;
1192
+ case 27: // KEY esc
1193
+ act && cal.callCloseHandler();
1194
+ break;
1195
+ case 37: // KEY left
1196
+ case 38: // KEY up
1197
+ case 39: // KEY right
1198
+ case 40: // KEY down
1199
+ if (act) {
1200
+ var prev, x, y, ne, el, step;
1201
+ prev = K == 37 || K == 38;
1202
+ step = (K == 37 || K == 39) ? 1 : 7;
1203
+ function setVars() {
1204
+ el = cal.currentDateEl;
1205
+ var p = el.pos;
1206
+ x = p & 15;
1207
+ y = p >> 4;
1208
+ ne = cal.ar_days[y][x];
1209
+ };setVars();
1210
+ function prevMonth() {
1211
+ var date = new Date(cal.date);
1212
+ date.setDate(date.getDate() - step);
1213
+ cal.setDate(date);
1214
+ };
1215
+ function nextMonth() {
1216
+ var date = new Date(cal.date);
1217
+ date.setDate(date.getDate() + step);
1218
+ cal.setDate(date);
1219
+ };
1220
+ while (1) {
1221
+ switch (K) {
1222
+ case 37: // KEY left
1223
+ if (--x >= 0)
1224
+ ne = cal.ar_days[y][x];
1225
+ else {
1226
+ x = 6;
1227
+ K = 38;
1228
+ continue;
1229
+ }
1230
+ break;
1231
+ case 38: // KEY up
1232
+ if (--y >= 0)
1233
+ ne = cal.ar_days[y][x];
1234
+ else {
1235
+ prevMonth();
1236
+ setVars();
1237
+ }
1238
+ break;
1239
+ case 39: // KEY right
1240
+ if (++x < 7)
1241
+ ne = cal.ar_days[y][x];
1242
+ else {
1243
+ x = 0;
1244
+ K = 40;
1245
+ continue;
1246
+ }
1247
+ break;
1248
+ case 40: // KEY down
1249
+ if (++y < cal.ar_days.length)
1250
+ ne = cal.ar_days[y][x];
1251
+ else {
1252
+ nextMonth();
1253
+ setVars();
1254
+ }
1255
+ break;
1256
+ }
1257
+ break;
1258
+ }
1259
+ if (ne) {
1260
+ if (!ne.disabled)
1261
+ Calendar.cellClick(ne);
1262
+ else if (prev)
1263
+ prevMonth();
1264
+ else
1265
+ nextMonth();
1266
+ }
1267
+ }
1268
+ break;
1269
+ case 13: // KEY enter
1270
+ if (act)
1271
+ Calendar.cellClick(cal.currentDateEl, ev);
1272
+ break;
1273
+ default:
1274
+ return false;
1275
+ }
1276
+ return Calendar.stopEvent(ev);
1277
+ };
1278
+
1279
+ /**
1280
+ * (RE)Initializes the calendar to the given date and firstDayOfWeek
1281
+ */
1282
+ Calendar.prototype._init = function (firstDayOfWeek, date) {
1283
+ var today = new Date(),
1284
+ TY = today.getFullYear(),
1285
+ TM = today.getMonth(),
1286
+ TD = today.getDate();
1287
+ this.table.style.visibility = "hidden";
1288
+ var year = date.getFullYear();
1289
+ if (year < this.minYear) {
1290
+ year = this.minYear;
1291
+ date.setFullYear(year);
1292
+ } else if (year > this.maxYear) {
1293
+ year = this.maxYear;
1294
+ date.setFullYear(year);
1295
+ }
1296
+ this.firstDayOfWeek = firstDayOfWeek;
1297
+ this.date = new Date(date);
1298
+ var month = date.getMonth();
1299
+ var mday = date.getDate();
1300
+ var no_days = date.getMonthDays();
1301
+
1302
+ // calendar voodoo for computing the first day that would actually be
1303
+ // displayed in the calendar, even if it's from the previous month.
1304
+ // WARNING: this is magic. ;-)
1305
+ date.setDate(1);
1306
+ var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
1307
+ if (day1 < 0)
1308
+ day1 += 7;
1309
+ date.setDate(-day1);
1310
+ date.setDate(date.getDate() + 1);
1311
+
1312
+ var row = this.tbody.firstChild;
1313
+ var MN = Calendar._SMN[month];
1314
+ var ar_days = this.ar_days = new Array();
1315
+ var weekend = Calendar._TT["WEEKEND"];
1316
+ var dates = this.multiple ? (this.datesCells = {}) : null;
1317
+ for (var i = 0; i < 6; ++i, row = row.nextSibling) {
1318
+ var cell = row.firstChild;
1319
+ if (this.weekNumbers) {
1320
+ cell.className = "day wn";
1321
+ cell.innerHTML = date.getWeekNumber();
1322
+ cell = cell.nextSibling;
1323
+ }
1324
+ row.className = "daysrow";
1325
+ var hasdays = false, iday, dpos = ar_days[i] = [];
1326
+ for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
1327
+ iday = date.getDate();
1328
+ var wday = date.getDay();
1329
+ cell.className = "day";
1330
+ cell.pos = i << 4 | j;
1331
+ dpos[j] = cell;
1332
+ var current_month = (date.getMonth() == month);
1333
+ if (!current_month) {
1334
+ if (this.showsOtherMonths) {
1335
+ cell.className += " othermonth";
1336
+ cell.otherMonth = true;
1337
+ } else {
1338
+ cell.className = "emptycell";
1339
+ cell.innerHTML = "&nbsp;";
1340
+ cell.disabled = true;
1341
+ continue;
1342
+ }
1343
+ } else {
1344
+ cell.otherMonth = false;
1345
+ hasdays = true;
1346
+ }
1347
+ cell.disabled = false;
1348
+ cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
1349
+ if (dates)
1350
+ dates[date.print("%Y%m%d")] = cell;
1351
+ if (this.getDateStatus) {
1352
+ var status = this.getDateStatus(date, year, month, iday);
1353
+ if (this.getDateToolTip) {
1354
+ var toolTip = this.getDateToolTip(date, year, month, iday);
1355
+ if (toolTip)
1356
+ cell.title = toolTip;
1357
+ }
1358
+ if (status === true) {
1359
+ cell.className += " disabled";
1360
+ cell.disabled = true;
1361
+ } else {
1362
+ if (/disabled/i.test(status))
1363
+ cell.disabled = true;
1364
+ cell.className += " " + status;
1365
+ }
1366
+ }
1367
+ if (!cell.disabled) {
1368
+ cell.caldate = new Date(date);
1369
+ cell.ttip = "_";
1370
+ if (!this.multiple && current_month
1371
+ && iday == mday && this.hiliteToday) {
1372
+ cell.className += " selected";
1373
+ this.currentDateEl = cell;
1374
+ }
1375
+ if (date.getFullYear() == TY &&
1376
+ date.getMonth() == TM &&
1377
+ iday == TD) {
1378
+ cell.className += " today";
1379
+ cell.ttip += Calendar._TT["PART_TODAY"];
1380
+ }
1381
+ if (weekend.indexOf(wday.toString()) != -1)
1382
+ cell.className += cell.otherMonth ? " oweekend" : " weekend";
1383
+ }
1384
+ }
1385
+ if (!(hasdays || this.showsOtherMonths))
1386
+ row.className = "emptyrow";
1387
+ }
1388
+ this.title.innerHTML = Calendar._MN[month] + ", " + year;
1389
+ this.onSetTime();
1390
+ this.table.style.visibility = "visible";
1391
+ this._initMultipleDates();
1392
+ // PROFILE
1393
+ // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
1394
+ };
1395
+
1396
+ Calendar.prototype._initMultipleDates = function() {
1397
+ if (this.multiple) {
1398
+ for (var i in this.multiple) {
1399
+ var cell = this.datesCells[i];
1400
+ var d = this.multiple[i];
1401
+ if (!d)
1402
+ continue;
1403
+ if (cell)
1404
+ cell.className += " selected";
1405
+ }
1406
+ }
1407
+ };
1408
+
1409
+ Calendar.prototype._toggleMultipleDate = function(date) {
1410
+ if (this.multiple) {
1411
+ var ds = date.print("%Y%m%d");
1412
+ var cell = this.datesCells[ds];
1413
+ if (cell) {
1414
+ var d = this.multiple[ds];
1415
+ if (!d) {
1416
+ Calendar.addClass(cell, "selected");
1417
+ this.multiple[ds] = date;
1418
+ } else {
1419
+ Calendar.removeClass(cell, "selected");
1420
+ delete this.multiple[ds];
1421
+ }
1422
+ }
1423
+ }
1424
+ };
1425
+
1426
+ Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
1427
+ this.getDateToolTip = unaryFunction;
1428
+ };
1429
+
1430
+ /**
1431
+ * Calls _init function above for going to a certain date (but only if the
1432
+ * date is different than the currently selected one).
1433
+ */
1434
+ Calendar.prototype.setDate = function (date) {
1435
+ if (!date.equalsTo(this.date)) {
1436
+ this._init(this.firstDayOfWeek, date);
1437
+ }
1438
+ };
1439
+
1440
+ /**
1441
+ * Refreshes the calendar. Useful if the "disabledHandler" function is
1442
+ * dynamic, meaning that the list of disabled date can change at runtime.
1443
+ * Just * call this function if you think that the list of disabled dates
1444
+ * should * change.
1445
+ */
1446
+ Calendar.prototype.refresh = function () {
1447
+ this._init(this.firstDayOfWeek, this.date);
1448
+ };
1449
+
1450
+ /** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
1451
+ Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
1452
+ this._init(firstDayOfWeek, this.date);
1453
+ this._displayWeekdays();
1454
+ };
1455
+
1456
+ /**
1457
+ * Allows customization of what dates are enabled. The "unaryFunction"
1458
+ * parameter must be a function object that receives the date (as a JS Date
1459
+ * object) and returns a boolean value. If the returned value is true then
1460
+ * the passed date will be marked as disabled.
1461
+ */
1462
+ Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
1463
+ this.getDateStatus = unaryFunction;
1464
+ };
1465
+
1466
+ /** Customization of allowed year range for the calendar. */
1467
+ Calendar.prototype.setRange = function (a, z) {
1468
+ this.minYear = a;
1469
+ this.maxYear = z;
1470
+ };
1471
+
1472
+ /** Customization of CSS position for the calendar. */
1473
+ Calendar.prototype.setPositionCSS = function (s) {
1474
+ this.opts.position_css = s;
1475
+ };
1476
+
1477
+ /** Calls the first user handler (selectedHandler). */
1478
+ Calendar.prototype.callHandler = function () {
1479
+ if (this.onSelected) {
1480
+ this.onSelected(this, this.date.print(this.dateFormat));
1481
+ }
1482
+ };
1483
+
1484
+ /** Calls the second user handler (closeHandler). */
1485
+ Calendar.prototype.callCloseHandler = function () {
1486
+ if (this.onClose) {
1487
+ this.onClose(this);
1488
+ }
1489
+ this.hideShowCovered();
1490
+ };
1491
+
1492
+ /** Removes the calendar object from the DOM tree and destroys it. */
1493
+ Calendar.prototype.destroy = function () {
1494
+ var el = this.element.parentNode;
1495
+ el.removeChild(this.element);
1496
+ Calendar._C = null;
1497
+ window._dynarch_popupCalendar = null;
1498
+ };
1499
+
1500
+ /**
1501
+ * Moves the calendar element to a different section in the DOM tree (changes
1502
+ * its parent).
1503
+ */
1504
+ Calendar.prototype.reparent = function (new_parent) {
1505
+ var el = this.element;
1506
+ el.parentNode.removeChild(el);
1507
+ new_parent.appendChild(el);
1508
+ };
1509
+
1510
+ // This gets called when the user presses a mouse button anywhere in the
1511
+ // document, if the calendar is shown. If the click was outside the open
1512
+ // calendar this function closes it.
1513
+ Calendar._checkCalendar = function(ev) {
1514
+ var calendar = window._dynarch_popupCalendar;
1515
+ if (!calendar) {
1516
+ return false;
1517
+ }
1518
+ var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
1519
+ for (; el != null && el != calendar.element; el = el.parentNode);
1520
+ if (el == null) {
1521
+ // calls closeHandler which should hide the calendar.
1522
+ window._dynarch_popupCalendar.callCloseHandler();
1523
+ return Calendar.stopEvent(ev);
1524
+ }
1525
+ };
1526
+
1527
+ /** Shows the calendar. */
1528
+ Calendar.prototype.show = function () {
1529
+ var rows = this.table.getElementsByTagName("tr");
1530
+ for (var i = rows.length; i > 0;) {
1531
+ var row = rows[--i];
1532
+ Calendar.removeClass(row, "rowhilite");
1533
+ var cells = row.getElementsByTagName("td");
1534
+ for (var j = cells.length; j > 0;) {
1535
+ var cell = cells[--j];
1536
+ Calendar.removeClass(cell, "hilite");
1537
+ Calendar.removeClass(cell, "active");
1538
+ }
1539
+ }
1540
+ this.element.style.display = "block";
1541
+ this.hidden = false;
1542
+ if (this.isPopup) {
1543
+ window._dynarch_popupCalendar = this;
1544
+ Calendar.addEvent(document, "keydown", Calendar._keyEvent);
1545
+ Calendar.addEvent(document, "keypress", Calendar._keyEvent);
1546
+ Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
1547
+ }
1548
+ this.hideShowCovered();
1549
+ };
1550
+
1551
+ /**
1552
+ * Hides the calendar. Also removes any "hilite" from the class of any TD
1553
+ * element.
1554
+ */
1555
+ Calendar.prototype.hide = function () {
1556
+ if (this.isPopup) {
1557
+ Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
1558
+ Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
1559
+ Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
1560
+ }
1561
+ this.element.style.display = "none";
1562
+ this.hidden = true;
1563
+ this.hideShowCovered();
1564
+ };
1565
+
1566
+ /**
1567
+ * Shows the calendar at a given absolute position (beware that, depending on
1568
+ * the calendar element style -- position property -- this might be relative
1569
+ * to the parent's containing rectangle).
1570
+ */
1571
+ Calendar.prototype.showAt = function (x, y) {
1572
+ var s = this.element.style;
1573
+ s.left = x + "px";
1574
+ s.top = y + "px";
1575
+ this.show();
1576
+ };
1577
+
1578
+ /** Shows the calendar near a given element. */
1579
+ Calendar.prototype.showAtElement = function (el, opts) {
1580
+ var self = this;
1581
+ var p = Calendar.getAbsolutePos(el);
1582
+ if (!opts || typeof opts != "string") {
1583
+ this.showAt(p.x, p.y + el.offsetHeight);
1584
+ return true;
1585
+ }
1586
+ function fixPosition(box) {
1587
+ if (box.x < 0)
1588
+ box.x = 0;
1589
+ if (box.y < 0)
1590
+ box.y = 0;
1591
+ var cp = document.createElement("div");
1592
+ var s = cp.style;
1593
+ s.position = "absolute";
1594
+ s.right = s.bottom = s.width = s.height = "0px";
1595
+ document.body.appendChild(cp);
1596
+ var br = Calendar.getAbsolutePos(cp);
1597
+ document.body.removeChild(cp);
1598
+ if (Calendar.is_ie) {
1599
+ br.y += document.documentElement.scrollTop;
1600
+ br.x += document.documentElement.scrollLeft;
1601
+ } else {
1602
+ br.y += window.scrollY;
1603
+ br.x += window.scrollX;
1604
+ }
1605
+ var tmp = box.x + box.width - br.x;
1606
+ if (tmp > 0) box.x -= tmp;
1607
+ tmp = box.y + box.height - br.y;
1608
+ if (tmp > 0) box.y -= tmp;
1609
+ };
1610
+ this.element.style.display = "block";
1611
+ Calendar.continuation_for_the_fucking_khtml_browser = function() {
1612
+ var w = self.element.offsetWidth;
1613
+ var h = self.element.offsetHeight;
1614
+ self.element.style.display = "none";
1615
+ var valign = opts.substr(0, 1);
1616
+ var halign = "l";
1617
+ if (opts.length > 1) {
1618
+ halign = opts.substr(1, 1);
1619
+ }
1620
+ // vertical alignment
1621
+ switch (valign) {
1622
+ case "T": p.y -= h; break;
1623
+ case "B": p.y += el.offsetHeight; break;
1624
+ case "C": p.y += (el.offsetHeight - h) / 2; break;
1625
+ case "t": p.y += el.offsetHeight - h; break;
1626
+ case "b": break; // already there
1627
+ }
1628
+ // horizontal alignment
1629
+ switch (halign) {
1630
+ case "L": p.x -= w; break;
1631
+ case "R": p.x += el.offsetWidth; break;
1632
+ case "C": p.x += (el.offsetWidth - w) / 2; break;
1633
+ case "l": p.x += el.offsetWidth - w; break;
1634
+ case "r": break; // already there
1635
+ }
1636
+ p.width = w;
1637
+ p.height = h + 40;
1638
+ self.monthsCombo.style.display = "none";
1639
+ fixPosition(p);
1640
+ self.showAt(p.x, p.y);
1641
+ };
1642
+ if (Calendar.is_khtml)
1643
+ setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
1644
+ else
1645
+ Calendar.continuation_for_the_fucking_khtml_browser();
1646
+ };
1647
+
1648
+ /** Customizes the date format. */
1649
+ Calendar.prototype.setDateFormat = function (str) {
1650
+ this.dateFormat = str;
1651
+ };
1652
+
1653
+ /** Customizes the tooltip date format. */
1654
+ Calendar.prototype.setTtDateFormat = function (str) {
1655
+ this.ttDateFormat = str;
1656
+ };
1657
+
1658
+ /**
1659
+ * Tries to identify the date represented in a string. If successful it also
1660
+ * calls this.setDate which moves the calendar to the given date.
1661
+ */
1662
+ Calendar.prototype.parseDate = function(str, fmt) {
1663
+ if (!fmt)
1664
+ fmt = this.dateFormat;
1665
+ this.setDate(Date.parseDate(str, fmt));
1666
+ };
1667
+
1668
+ Calendar.prototype.hideShowCovered = function () {
1669
+ if (!Calendar.is_ie && !Calendar.is_opera)
1670
+ return;
1671
+ function getVisib(obj){
1672
+ var value = obj.style.visibility;
1673
+ if (!value) {
1674
+ if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
1675
+ if (!Calendar.is_khtml)
1676
+ value = document.defaultView.
1677
+ getComputedStyle(obj, "").getPropertyValue("visibility");
1678
+ else
1679
+ value = '';
1680
+ } else if (obj.currentStyle) { // IE
1681
+ value = obj.currentStyle.visibility;
1682
+ } else
1683
+ value = '';
1684
+ }
1685
+ return value;
1686
+ };
1687
+
1688
+ var tags = new Array("applet", "iframe", "select");
1689
+ var el = this.element;
1690
+
1691
+ var p = Calendar.getAbsolutePos(el);
1692
+ var EX1 = p.x;
1693
+ var EX2 = el.offsetWidth + EX1;
1694
+ var EY1 = p.y;
1695
+ var EY2 = el.offsetHeight + EY1;
1696
+
1697
+ for (var k = tags.length; k > 0; ) {
1698
+ var ar = document.getElementsByTagName(tags[--k]);
1699
+ var cc = null;
1700
+
1701
+ for (var i = ar.length; i > 0;) {
1702
+ cc = ar[--i];
1703
+
1704
+ p = Calendar.getAbsolutePos(cc);
1705
+ var CX1 = p.x;
1706
+ var CX2 = cc.offsetWidth + CX1;
1707
+ var CY1 = p.y;
1708
+ var CY2 = cc.offsetHeight + CY1;
1709
+
1710
+ if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
1711
+ if (!cc.__msh_save_visibility) {
1712
+ cc.__msh_save_visibility = getVisib(cc);
1713
+ }
1714
+ cc.style.visibility = cc.__msh_save_visibility;
1715
+ } else {
1716
+ if (!cc.__msh_save_visibility) {
1717
+ cc.__msh_save_visibility = getVisib(cc);
1718
+ }
1719
+ cc.style.visibility = "hidden";
1720
+ }
1721
+ }
1722
+ }
1723
+ };
1724
+
1725
+ /** Internal function; it displays the bar with the names of the weekday. */
1726
+ Calendar.prototype._displayWeekdays = function () {
1727
+ var fdow = this.firstDayOfWeek;
1728
+ var cell = this.firstdayname;
1729
+ var weekend = Calendar._TT["WEEKEND"];
1730
+ for (var i = 0; i < 7; ++i) {
1731
+ cell.className = "day name";
1732
+ var realday = (i + fdow) % 7;
1733
+ if (i) {
1734
+ cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
1735
+ cell.navtype = 100;
1736
+ cell.calendar = this;
1737
+ cell.fdow = realday;
1738
+ Calendar._add_evs(cell);
1739
+ }
1740
+ if (weekend.indexOf(realday.toString()) != -1) {
1741
+ Calendar.addClass(cell, "weekend");
1742
+ }
1743
+ cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
1744
+ cell = cell.nextSibling;
1745
+ }
1746
+ };
1747
+
1748
+ /** Internal function. Hides all combo boxes that might be displayed. */
1749
+ Calendar.prototype._hideCombos = function () {
1750
+ this.monthsCombo.style.display = "none";
1751
+ this.yearsCombo.style.display = "none";
1752
+ };
1753
+
1754
+ /** Internal function. Starts dragging the element. */
1755
+ Calendar.prototype._dragStart = function (ev) {
1756
+ if (this.dragging) {
1757
+ return;
1758
+ }
1759
+ this.dragging = true;
1760
+ var posX;
1761
+ var posY;
1762
+ if (Calendar.is_ie) {
1763
+ posY = window.event.clientY + document.body.scrollTop;
1764
+ posX = window.event.clientX + document.body.scrollLeft;
1765
+ } else {
1766
+ posY = ev.clientY + window.scrollY;
1767
+ posX = ev.clientX + window.scrollX;
1768
+ }
1769
+ var st = this.element.style;
1770
+ this.xOffs = posX - parseInt(st.left);
1771
+ this.yOffs = posY - parseInt(st.top);
1772
+ with (Calendar) {
1773
+ addEvent(document, "mousemove", calDragIt);
1774
+ addEvent(document, "mouseup", calDragEnd);
1775
+ }
1776
+ };
1777
+
1778
+ // BEGIN: DATE OBJECT PATCHES
1779
+
1780
+ /** Adds the number of days array to the Date object. */
1781
+ Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1782
+
1783
+ /** Constants used for time computations */
1784
+ Date.SECOND = 1000 /* milliseconds */;
1785
+ Date.MINUTE = 60 * Date.SECOND;
1786
+ Date.HOUR = 60 * Date.MINUTE;
1787
+ Date.DAY = 24 * Date.HOUR;
1788
+ Date.WEEK = 7 * Date.DAY;
1789
+
1790
+ Date.parseDate = function(str, fmt) {
1791
+ var today = new Date();
1792
+ var y = 0;
1793
+ var m = -1;
1794
+ var d = 0;
1795
+ var a = str.split(/\W+/);
1796
+ var b = fmt.match(/%./g);
1797
+ var i = 0, j = 0;
1798
+ var hr = 0;
1799
+ var min = 0;
1800
+ for (i = 0; i < a.length; ++i) {
1801
+ if (!a[i])
1802
+ continue;
1803
+ switch (b[i]) {
1804
+ case "%d":
1805
+ case "%e":
1806
+ d = parseInt(a[i], 10);
1807
+ break;
1808
+
1809
+ case "%F":
1810
+ case "%m":
1811
+ m = parseInt(a[i], 10) - 1;
1812
+ break;
1813
+
1814
+ case "%Y":
1815
+ case "%y":
1816
+ y = parseInt(a[i], 10);
1817
+ (y < 100) && (y += (y > 29) ? 1900 : 2000);
1818
+ break;
1819
+
1820
+ case "%b":
1821
+ case "%B":
1822
+ for (j = 0; j < 12; ++j) {
1823
+ if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
1824
+ }
1825
+ break;
1826
+ case "%H":
1827
+ case "%I":
1828
+ case "%k":
1829
+ case "%l":
1830
+ hr = parseInt(a[i], 10);
1831
+ break;
1832
+ case "%P":
1833
+ case "%p":
1834
+ if (/pm/i.test(a[i]) && hr < 12)
1835
+ hr += 12;
1836
+ else if (/am/i.test(a[i]) && hr >= 12)
1837
+ hr -= 12;
1838
+ break;
1839
+ case "%M":
1840
+ min = parseInt(a[i], 10);
1841
+ break;
1842
+ }
1843
+ }
1844
+ if (isNaN(y)) y = today.getFullYear();
1845
+ if (isNaN(m)) m = today.getMonth();
1846
+ if (isNaN(d)) d = today.getDate();
1847
+ if (isNaN(hr)) hr = today.getHours();
1848
+ if (isNaN(min)) min = today.getMinutes();
1849
+ if (y != 0 && m != -1 && d != 0)
1850
+ return new Date(y, m, d, hr, min, 0);
1851
+ y = 0; m = -1; d = 0;
1852
+ for (i = 0; i < a.length; ++i) {
1853
+ if (a[i].search(/[a-zA-Z]+/) != -1) {
1854
+ var t = -1;
1855
+ for (j = 0; j < 12; ++j) {
1856
+ if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
1857
+ }
1858
+ if (t != -1) {
1859
+ if (m != -1) {
1860
+ d = m+1;
1861
+ }
1862
+ m = t;
1863
+ }
1864
+ } else if (parseInt(a[i], 10) <= 12 && m == -1) {
1865
+ m = a[i]-1;
1866
+ } else if (parseInt(a[i], 10) > 31 && y == 0) {
1867
+ y = parseInt(a[i], 10);
1868
+ (y < 100) && (y += (y > 29) ? 1900 : 2000);
1869
+ } else if (d == 0) {
1870
+ d = a[i];
1871
+ }
1872
+ }
1873
+ if (y == 0)
1874
+ y = today.getFullYear();
1875
+ if (m != -1 && d != 0)
1876
+ return new Date(y, m, d, hr, min, 0);
1877
+ return today;
1878
+ };
1879
+
1880
+ /** Returns the number of days in the current month */
1881
+ Date.prototype.getMonthDays = function(month) {
1882
+ var year = this.getFullYear();
1883
+ if (typeof month == "undefined") {
1884
+ month = this.getMonth();
1885
+ }
1886
+ if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
1887
+ return 29;
1888
+ } else {
1889
+ return Date._MD[month];
1890
+ }
1891
+ };
1892
+
1893
+ /** Returns the number of day in the year. */
1894
+ Date.prototype.getDayOfYear = function() {
1895
+ var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1896
+ var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
1897
+ var time = now - then;
1898
+ return Math.floor(time / Date.DAY);
1899
+ };
1900
+
1901
+ /** Returns the number of the week in year, as defined in ISO 8601. */
1902
+ Date.prototype.getWeekNumber = function() {
1903
+ var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1904
+ var DoW = d.getDay();
1905
+ d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
1906
+ var ms = d.valueOf(); // GMT
1907
+ d.setMonth(0);
1908
+ d.setDate(4); // Thu in Week 1
1909
+ return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
1910
+ };
1911
+
1912
+ /** Checks date and time equality */
1913
+ Date.prototype.equalsTo = function(date) {
1914
+ return ((this.getFullYear() == date.getFullYear()) &&
1915
+ (this.getMonth() == date.getMonth()) &&
1916
+ (this.getDate() == date.getDate()) &&
1917
+ (this.getHours() == date.getHours()) &&
1918
+ (this.getMinutes() == date.getMinutes()));
1919
+ };
1920
+
1921
+ /** Set only the year, month, date parts (keep existing time) */
1922
+ Date.prototype.setDateOnly = function(date) {
1923
+ var tmp = new Date(date);
1924
+ this.setDate(1);
1925
+ this.setFullYear(tmp.getFullYear());
1926
+ this.setMonth(tmp.getMonth());
1927
+ this.setDate(tmp.getDate());
1928
+ };
1929
+
1930
+ /** Prints the date in a string according to the given format. */
1931
+ Date.prototype.print = function (str) {
1932
+ var m = this.getMonth();
1933
+ var d = this.getDate();
1934
+ var y = this.getFullYear();
1935
+ var wn = this.getWeekNumber();
1936
+ var w = this.getDay();
1937
+ var s = {};
1938
+ var hr = this.getHours();
1939
+ var pm = (hr >= 12);
1940
+ var ir = (pm) ? (hr - 12) : hr;
1941
+ var dy = this.getDayOfYear();
1942
+ if (ir == 0)
1943
+ ir = 12;
1944
+ var min = this.getMinutes();
1945
+ var sec = this.getSeconds();
1946
+ s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
1947
+ s["%A"] = Calendar._DN[w]; // full weekday name
1948
+ s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
1949
+ s["%B"] = Calendar._MN[m]; // full month name
1950
+ // FIXME: %c : preferred date and time representation for the current locale
1951
+ s["%C"] = 1 + Math.floor(y / 100); // the century number
1952
+ s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
1953
+ s["%e"] = d; // the day of the month (range 1 to 31)
1954
+ // FIXME: %D : american date style: %m/%d/%y
1955
+ // FIXME: %E, %F, %G, %g, %h (man strftime)
1956
+ s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
1957
+ s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
1958
+ s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
1959
+ s["%k"] = hr; // hour, range 0 to 23 (24h format)
1960
+ s["%l"] = ir; // hour, range 1 to 12 (12h format)
1961
+ s["%F"] = 1+m; // month, range 1 to 12
1962
+ s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
1963
+ s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
1964
+ s["%n"] = "\n"; // a newline character
1965
+ s["%p"] = pm ? "PM" : "AM";
1966
+ s["%P"] = pm ? "pm" : "am";
1967
+ // FIXME: %r : the time in am/pm notation %I:%M:%S %p
1968
+ // FIXME: %R : the time in 24-hour notation %H:%M
1969
+ s["%s"] = Math.floor(this.getTime() / 1000);
1970
+ s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
1971
+ s["%t"] = "\t"; // a tab character
1972
+ // FIXME: %T : the time in 24-hour notation (%H:%M:%S)
1973
+ s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
1974
+ s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
1975
+ s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
1976
+ // FIXME: %x : preferred date representation for the current locale without the time
1977
+ // FIXME: %X : preferred time representation for the current locale without the date
1978
+ s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
1979
+ s["%Y"] = y; // year with the century
1980
+ s["%%"] = "%"; // a literal '%' character
1981
+
1982
+ var re = /%./g;
1983
+ if (!Calendar.is_ie5 && !Calendar.is_khtml)
1984
+ return str.replace(re, function (par) { return s[par] || par; });
1985
+
1986
+ var a = str.match(re);
1987
+ for (var i = 0; i < a.length; i++) {
1988
+ var tmp = s[a[i]];
1989
+ if (tmp) {
1990
+ re = new RegExp(a[i], 'g');
1991
+ str = str.replace(re, tmp);
1992
+ }
1993
+ }
1994
+
1995
+ return str;
1996
+ };
1997
+
1998
+ Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
1999
+ Date.prototype.setFullYear = function(y) {
2000
+ var d = new Date(this);
2001
+ d.__msh_oldSetFullYear(y);
2002
+ if (d.getMonth() != this.getMonth())
2003
+ this.setDate(28);
2004
+ this.__msh_oldSetFullYear(y);
2005
+ };
2006
+
2007
+ // END: DATE OBJECT PATCHES
2008
+
2009
+
2010
+ // global object that remembers the calendar
2011
+ window._dynarch_popupCalendar = null;