wice_grid_mongoid 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/CHANGELOG +409 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +1172 -0
- data/Rakefile +42 -0
- data/SAVED_QUERIES_HOWTO.rdoc +123 -0
- data/VERSION +1 -0
- data/generators/common_templates/icons/arrow_down.gif +0 -0
- data/generators/common_templates/icons/arrow_up.gif +0 -0
- data/generators/common_templates/icons/calendar_view_month.png +0 -0
- data/generators/common_templates/icons/delete.png +0 -0
- data/generators/common_templates/icons/expand.png +0 -0
- data/generators/common_templates/icons/page_white_excel.png +0 -0
- data/generators/common_templates/icons/page_white_find.png +0 -0
- data/generators/common_templates/icons/table.png +0 -0
- data/generators/common_templates/icons/table_refresh.png +0 -0
- data/generators/common_templates/icons/tick_all.png +0 -0
- data/generators/common_templates/icons/untick_all.png +0 -0
- data/generators/common_templates/initializers/wice_grid_config.rb +215 -0
- data/generators/common_templates/locales/wice_grid.yml +269 -0
- data/generators/common_templates/stylesheets/wice_grid.css +173 -0
- data/generators/wice_grid_assets_jquery/templates/USAGE +6 -0
- data/generators/wice_grid_assets_jquery/templates/javascripts/wice_grid_jquery.js +161 -0
- data/generators/wice_grid_assets_jquery/wice_grid_assets_jquery_generator.rb +35 -0
- data/generators/wice_grid_assets_prototype/USAGE +8 -0
- data/generators/wice_grid_assets_prototype/templates/javascripts/calendarview.js +1168 -0
- data/generators/wice_grid_assets_prototype/templates/javascripts/wice_grid_prototype.js +153 -0
- data/generators/wice_grid_assets_prototype/templates/stylesheets/calendarview.css +107 -0
- data/generators/wice_grid_assets_prototype/wice_grid_assets_prototype_generator.rb +37 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/grid_output_buffer.rb +52 -0
- data/lib/grid_renderer.rb +531 -0
- data/lib/helpers/js_calendar_helpers.rb +188 -0
- data/lib/helpers/wice_grid_misc_view_helpers.rb +113 -0
- data/lib/helpers/wice_grid_serialized_queries_view_helpers.rb +82 -0
- data/lib/helpers/wice_grid_view_helpers.rb +781 -0
- data/lib/js_adaptors/jquery_adaptor.rb +145 -0
- data/lib/js_adaptors/js_adaptor.rb +12 -0
- data/lib/js_adaptors/prototype_adaptor.rb +168 -0
- data/lib/table_column_matrix.rb +51 -0
- data/lib/view_columns.rb +469 -0
- data/lib/views/create.rjs +13 -0
- data/lib/views/delete.rjs +12 -0
- data/lib/wice_grid.rb +809 -0
- data/lib/wice_grid_controller.rb +165 -0
- data/lib/wice_grid_core_ext.rb +179 -0
- data/lib/wice_grid_misc.rb +99 -0
- data/lib/wice_grid_serialized_queries_controller.rb +77 -0
- data/lib/wice_grid_serialized_query.rb +14 -0
- data/lib/wice_grid_spreadsheet.rb +33 -0
- data/tasks/wice_grid_tasks.rake +28 -0
- data/test/.gitignore +2 -0
- data/test/database.yml +21 -0
- data/test/schema.rb +33 -0
- data/test/test_helper.rb +89 -0
- data/test/views/projects_and_people_grid.html.erb +12 -0
- data/test/views/projects_and_people_grid_invalid.html.erb +12 -0
- data/test/views/simple_projects_grid.html.erb +9 -0
- data/test/wice_grid_core_ext_test.rb +183 -0
- data/test/wice_grid_functional_test.rb +68 -0
- data/test/wice_grid_misc_test.rb +41 -0
- data/test/wice_grid_test.rb +42 -0
- data/test/wice_grid_view_helper_test.rb +12 -0
- data/uninstall.rb +1 -0
- data/wice_grid_mongoid.gemspec +111 -0
- metadata +141 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
/* This is just an example, so feel free to re-style it completely */
|
2
|
+
|
3
|
+
.wice_grid {
|
4
|
+
border: 1px solid #ccc;
|
5
|
+
border-collapse: collapse;
|
6
|
+
border-spacing: 0px
|
7
|
+
}
|
8
|
+
|
9
|
+
.wice_grid .clickable{
|
10
|
+
cursor: pointer;
|
11
|
+
}
|
12
|
+
|
13
|
+
.wice_grid th {
|
14
|
+
background-color: #dfdfdf;
|
15
|
+
font-weight: bold;
|
16
|
+
text-shadow: rgb(204, 204, 204) 0px 1px 0px;
|
17
|
+
height: 2em;
|
18
|
+
padding: 0 1em;
|
19
|
+
|
20
|
+
}
|
21
|
+
.wice_grid th a {
|
22
|
+
color: #000;
|
23
|
+
}
|
24
|
+
.wice_grid th a:hover {
|
25
|
+
color: #333;
|
26
|
+
}
|
27
|
+
|
28
|
+
.wice_grid tr.wice_grid_title_row th,
|
29
|
+
.wice_grid tr.wice_grid_filter_row th{
|
30
|
+
background-color: #dddddd;
|
31
|
+
vertical-align: top;
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
.wice_grid th.filter_icons, .wice_grid th.hide_show_icon {
|
37
|
+
text-align: right ;
|
38
|
+
}
|
39
|
+
|
40
|
+
.wice_grid thead {
|
41
|
+
border-bottom: 1px solid #666;
|
42
|
+
}
|
43
|
+
|
44
|
+
.wice_grid tr.odd {
|
45
|
+
background-color: #fff;
|
46
|
+
}
|
47
|
+
|
48
|
+
.wice_grid tr.even {
|
49
|
+
background-color: #eeeeee;
|
50
|
+
}
|
51
|
+
|
52
|
+
.wice_grid td {
|
53
|
+
border-bottom: 1px dotted #9999CC;
|
54
|
+
height: 2.5em;
|
55
|
+
padding: 0 1em;
|
56
|
+
}
|
57
|
+
|
58
|
+
.wice_grid .desc, .wice_grid .asc{
|
59
|
+
padding-right: 18px;
|
60
|
+
text-decoration:none;
|
61
|
+
}
|
62
|
+
|
63
|
+
.wice_grid .desc {
|
64
|
+
background: transparent url(/images/icons/grid/arrow_down.gif) right no-repeat
|
65
|
+
}
|
66
|
+
.wice_grid .asc {
|
67
|
+
background: transparent url(/images/icons/grid/arrow_up.gif) right no-repeat
|
68
|
+
}
|
69
|
+
|
70
|
+
.wice_grid th div.date-filter {
|
71
|
+
text-align: left;
|
72
|
+
}
|
73
|
+
|
74
|
+
.wice_grid tr.even td.active_filter { background-color: #ddddff; }
|
75
|
+
.wice_grid tr.odd td.active_filter { background-color: #eeeeff; }
|
76
|
+
|
77
|
+
.wice_grid tr.even td.sorted { background-color: #ffffcc; }
|
78
|
+
.wice_grid tr.odd td.sorted { background-color: #ffffee; }
|
79
|
+
|
80
|
+
|
81
|
+
.wice_grid a.date_label {text-decoration: none;}
|
82
|
+
.wice_grid a.date_label:hover {text-decoration: line-through;}
|
83
|
+
|
84
|
+
.wice_grid td.sel{
|
85
|
+
text-align: center;
|
86
|
+
}
|
87
|
+
|
88
|
+
.wice_grid_container .pagination {
|
89
|
+
float: left;
|
90
|
+
}
|
91
|
+
|
92
|
+
.wice_grid_container .pagination_status {
|
93
|
+
font-weight: bold;
|
94
|
+
float: right;
|
95
|
+
}
|
96
|
+
|
97
|
+
.wice_grid_container .pagination_status .show_all_link a {
|
98
|
+
text-decoration: none;
|
99
|
+
font-size: 80%;
|
100
|
+
}
|
101
|
+
|
102
|
+
.wice_grid .custom_dropdown_container { position: relative; padding-right: 9px;}
|
103
|
+
.wice_grid .custom_dropdown_container .toggle_multi_select_icon { position:absolute; top:0; right:0; }
|
104
|
+
|
105
|
+
.wice_grid .text_filter_container { position: relative; padding-right: 13px;}
|
106
|
+
.wice_grid .text_filter_container .negation_checkbox { position:absolute; top:0; right:0; }
|
107
|
+
|
108
|
+
|
109
|
+
/* Saved Queries */
|
110
|
+
|
111
|
+
.wice_grid_container h3 {
|
112
|
+
font-family: 'Lucida Grande';
|
113
|
+
font-size: 16px;
|
114
|
+
font-style: normal;
|
115
|
+
font-weight: bold;
|
116
|
+
margin-bottom: 2px;
|
117
|
+
}
|
118
|
+
|
119
|
+
.wice_grid_query_panel {
|
120
|
+
width: 400px;
|
121
|
+
border:1px solid #ddd;
|
122
|
+
margin-top : 10px;
|
123
|
+
margin-bottom : 10px;
|
124
|
+
padding : 5px;
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
.wice_grid_query_panel .query_list{
|
129
|
+
list-style-image: none;
|
130
|
+
list-style-position: outside;
|
131
|
+
list-style-type: none;
|
132
|
+
margin-left : 0px;
|
133
|
+
}
|
134
|
+
|
135
|
+
.wice_grid_query_panel .query_list li a.query_load_link {
|
136
|
+
text-decoration: none;
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
.wice_grid_query_panel .query_list li a.current {
|
141
|
+
font-weight: bold;
|
142
|
+
text-decoration: underline;
|
143
|
+
}
|
144
|
+
|
145
|
+
|
146
|
+
.wice_grid_query_panel .query_list li a.query_load_link:hover {
|
147
|
+
text-decoration: underline;
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
.wice_grid_query_panel .wice_grid_notice {
|
152
|
+
padding:.4em;
|
153
|
+
margin-bottom:1em;
|
154
|
+
border:2px solid #ddd;
|
155
|
+
background:#FFF6BF;
|
156
|
+
color:#514721;
|
157
|
+
border-color:#FFD324;
|
158
|
+
}
|
159
|
+
|
160
|
+
|
161
|
+
.wice_grid_query_panel .errorExplanation {
|
162
|
+
padding:.4em;
|
163
|
+
margin-bottom:1em;
|
164
|
+
border:2px solid #ddd;
|
165
|
+
background:#FBE3E4;
|
166
|
+
color:#8a1f11;
|
167
|
+
border-color:#FBC2C4;
|
168
|
+
list-style-image: none;
|
169
|
+
list-style-position: outside;
|
170
|
+
list-style-type: none;
|
171
|
+
margin-left : 0px;
|
172
|
+
}
|
173
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
function WiceGridProcessor(name, base_request_for_filter, base_link_for_show_all_records,
|
2
|
+
link_for_export, parameter_name_for_query_loading, parameter_name_for_focus, environment){
|
3
|
+
|
4
|
+
this.checkIfJsFrameworkIsLoaded = function(){
|
5
|
+
if (! jQuery){
|
6
|
+
alert("jQuery not loaded, WiceGrid cannot proceed!")
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
this.checkIfJsFrameworkIsLoaded();
|
11
|
+
this.name = name;
|
12
|
+
this.parameter_name_for_query_loading = parameter_name_for_query_loading;
|
13
|
+
this.parameter_name_for_focus = parameter_name_for_focus;
|
14
|
+
this.base_request_for_filter = base_request_for_filter;
|
15
|
+
this.base_link_for_show_all_records = base_link_for_show_all_records;
|
16
|
+
this.link_for_export = link_for_export;
|
17
|
+
this.filter_declarations = new Array();
|
18
|
+
this.environment = environment;
|
19
|
+
|
20
|
+
this.toString = function(){
|
21
|
+
return "<WiceGridProcessor instance for grid '" + this.name + "'>";
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
this.process = function(dom_id_to_focus){
|
26
|
+
window.location = this.build_url_with_params(dom_id_to_focus);
|
27
|
+
}
|
28
|
+
|
29
|
+
this.reload_page_for_given_grid_state = function(grid_state){
|
30
|
+
var request_path = this.grid_state_to_request(grid_state);
|
31
|
+
window.location = this.append_to_url(this.base_link_for_show_all_records, request_path);
|
32
|
+
}
|
33
|
+
|
34
|
+
this.load_query = function(query_id){
|
35
|
+
var request = this.append_to_url(this.build_url_with_params(),
|
36
|
+
(this.parameter_name_for_query_loading + encodeURIComponent(query_id)));
|
37
|
+
window.location = request;
|
38
|
+
}
|
39
|
+
|
40
|
+
this.save_query = function(query_name, base_path_to_query_controller, grid_state, input_ids){
|
41
|
+
if (input_ids instanceof Array) {
|
42
|
+
input_ids.each(function(dom_id){
|
43
|
+
grid_state.push(['extra[' + dom_id + ']', $('#'+ dom_id)[0].value])
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
var request_path = this.grid_state_to_request(grid_state);
|
48
|
+
|
49
|
+
jQuery.ajax({
|
50
|
+
url: base_path_to_query_controller,
|
51
|
+
async: true,
|
52
|
+
data: request_path + '&query_name=' + encodeURIComponent(query_name),
|
53
|
+
dataType: 'script',
|
54
|
+
type: 'POST'
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
this.grid_state_to_request = function(grid_state){
|
59
|
+
return jQuery.map(grid_state, function(pair){
|
60
|
+
return encodeURIComponent(pair[0]) + '=' + encodeURIComponent(pair[1]);
|
61
|
+
}).join('&');
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
this.append_to_url = function(url, str){
|
66
|
+
var sep;
|
67
|
+
if (url.indexOf('?') != -1){
|
68
|
+
if (/[&\?]$/.exec(url)){
|
69
|
+
sep = '';
|
70
|
+
}else{
|
71
|
+
sep = '&';
|
72
|
+
}
|
73
|
+
}else{
|
74
|
+
sep = '?';
|
75
|
+
}
|
76
|
+
return url + sep + str;
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
this.build_url_with_params = function(dom_id_to_focus){
|
81
|
+
var results = new Array();
|
82
|
+
var _this = this;
|
83
|
+
jQuery.each(this.filter_declarations, function(i, filter_declaration){
|
84
|
+
param = _this.read_values_and_form_query_string(
|
85
|
+
filter_declaration.filter_name, filter_declaration.detached,
|
86
|
+
filter_declaration.templates, filter_declaration.ids);
|
87
|
+
if (param && param != ''){
|
88
|
+
results.push(param);
|
89
|
+
}
|
90
|
+
});
|
91
|
+
|
92
|
+
var res = this.base_request_for_filter;
|
93
|
+
if ( results.length != 0){
|
94
|
+
all_filter_params = results.join('&');
|
95
|
+
res = this.append_to_url(res, all_filter_params);
|
96
|
+
}
|
97
|
+
if (dom_id_to_focus){
|
98
|
+
res = this.append_to_url(res, this.parameter_name_for_focus + dom_id_to_focus);
|
99
|
+
}
|
100
|
+
return res;
|
101
|
+
}
|
102
|
+
|
103
|
+
this.reset = function(){
|
104
|
+
window.location = this.base_request_for_filter;
|
105
|
+
}
|
106
|
+
|
107
|
+
this.export_to_csv = function(){
|
108
|
+
window.location = this.link_for_export;
|
109
|
+
}
|
110
|
+
|
111
|
+
this.register = function(func){
|
112
|
+
this.filter_declarations.push(func);
|
113
|
+
}
|
114
|
+
|
115
|
+
this.read_values_and_form_query_string = function(filter_name, detached, templates, ids){
|
116
|
+
var res = new Array();
|
117
|
+
for(i = 0; i < templates.length; i++){
|
118
|
+
if($(ids[i]) == null){
|
119
|
+
if (this.environment == "development"){
|
120
|
+
message = 'WiceGrid: Error reading state of filter "' + filter_name + '". No DOM element with id "' + ids[i] + '" found.'
|
121
|
+
if (detached){
|
122
|
+
message += 'You have declared "' + filter_name +
|
123
|
+
'" as a detached filter but have not output it anywhere in the template. Read documentation about detached filters.'
|
124
|
+
}
|
125
|
+
alert(message);
|
126
|
+
}
|
127
|
+
return '';
|
128
|
+
}
|
129
|
+
var el = $('#' + ids[i]);
|
130
|
+
var val;
|
131
|
+
if (el[0] && el[0].type == 'checkbox'){
|
132
|
+
if (el[0].checked) val = 1;
|
133
|
+
} else {
|
134
|
+
val = el.val();
|
135
|
+
}
|
136
|
+
if (val instanceof Array) {
|
137
|
+
for(j = 0; j < val.length; j++){
|
138
|
+
if (val[j] && val[j] != "")
|
139
|
+
res.push(templates[i] + encodeURIComponent(val[j]));
|
140
|
+
}
|
141
|
+
} else if (val && val != ''){
|
142
|
+
res.push(templates[i] + encodeURIComponent(val));
|
143
|
+
}
|
144
|
+
}
|
145
|
+
return res.join('&');
|
146
|
+
}
|
147
|
+
|
148
|
+
};
|
149
|
+
|
150
|
+
function toggle_multi_select(select_id, link_obj, expand_label, collapse_label) {
|
151
|
+
var select = $('#' + select_id)[0];
|
152
|
+
if (select.multiple == true) {
|
153
|
+
select.multiple = false;
|
154
|
+
link_obj.title = expand_label;
|
155
|
+
} else {
|
156
|
+
select.multiple = true;
|
157
|
+
link_obj.title = collapse_label;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
WiceGridProcessor._version = '0.4.3';
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class WiceGridAssetsJqueryGenerator < Rails::Generator::Base
|
2
|
+
def active_js_framework
|
3
|
+
'jquery'
|
4
|
+
end
|
5
|
+
def inactive_js_framework
|
6
|
+
'prototype'
|
7
|
+
end
|
8
|
+
|
9
|
+
def manifest
|
10
|
+
record do |m|
|
11
|
+
# wice_grid config
|
12
|
+
m.directory "config/initializers"
|
13
|
+
@active_js_framework = 'jquery'
|
14
|
+
@inactive_js_framework = 'prototype'
|
15
|
+
m.template "../../common_templates/initializers/wice_grid_config.rb", "config/initializers/wice_grid_config.rb"
|
16
|
+
|
17
|
+
# wice_grid locales
|
18
|
+
m.directory "config/locales"
|
19
|
+
m.file "../../common_templates/locales/wice_grid.yml", "config/locales/wice_grid.yml"
|
20
|
+
|
21
|
+
# wice_grid js & css
|
22
|
+
m.file "javascripts/wice_grid_jquery.js", "public/javascripts/wice_grid.js"
|
23
|
+
m.file "../../common_templates/stylesheets/wice_grid.css", "public/stylesheets/wice_grid.css"
|
24
|
+
|
25
|
+
# images
|
26
|
+
m.directory "public/images/icons/grid"
|
27
|
+
|
28
|
+
%w(arrow_down.gif calendar_view_month.png expand.png page_white_find.png table_refresh.png
|
29
|
+
arrow_up.gif delete.png page_white_excel.png table.png tick_all.png untick_all.png ).each do |f|
|
30
|
+
m.file "../../common_templates/icons/#{f}", "public/images/icons/grid/#{f}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Description:
|
2
|
+
Copies
|
3
|
+
configuration file wice_grid_config.rb to config/initializers/
|
4
|
+
wice_grid_prototype.js to public/javascripts/wice_grid.js
|
5
|
+
wice_grid.css to public/stylesheets/
|
6
|
+
calendarview.js to public/javascripts/
|
7
|
+
calendarview.css to public/stylesheets/
|
8
|
+
wice_grid images to public/images/icons/grid
|
@@ -0,0 +1,1168 @@
|
|
1
|
+
//
|
2
|
+
// CalendarView (for Prototype)
|
3
|
+
// calendarview.org
|
4
|
+
//
|
5
|
+
// Maintained by Justin Mecham <justin@aspect.net>
|
6
|
+
//
|
7
|
+
// Portions Copyright 2002-2005 Mihai Bazon
|
8
|
+
//
|
9
|
+
// This calendar is based very loosely on the Dynarch Calendar in that it was
|
10
|
+
// used as a base, but completely gutted and more or less rewritten in place
|
11
|
+
// to use the Prototype JavaScript library.
|
12
|
+
//
|
13
|
+
// As such, CalendarView is licensed under the terms of the GNU Lesser General
|
14
|
+
// Public License (LGPL). More information on the Dynarch Calendar can be
|
15
|
+
// found at:
|
16
|
+
//
|
17
|
+
// www.dynarch.com/projects/calendar
|
18
|
+
//
|
19
|
+
|
20
|
+
|
21
|
+
/* This fork by Yuri Leikind ( git://github.com/leikind/calendarview.git ) adds a number of features.
|
22
|
+
|
23
|
+
The differences from the original are
|
24
|
+
|
25
|
+
* Support for time in the form of two dropdowns for hours and minutes. Can be turned off/on.
|
26
|
+
* Draggable popup calendars (which introduces new dependancies: script.aculo.us effects.js and dragdrop.js)
|
27
|
+
* Close button
|
28
|
+
* Ability to unset the date by clicking on the active date
|
29
|
+
* Simple I18n support
|
30
|
+
* Removed all ambiguity in the API
|
31
|
+
* Two strategies in positioning of popup calendars: relative to the popup trigger element (original behavior),
|
32
|
+
and is relative to the mouse pointer (can be configured)
|
33
|
+
* Popup calendars are not created every time they pop up, on the contrary, they are created once just like
|
34
|
+
embedded calendars, and then shown or hidden.
|
35
|
+
* Possible to have many popup calendars on page. The behavior of the original calendarview when a popup
|
36
|
+
calendar is hidden when the user clicks elsewhere on the page is an option now.
|
37
|
+
* Refactoring and changes to the OO design like getting rid of Calendar.prototype in favor of class based
|
38
|
+
OO provided by OO, and getting rid of Calendar.setup({}) in favor of a simple object constructor new Calendar({}).
|
39
|
+
|
40
|
+
*/
|
41
|
+
|
42
|
+
var Calendar = Class.create({
|
43
|
+
|
44
|
+
container: null,
|
45
|
+
|
46
|
+
minYear: 1900,
|
47
|
+
maxYear: 2100,
|
48
|
+
|
49
|
+
date: new Date(),
|
50
|
+
currentDateElement: null,
|
51
|
+
|
52
|
+
shouldClose: false,
|
53
|
+
isPopup: true,
|
54
|
+
|
55
|
+
initialize: function(params){
|
56
|
+
|
57
|
+
if (! Calendar.init_done){
|
58
|
+
Calendar.init();
|
59
|
+
}
|
60
|
+
|
61
|
+
embedAt = params.embedAt || null;
|
62
|
+
withTime = params.withTime || null;
|
63
|
+
dateFormat = params.dateFormat || null;
|
64
|
+
initialDate = params.initialDate || null;
|
65
|
+
popupTriggerElement = params.popupTriggerElement || null;
|
66
|
+
this.onHideCallback = params.onHideCallback || function(date, calendar){};
|
67
|
+
this.onDateChangedCallback = params.onDateChangedCallback || function(date, calendar){};
|
68
|
+
this.minuteStep = params.minuteStep || 5;
|
69
|
+
this.hideOnClickOnDay = params.hideOnClickOnDay || false;
|
70
|
+
this.hideOnClickElsewhere = params.hideOnClickElsewhere || false;
|
71
|
+
this.outputFields = params.outputFields || $A();
|
72
|
+
this.popupPositioningStrategy = params.popupPositioningStrategy || 'trigger'; // or 'pointer'
|
73
|
+
this.x = params.x || 0;
|
74
|
+
this.y = params.y || 0.6;
|
75
|
+
|
76
|
+
this.outputFields = $A(this.outputFields).collect(function(f){
|
77
|
+
return $(f);
|
78
|
+
});
|
79
|
+
|
80
|
+
if (embedAt){
|
81
|
+
this.embedAt = $(embedAt);
|
82
|
+
this.embedAt._calendar = this;
|
83
|
+
}else{
|
84
|
+
this.embedAt = null;
|
85
|
+
}
|
86
|
+
|
87
|
+
this.withTime = withTime;
|
88
|
+
|
89
|
+
if (dateFormat){
|
90
|
+
this.dateFormat = dateFormat;
|
91
|
+
}else{
|
92
|
+
if(this.withTime){
|
93
|
+
this.dateFormat = Calendar.defaultDateTimeFormat;
|
94
|
+
}else{
|
95
|
+
this.dateFormat = Calendar.defaultDateFormat;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
this.dateFormatForHiddenField = params.dateFormatForHiddenField || this.dateFormat;
|
100
|
+
|
101
|
+
|
102
|
+
if (initialDate) {
|
103
|
+
this.date = this.parseDate(initialDate);
|
104
|
+
}
|
105
|
+
|
106
|
+
this.build();
|
107
|
+
|
108
|
+
if (this.isPopup) { //Popup Calendars
|
109
|
+
var popupTriggerElement = $(popupTriggerElement);
|
110
|
+
popupTriggerElement._calendar = this;
|
111
|
+
|
112
|
+
popupTriggerElement.observe('click', function(event){
|
113
|
+
this.showAtElement(event, popupTriggerElement);
|
114
|
+
}.bind(this) );
|
115
|
+
|
116
|
+
} else{ // In-Page Calendar
|
117
|
+
this.show();
|
118
|
+
}
|
119
|
+
|
120
|
+
if (params.updateOuterFieldsOnInit){
|
121
|
+
this.updateOuterFieldWithoutCallback(); // Just for the sake of localization and DatePicker
|
122
|
+
}
|
123
|
+
},
|
124
|
+
|
125
|
+
build: function(){
|
126
|
+
if (this.embedAt) {
|
127
|
+
var parentForCalendarTable = this.embedAt;
|
128
|
+
this.isPopup = false;
|
129
|
+
} else {
|
130
|
+
var parentForCalendarTable = document.getElementsByTagName('body')[0];
|
131
|
+
this.isPopup = true;
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
var table = new Element('table');
|
136
|
+
|
137
|
+
var thead = new Element('thead');
|
138
|
+
table.appendChild(thead);
|
139
|
+
|
140
|
+
var firstRow = new Element('tr');
|
141
|
+
|
142
|
+
if (this.isPopup){
|
143
|
+
var cell = new Element('td');
|
144
|
+
cell.addClassName('draggableHandler');
|
145
|
+
firstRow.appendChild(cell);
|
146
|
+
|
147
|
+
cell = new Element('td', { colSpan: 5 });
|
148
|
+
cell.addClassName('title' );
|
149
|
+
cell.addClassName('draggableHandler');
|
150
|
+
firstRow.appendChild(cell);
|
151
|
+
|
152
|
+
cell = new Element('td');
|
153
|
+
cell.addClassName('closeButton');
|
154
|
+
firstRow.appendChild(cell);
|
155
|
+
cell.update('x');
|
156
|
+
|
157
|
+
cell.observe('mousedown', function(){
|
158
|
+
this.hide();
|
159
|
+
}.bind(this));
|
160
|
+
|
161
|
+
|
162
|
+
}else{
|
163
|
+
var cell = new Element('td', { colSpan: 7 } );
|
164
|
+
firstRow.appendChild(cell);
|
165
|
+
}
|
166
|
+
|
167
|
+
cell.addClassName('title');
|
168
|
+
|
169
|
+
thead.appendChild(firstRow);
|
170
|
+
|
171
|
+
var row = new Element('tr')
|
172
|
+
this._drawButtonCell(row, '«', 1, Calendar.NAV_PREVIOUS_YEAR);
|
173
|
+
this._drawButtonCell(row, '‹', 1, Calendar.NAV_PREVIOUS_MONTH);
|
174
|
+
this._drawButtonCell(row, Calendar.getMessageFor('today'), 3, Calendar.NAV_TODAY);
|
175
|
+
this._drawButtonCell(row, '›', 1, Calendar.NAV_NEXT_MONTH);
|
176
|
+
this._drawButtonCell(row, '»', 1, Calendar.NAV_NEXT_YEAR);
|
177
|
+
thead.appendChild(row)
|
178
|
+
|
179
|
+
// Day Names
|
180
|
+
row = new Element('tr');
|
181
|
+
for (var i = 0; i < 7; ++i) {
|
182
|
+
cell = new Element('th').update(Calendar.SHORT_DAY_NAMES[i]);
|
183
|
+
if (i == 0 || i == 6){
|
184
|
+
cell.addClassName('weekend');
|
185
|
+
}
|
186
|
+
row.appendChild(cell);
|
187
|
+
}
|
188
|
+
thead.appendChild(row);
|
189
|
+
|
190
|
+
// Calendar Days
|
191
|
+
var tbody = table.appendChild(new Element('tbody'));
|
192
|
+
for (i = 6; i > 0; --i) {
|
193
|
+
row = tbody.appendChild(new Element('tr'));
|
194
|
+
row.addClassName('days');
|
195
|
+
for (var j = 7; j > 0; --j) {
|
196
|
+
cell = row.appendChild(new Element('td'));
|
197
|
+
cell.calendar = this;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
// Time Placeholder
|
202
|
+
if (this.withTime){
|
203
|
+
var tfoot = table.appendChild(new Element('tfoot'));
|
204
|
+
row = tfoot.appendChild(new Element('tr'));
|
205
|
+
cell = row.appendChild(new Element('td', { colSpan: 7 }));
|
206
|
+
cell.addClassName('time');
|
207
|
+
var hourSelect = cell.appendChild(new Element('select', { name : 'hourSelect'}));
|
208
|
+
for (var i = 0; i < 24; i++) {
|
209
|
+
hourSelect.appendChild(new Element('option', {value : i}).update(i));
|
210
|
+
}
|
211
|
+
this.hourSelect = hourSelect;
|
212
|
+
|
213
|
+
cell.appendChild(new Element('span')).update(' : ');
|
214
|
+
|
215
|
+
var minuteSelect = cell.appendChild(new Element('select', { name : 'minuteSelect'}));
|
216
|
+
for (var i = 0; i < 60; i += this.minuteStep) {
|
217
|
+
minuteSelect.appendChild(new Element('option', {value : i}).update(i));
|
218
|
+
}
|
219
|
+
this.minuteSelect = minuteSelect;
|
220
|
+
|
221
|
+
hourSelect.observe('change', function(event){
|
222
|
+
if (! this.date) return;
|
223
|
+
var elem = event.element();
|
224
|
+
var selectedIndex = elem.selectedIndex;
|
225
|
+
if ((typeof selectedIndex != 'undefined') && selectedIndex != null){
|
226
|
+
this.date.setHours(elem.options[selectedIndex].value);
|
227
|
+
this.updateOuterField();
|
228
|
+
}
|
229
|
+
}.bind(this));
|
230
|
+
|
231
|
+
minuteSelect.observe('change', function(event){
|
232
|
+
if (! this.date) return;
|
233
|
+
var elem = event.element();
|
234
|
+
var selectedIndex = elem.selectedIndex;
|
235
|
+
if ((typeof selectedIndex != 'undefined') && selectedIndex != null){
|
236
|
+
this.date.setMinutes(elem.options[selectedIndex].value);
|
237
|
+
this.updateOuterField();
|
238
|
+
}
|
239
|
+
}.bind(this))
|
240
|
+
}
|
241
|
+
|
242
|
+
// Calendar Container (div)
|
243
|
+
this.container = new Element('div');
|
244
|
+
this.container.addClassName('calendar');
|
245
|
+
if (this.isPopup) {
|
246
|
+
this.container.setStyle({ position: 'absolute', display: 'none' });
|
247
|
+
this.container.addClassName('popup');
|
248
|
+
}
|
249
|
+
this.container.appendChild(table);
|
250
|
+
|
251
|
+
this.update(this.date);
|
252
|
+
|
253
|
+
Event.observe(this.container, 'mousedown', Calendar.handleMouseDownEvent);
|
254
|
+
|
255
|
+
parentForCalendarTable.appendChild(this.container);
|
256
|
+
|
257
|
+
if (this.isPopup){
|
258
|
+
new Draggable(table, {handle : firstRow });
|
259
|
+
}
|
260
|
+
},
|
261
|
+
|
262
|
+
updateOuterFieldReal: function(element){
|
263
|
+
if (element.tagName == 'DIV' || element.tagName == 'SPAN') {
|
264
|
+
formatted = this.date ? this.date.print(this.dateFormat) : '';
|
265
|
+
element.update(formatted);
|
266
|
+
} else if (element.tagName == 'INPUT') {
|
267
|
+
formatted = this.date ? this.date.print(this.dateFormatForHiddenField) : '';
|
268
|
+
element.value = formatted;
|
269
|
+
}
|
270
|
+
},
|
271
|
+
|
272
|
+
updateOuterFieldWithoutCallback: function(){
|
273
|
+
this.outputFields.each(function(field){
|
274
|
+
this.updateOuterFieldReal(field);
|
275
|
+
}.bind(this));
|
276
|
+
},
|
277
|
+
|
278
|
+
updateOuterField: function(){
|
279
|
+
this.updateOuterFieldWithoutCallback();
|
280
|
+
this.onDateChangedCallback(this.date, this);
|
281
|
+
},
|
282
|
+
|
283
|
+
viewOutputFields: function(){
|
284
|
+
return this.outputFields.findAll(function(element){
|
285
|
+
if (element.tagName == 'DIV' || element.tagName == 'SPAN'){
|
286
|
+
return true;
|
287
|
+
}else{
|
288
|
+
return false;
|
289
|
+
}
|
290
|
+
});
|
291
|
+
},
|
292
|
+
|
293
|
+
|
294
|
+
//----------------------------------------------------------------------------
|
295
|
+
// Update Calendar
|
296
|
+
//----------------------------------------------------------------------------
|
297
|
+
|
298
|
+
update: function(date) {
|
299
|
+
|
300
|
+
var today = new Date();
|
301
|
+
var thisYear = today.getFullYear();
|
302
|
+
var thisMonth = today.getMonth();
|
303
|
+
var thisDay = today.getDate();
|
304
|
+
var month = date.getMonth();
|
305
|
+
var dayOfMonth = date.getDate();
|
306
|
+
var hour = date.getHours();
|
307
|
+
var minute = date.getMinutes();
|
308
|
+
|
309
|
+
// Ensure date is within the defined range
|
310
|
+
if (date.getFullYear() < this.minYear)
|
311
|
+
date.__setFullYear(this.minYear);
|
312
|
+
else if (date.getFullYear() > this.maxYear)
|
313
|
+
date.__setFullYear(this.maxYear);
|
314
|
+
|
315
|
+
if (this.isBackedUp()){
|
316
|
+
this.dateBackedUp = new Date(date);
|
317
|
+
}else{
|
318
|
+
this.date = new Date(date);
|
319
|
+
}
|
320
|
+
|
321
|
+
// Calculate the first day to display (including the previous month)
|
322
|
+
date.setDate(1)
|
323
|
+
date.setDate(-(date.getDay()) + 1)
|
324
|
+
|
325
|
+
// Fill in the days of the month
|
326
|
+
Element.getElementsBySelector(this.container, 'tbody tr').each(
|
327
|
+
function(row, i) {
|
328
|
+
var rowHasDays = false;
|
329
|
+
row.immediateDescendants().each(
|
330
|
+
function(cell, j) {
|
331
|
+
var day = date.getDate();
|
332
|
+
var dayOfWeek = date.getDay();
|
333
|
+
var isCurrentMonth = (date.getMonth() == month);
|
334
|
+
|
335
|
+
// Reset classes on the cell
|
336
|
+
cell.className = '';
|
337
|
+
cell.date = new Date(date);
|
338
|
+
cell.update(day);
|
339
|
+
|
340
|
+
// Account for days of the month other than the current month
|
341
|
+
if (!isCurrentMonth)
|
342
|
+
cell.addClassName('otherDay');
|
343
|
+
else
|
344
|
+
rowHasDays = true;
|
345
|
+
|
346
|
+
// Ensure the current day is selected
|
347
|
+
if ((! this.isBackedUp()) && isCurrentMonth && day == dayOfMonth) {
|
348
|
+
cell.addClassName('selected');
|
349
|
+
this.currentDateElement = cell;
|
350
|
+
}
|
351
|
+
|
352
|
+
// Today
|
353
|
+
if (date.getFullYear() == thisYear && date.getMonth() == thisMonth && day == thisDay)
|
354
|
+
cell.addClassName('today');
|
355
|
+
|
356
|
+
// Weekend
|
357
|
+
if ([0, 6].indexOf(dayOfWeek) != -1)
|
358
|
+
cell.addClassName('weekend');
|
359
|
+
|
360
|
+
// Set the date to tommorrow
|
361
|
+
date.setDate(day + 1);
|
362
|
+
}.bind(this)
|
363
|
+
)
|
364
|
+
// Hide the extra row if it contains only days from another month
|
365
|
+
!rowHasDays ? row.hide() : row.show();
|
366
|
+
}.bind(this)
|
367
|
+
)
|
368
|
+
|
369
|
+
Element.getElementsBySelector(this.container, 'tfoot tr td select').each(
|
370
|
+
function(sel){
|
371
|
+
if(sel.name == 'hourSelect'){
|
372
|
+
sel.selectedIndex = hour;
|
373
|
+
}else if(sel.name == 'minuteSelect'){
|
374
|
+
if (this.minuteStep == 1){
|
375
|
+
sel.selectedIndex = minute;
|
376
|
+
}else{
|
377
|
+
sel.selectedIndex = this.findClosestMinute(minute);
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}.bind(this)
|
381
|
+
)
|
382
|
+
|
383
|
+
this.container.getElementsBySelector('td.title')[0].update(
|
384
|
+
Calendar.MONTH_NAMES[month] + ' ' + this.dateOrDateBackedUp().getFullYear()
|
385
|
+
)
|
386
|
+
|
387
|
+
},
|
388
|
+
|
389
|
+
|
390
|
+
findClosestMinute: function(val){
|
391
|
+
if (val == 0){
|
392
|
+
return 0;
|
393
|
+
}
|
394
|
+
var lowest = ((val / this.minuteStep).floor() * this.minuteStep);
|
395
|
+
var distance = val % this.minuteStep;
|
396
|
+
var minuteValueToShow;
|
397
|
+
|
398
|
+
if (distance <= (this.minuteStep / 2)){
|
399
|
+
minuteValueToShow = lowest;
|
400
|
+
}else{
|
401
|
+
minuteValueToShow = lowest + this.minuteStep;
|
402
|
+
}
|
403
|
+
|
404
|
+
if (minuteValueToShow == 0){
|
405
|
+
return minuteValueToShow;
|
406
|
+
}else if(minuteValueToShow >= 60){
|
407
|
+
return (minuteValueToShow / this.minuteStep).floor() - 1;
|
408
|
+
}else{
|
409
|
+
return minuteValueToShow / this.minuteStep;
|
410
|
+
}
|
411
|
+
},
|
412
|
+
|
413
|
+
_drawButtonCell: function(parentForCell, text, colSpan, navAction) {
|
414
|
+
var cell = new Element('td');
|
415
|
+
if (colSpan > 1) cell.colSpan = colSpan;
|
416
|
+
cell.className = 'cvbutton';
|
417
|
+
cell.calendar = this;
|
418
|
+
cell.navAction = navAction;
|
419
|
+
cell.innerHTML = text;
|
420
|
+
cell.unselectable = 'on'; // IE
|
421
|
+
parentForCell.appendChild(cell);
|
422
|
+
return cell;
|
423
|
+
},
|
424
|
+
|
425
|
+
|
426
|
+
//------------------------------------------------------------------------------
|
427
|
+
// Calendar Display Functions
|
428
|
+
//------------------------------------------------------------------------------
|
429
|
+
|
430
|
+
show: function(){
|
431
|
+
this.container.show();
|
432
|
+
if (this.isPopup) {
|
433
|
+
if (this.hideOnClickElsewhere){
|
434
|
+
window._popupCalendar = this;
|
435
|
+
document.observe('mousedown', Calendar._checkCalendar);
|
436
|
+
}
|
437
|
+
}
|
438
|
+
},
|
439
|
+
|
440
|
+
showAt: function (x, y) {
|
441
|
+
this.container.setStyle({ left: x + 'px', top: y + 'px' });
|
442
|
+
this.show();
|
443
|
+
},
|
444
|
+
|
445
|
+
|
446
|
+
showAtElement: function(event, element) {
|
447
|
+
this.container.show();
|
448
|
+
var x, y;
|
449
|
+
if (this.popupPositioningStrategy == 'pointer'){ // follow the mouse pointer
|
450
|
+
var pos = Event.pointer(event);
|
451
|
+
var containerWidth = this.container.getWidth();
|
452
|
+
x = containerWidth * this.x + pos.x;
|
453
|
+
y = containerWidth * this.y + pos.y;
|
454
|
+
}else{ // 'container' - container of the trigger elements
|
455
|
+
var pos = Position.cumulativeOffset(element);
|
456
|
+
x = pos[0];
|
457
|
+
y = this.container.offsetHeight * 0.75 + pos[1];
|
458
|
+
}
|
459
|
+
this.showAt(x, y);
|
460
|
+
},
|
461
|
+
|
462
|
+
hide: function() {
|
463
|
+
if (this.isPopup){
|
464
|
+
Event.stopObserving(document, 'mousedown', Calendar._checkCalendar);
|
465
|
+
}
|
466
|
+
this.container.hide();
|
467
|
+
this.onHideCallback(this.date, this);
|
468
|
+
},
|
469
|
+
|
470
|
+
|
471
|
+
// Tries to identify the date represented in a string. If successful it also
|
472
|
+
// calls this.updateIfDateDifferent which moves the calendar to the given date.
|
473
|
+
parseDate: function(str, format){
|
474
|
+
if (!format){
|
475
|
+
format = this.dateFormat;
|
476
|
+
}
|
477
|
+
var res = Date.parseDate(str, format);
|
478
|
+
return res;
|
479
|
+
},
|
480
|
+
|
481
|
+
|
482
|
+
dateOrDateBackedUp: function(){
|
483
|
+
return this.date || this.dateBackedUp;
|
484
|
+
},
|
485
|
+
|
486
|
+
updateIfDateDifferent: function(date) {
|
487
|
+
if (!date.equalsTo(this.dateOrDateBackedUp())){
|
488
|
+
this.update(date);
|
489
|
+
}
|
490
|
+
},
|
491
|
+
|
492
|
+
backupDateAndCurrentElement: function(){
|
493
|
+
if (this.minuteSelect){
|
494
|
+
this.minuteSelect.disable();
|
495
|
+
}
|
496
|
+
if (this.hourSelect){
|
497
|
+
this.hourSelect.disable();
|
498
|
+
}
|
499
|
+
|
500
|
+
this.currentDateElementBackedUp = this.currentDateElement;
|
501
|
+
this.currentDateElement = null;
|
502
|
+
|
503
|
+
this.dateBackedUp = this.date;
|
504
|
+
this.date = null;
|
505
|
+
},
|
506
|
+
|
507
|
+
restoreDateAndCurrentElement: function(){
|
508
|
+
if (this.minuteSelect){
|
509
|
+
this.minuteSelect.enable();
|
510
|
+
}
|
511
|
+
if (this.hourSelect){
|
512
|
+
this.hourSelect.enable();
|
513
|
+
}
|
514
|
+
|
515
|
+
this.currentDateElement = this.currentDateElementBackedUp;
|
516
|
+
this.currentDateElementBackedUp = null;
|
517
|
+
|
518
|
+
this.date = this.dateBackedUp;
|
519
|
+
this.dateBackedUp = null;
|
520
|
+
},
|
521
|
+
|
522
|
+
isBackedUp: function(){
|
523
|
+
return ((this.date == null) && this.dateBackedUp);
|
524
|
+
},
|
525
|
+
|
526
|
+
dumpDates: function(){
|
527
|
+
console.log('date: ' + this.date);
|
528
|
+
console.log('dateBackedUp: ' + this.dateBackedUp);
|
529
|
+
},
|
530
|
+
|
531
|
+
|
532
|
+
setRange: function(minYear, maxYear) {
|
533
|
+
this.minYear = minYear;
|
534
|
+
this.maxYear = maxYear;
|
535
|
+
}
|
536
|
+
})
|
537
|
+
|
538
|
+
// Delete or add new locales from I18n.js according to your needs
|
539
|
+
Calendar.messagebundle = $H({'en' :
|
540
|
+
$H({
|
541
|
+
'monday' : 'Monday',
|
542
|
+
'tuesday' : 'Tuesday',
|
543
|
+
'wednesday' : 'Wednesday',
|
544
|
+
'thursday' : 'Thursday',
|
545
|
+
'friday' : 'Friday',
|
546
|
+
'saturday' : 'Saturday',
|
547
|
+
'sunday' : 'Sunday',
|
548
|
+
|
549
|
+
'monday_short' : 'M',
|
550
|
+
'tuesday_short' : 'T',
|
551
|
+
'wednesday_short' : 'W',
|
552
|
+
'thursday_short' : 'T',
|
553
|
+
'friday_short' : 'F',
|
554
|
+
'saturday_short' : 'S',
|
555
|
+
'sunday_short' : 'S',
|
556
|
+
|
557
|
+
'january' : 'January',
|
558
|
+
'february' : 'February',
|
559
|
+
'march' : 'March',
|
560
|
+
'april' : 'April',
|
561
|
+
'may' : 'May',
|
562
|
+
'june' : 'June',
|
563
|
+
'july' : 'July',
|
564
|
+
'august' : 'August',
|
565
|
+
'september' : 'September',
|
566
|
+
'october' : 'October',
|
567
|
+
'november' : 'November',
|
568
|
+
'december' : 'December',
|
569
|
+
|
570
|
+
'january_short' : 'Jan',
|
571
|
+
'february_short' : 'Feb',
|
572
|
+
'march_short' : 'Mar',
|
573
|
+
'april_short' : 'Apr',
|
574
|
+
'may_short' : 'May',
|
575
|
+
'june_short' : 'Jun',
|
576
|
+
'july_short' : 'Jul',
|
577
|
+
'august_short' : 'Aug',
|
578
|
+
'september_short' : 'Sep',
|
579
|
+
'october_short' : 'Oct',
|
580
|
+
'november_short' : 'Nov',
|
581
|
+
'december_short' : 'Dec',
|
582
|
+
|
583
|
+
'today' : 'Today'
|
584
|
+
}),
|
585
|
+
'fr' :
|
586
|
+
$H({
|
587
|
+
'monday' : 'Lundi',
|
588
|
+
'tuesday' : 'Mardi',
|
589
|
+
'wednesday' : 'Mercredi',
|
590
|
+
'thursday' : 'Jeudi',
|
591
|
+
'friday' : 'Vendredi',
|
592
|
+
'saturday' : 'Samedi',
|
593
|
+
'sunday' : 'Dimanche',
|
594
|
+
|
595
|
+
'monday_short' : 'Lu',
|
596
|
+
'tuesday_short' : 'Ma',
|
597
|
+
'wednesday_short' : 'Me',
|
598
|
+
'thursday_short' : 'Je',
|
599
|
+
'friday_short' : 'Ve',
|
600
|
+
'saturday_short' : 'Sa',
|
601
|
+
'sunday_short' : 'Di',
|
602
|
+
|
603
|
+
'january' : 'janvier',
|
604
|
+
'february' : 'février',
|
605
|
+
'march' : 'mars',
|
606
|
+
'april' : 'avril',
|
607
|
+
'may' : 'mai',
|
608
|
+
'june' : 'juin',
|
609
|
+
'july' : 'juillet',
|
610
|
+
'august' : 'août',
|
611
|
+
'september' : 'septembre',
|
612
|
+
'october' : 'octobre',
|
613
|
+
'november' : 'novembre',
|
614
|
+
'december' : 'décembre',
|
615
|
+
|
616
|
+
'january_short' : 'jan',
|
617
|
+
'february_short' : 'fév',
|
618
|
+
'march_short' : 'mar',
|
619
|
+
'april_short' : 'avr',
|
620
|
+
'may_short' : 'mai',
|
621
|
+
'june_short' : 'jun',
|
622
|
+
'july_short' : 'jul',
|
623
|
+
'august_short' : 'aoû',
|
624
|
+
'september_short' : 'sep',
|
625
|
+
'october_short' : 'oct',
|
626
|
+
'november_short' : 'nov',
|
627
|
+
'december_short' : 'dec',
|
628
|
+
|
629
|
+
'today' : 'aujourd\'hui'
|
630
|
+
}),
|
631
|
+
'nl' :
|
632
|
+
$H({
|
633
|
+
'monday' : 'maandag',
|
634
|
+
'tuesday' : 'dinsdag',
|
635
|
+
'wednesday' : 'woensdag',
|
636
|
+
'thursday' : 'donderdag',
|
637
|
+
'friday' : 'vrijdag',
|
638
|
+
'saturday' : 'zaterdag',
|
639
|
+
'sunday' : 'zondag',
|
640
|
+
|
641
|
+
'monday_short' : 'Ma',
|
642
|
+
'tuesday_short' : 'Di',
|
643
|
+
'wednesday_short' : 'Wo',
|
644
|
+
'thursday_short' : 'Do',
|
645
|
+
'friday_short' : 'Vr',
|
646
|
+
'saturday_short' : 'Za',
|
647
|
+
'sunday_short' : 'Zo',
|
648
|
+
|
649
|
+
'january' : 'januari',
|
650
|
+
'february' : 'februari',
|
651
|
+
'march' : 'maart',
|
652
|
+
'april' : 'april',
|
653
|
+
'may' : 'mei',
|
654
|
+
'june' : 'juni',
|
655
|
+
'july' : 'juli',
|
656
|
+
'august' : 'augustus',
|
657
|
+
'september' : 'september',
|
658
|
+
'october' : 'oktober',
|
659
|
+
'november' : 'november',
|
660
|
+
'december' : 'december',
|
661
|
+
|
662
|
+
'january_short' : 'jan',
|
663
|
+
'february_short' : 'feb',
|
664
|
+
'march_short' : 'mrt',
|
665
|
+
'april_short' : 'apr',
|
666
|
+
'may_short' : 'mei',
|
667
|
+
'june_short' : 'jun',
|
668
|
+
'july_short' : 'jul',
|
669
|
+
'august_short' : 'aug',
|
670
|
+
'september_short' : 'sep',
|
671
|
+
'october_short' : 'okt',
|
672
|
+
'november_short' : 'nov',
|
673
|
+
'december_short' : 'dec',
|
674
|
+
|
675
|
+
'today' : 'vandaag'
|
676
|
+
})
|
677
|
+
});
|
678
|
+
|
679
|
+
|
680
|
+
Calendar.getMessageFor = function(key){
|
681
|
+
|
682
|
+
var lang = Calendar.language || 'en';
|
683
|
+
if (! Calendar.messagebundle.get(lang)){
|
684
|
+
lang = 'en';
|
685
|
+
}
|
686
|
+
return Calendar.messagebundle.get(lang).get(key);
|
687
|
+
};
|
688
|
+
|
689
|
+
Calendar.VERSION = '1.4';
|
690
|
+
|
691
|
+
Calendar.defaultDateFormat = '%Y-%m-%d';
|
692
|
+
Calendar.defaultDateTimeFormat = '%Y-%m-%d %H:%M';
|
693
|
+
|
694
|
+
// we need to postpone the initialization of these structures to let the page define the language of the page
|
695
|
+
Calendar.init = function(){
|
696
|
+
|
697
|
+
Calendar.DAY_NAMES = new Array(
|
698
|
+
Calendar.getMessageFor('sunday'),
|
699
|
+
Calendar.getMessageFor('monday'),
|
700
|
+
Calendar.getMessageFor('tuesday'),
|
701
|
+
Calendar.getMessageFor('wednesday'),
|
702
|
+
Calendar.getMessageFor('thursday'),
|
703
|
+
Calendar.getMessageFor('friday'),
|
704
|
+
Calendar.getMessageFor('saturday')
|
705
|
+
);
|
706
|
+
|
707
|
+
Calendar.SHORT_DAY_NAMES = new Array(
|
708
|
+
Calendar.getMessageFor('sunday_short'),
|
709
|
+
Calendar.getMessageFor('monday_short'),
|
710
|
+
Calendar.getMessageFor('tuesday_short'),
|
711
|
+
Calendar.getMessageFor('wednesday_short'),
|
712
|
+
Calendar.getMessageFor('thursday_short'),
|
713
|
+
Calendar.getMessageFor('friday_short'),
|
714
|
+
Calendar.getMessageFor('saturday_short')
|
715
|
+
);
|
716
|
+
|
717
|
+
Calendar.MONTH_NAMES = new Array(
|
718
|
+
Calendar.getMessageFor('january'),
|
719
|
+
Calendar.getMessageFor('february'),
|
720
|
+
Calendar.getMessageFor('march'),
|
721
|
+
Calendar.getMessageFor('april'),
|
722
|
+
Calendar.getMessageFor('may'),
|
723
|
+
Calendar.getMessageFor('june'),
|
724
|
+
Calendar.getMessageFor('july'),
|
725
|
+
Calendar.getMessageFor('august'),
|
726
|
+
Calendar.getMessageFor('september'),
|
727
|
+
Calendar.getMessageFor('october'),
|
728
|
+
Calendar.getMessageFor('november'),
|
729
|
+
Calendar.getMessageFor('december')
|
730
|
+
);
|
731
|
+
|
732
|
+
Calendar.SHORT_MONTH_NAMES = new Array(
|
733
|
+
Calendar.getMessageFor('january_short'),
|
734
|
+
Calendar.getMessageFor('february_short'),
|
735
|
+
Calendar.getMessageFor('march_short'),
|
736
|
+
Calendar.getMessageFor('april_short'),
|
737
|
+
Calendar.getMessageFor('may_short'),
|
738
|
+
Calendar.getMessageFor('june_short'),
|
739
|
+
Calendar.getMessageFor('july_short'),
|
740
|
+
Calendar.getMessageFor('august_short'),
|
741
|
+
Calendar.getMessageFor('september_short'),
|
742
|
+
Calendar.getMessageFor('october_short'),
|
743
|
+
Calendar.getMessageFor('november_short'),
|
744
|
+
Calendar.getMessageFor('december_short')
|
745
|
+
);
|
746
|
+
Calendar.init_done = true;
|
747
|
+
};
|
748
|
+
|
749
|
+
Calendar.NAV_PREVIOUS_YEAR = -2;
|
750
|
+
Calendar.NAV_PREVIOUS_MONTH = -1;
|
751
|
+
Calendar.NAV_TODAY = 0;
|
752
|
+
Calendar.NAV_NEXT_MONTH = 1;
|
753
|
+
Calendar.NAV_NEXT_YEAR = 2;
|
754
|
+
|
755
|
+
//------------------------------------------------------------------------------
|
756
|
+
// Static Methods
|
757
|
+
//------------------------------------------------------------------------------
|
758
|
+
|
759
|
+
// This gets called when the user presses a mouse button anywhere in the
|
760
|
+
// document, if the calendar is shown. If the click was outside the open
|
761
|
+
// calendar this function closes it.
|
762
|
+
Calendar._checkCalendar = function(event) {
|
763
|
+
if (!window._popupCalendar){
|
764
|
+
return false;
|
765
|
+
}
|
766
|
+
if (Element.descendantOf(Event.element(event), window._popupCalendar.container)){
|
767
|
+
return;
|
768
|
+
}
|
769
|
+
Calendar.closeHandler(window._popupCalendar);
|
770
|
+
return Event.stop(event);
|
771
|
+
}
|
772
|
+
|
773
|
+
//------------------------------------------------------------------------------
|
774
|
+
// Event Handlers
|
775
|
+
//------------------------------------------------------------------------------
|
776
|
+
|
777
|
+
Calendar.handleMouseDownEvent = function(event){
|
778
|
+
if (event.element().type == 'select-one'){ // ignore select elements - not escaping this in Safari leaves select boxes non-functional
|
779
|
+
return true;
|
780
|
+
}
|
781
|
+
Event.observe(document, 'mouseup', Calendar.handleMouseUpEvent);
|
782
|
+
Event.stop(event)
|
783
|
+
}
|
784
|
+
|
785
|
+
Calendar.handleMouseUpEvent = function(event){
|
786
|
+
var el = Event.element(event);
|
787
|
+
var calendar = el.calendar;
|
788
|
+
var isNewDate = false;
|
789
|
+
|
790
|
+
|
791
|
+
// If the element that was clicked on does not have an associated Calendar
|
792
|
+
// object, return as we have nothing to do.
|
793
|
+
if (!calendar) return false;
|
794
|
+
|
795
|
+
// Clicked on a day
|
796
|
+
if (typeof el.navAction == 'undefined') {
|
797
|
+
|
798
|
+
var dateWasDefined = true;
|
799
|
+
if (calendar.date == null){
|
800
|
+
dateWasDefined = false;
|
801
|
+
calendar.restoreDateAndCurrentElement();
|
802
|
+
}
|
803
|
+
|
804
|
+
|
805
|
+
if (calendar.currentDateElement) {
|
806
|
+
Element.removeClassName(calendar.currentDateElement, 'selected');
|
807
|
+
|
808
|
+
if (dateWasDefined && el == calendar.currentDateElement){
|
809
|
+
calendar.backupDateAndCurrentElement();
|
810
|
+
|
811
|
+
calendar.updateOuterField();
|
812
|
+
|
813
|
+
Event.stopObserving(document, 'mouseup', Calendar.handleMouseUpEvent);
|
814
|
+
return Event.stop(event);
|
815
|
+
}
|
816
|
+
|
817
|
+
Element.addClassName(el, 'selected');
|
818
|
+
|
819
|
+
calendar.shouldClose = (calendar.currentDateElement == el);
|
820
|
+
|
821
|
+
if (!calendar.shouldClose) {
|
822
|
+
|
823
|
+
calendar.currentDateElement = el;
|
824
|
+
}
|
825
|
+
}
|
826
|
+
calendar.date.setDateOnly(el.date);
|
827
|
+
isNewDate = true;
|
828
|
+
|
829
|
+
calendar.shouldClose = !el.hasClassName('otherDay');
|
830
|
+
|
831
|
+
|
832
|
+
var isOtherMonth = !calendar.shouldClose;
|
833
|
+
if (isOtherMonth) {
|
834
|
+
calendar.update(calendar.date);
|
835
|
+
}
|
836
|
+
|
837
|
+
if (! calendar.hideOnClickOnDay){ // override closing if calendar.hideOnClickOnDay is false
|
838
|
+
calendar.shouldClose = false;
|
839
|
+
}
|
840
|
+
|
841
|
+
} else { // Clicked on an action button
|
842
|
+
|
843
|
+
var date = new Date(calendar.dateOrDateBackedUp());
|
844
|
+
|
845
|
+
if (el.navAction == Calendar.NAV_TODAY){
|
846
|
+
date.setDateOnly(new Date());
|
847
|
+
}
|
848
|
+
|
849
|
+
var year = date.getFullYear();
|
850
|
+
var mon = date.getMonth();
|
851
|
+
|
852
|
+
function setMonth(m) {
|
853
|
+
var day = date.getDate();
|
854
|
+
var max = date.getMonthDays(m);
|
855
|
+
if (day > max) date.setDate(max);
|
856
|
+
date.setMonth(m);
|
857
|
+
}
|
858
|
+
|
859
|
+
switch (el.navAction) {
|
860
|
+
|
861
|
+
// Previous Year
|
862
|
+
case Calendar.NAV_PREVIOUS_YEAR:
|
863
|
+
if (year > calendar.minYear)
|
864
|
+
date.__setFullYear(year - 1);
|
865
|
+
break;
|
866
|
+
|
867
|
+
// Previous Month
|
868
|
+
case Calendar.NAV_PREVIOUS_MONTH:
|
869
|
+
if (mon > 0) {
|
870
|
+
setMonth(mon - 1);
|
871
|
+
}
|
872
|
+
else if (year-- > calendar.minYear) {
|
873
|
+
date.__setFullYear(year);
|
874
|
+
setMonth(11);
|
875
|
+
}
|
876
|
+
break;
|
877
|
+
|
878
|
+
// Today
|
879
|
+
case Calendar.NAV_TODAY:
|
880
|
+
break;
|
881
|
+
|
882
|
+
// Next Month
|
883
|
+
case Calendar.NAV_NEXT_MONTH:
|
884
|
+
if (mon < 11) {
|
885
|
+
setMonth(mon + 1);
|
886
|
+
}else if (year < calendar.maxYear) {
|
887
|
+
date.__setFullYear(year + 1);
|
888
|
+
setMonth(0);
|
889
|
+
}
|
890
|
+
break;
|
891
|
+
|
892
|
+
// Next Year
|
893
|
+
case Calendar.NAV_NEXT_YEAR:
|
894
|
+
if (year < calendar.maxYear){
|
895
|
+
date.__setFullYear(year + 1);
|
896
|
+
}
|
897
|
+
break;
|
898
|
+
}
|
899
|
+
|
900
|
+
if (!date.equalsTo(calendar.dateOrDateBackedUp())) {
|
901
|
+
calendar.updateIfDateDifferent(date);
|
902
|
+
isNewDate = true;
|
903
|
+
} // else if (el.navAction == 0) {
|
904
|
+
// isNewDate = (calendar.shouldClose = true);
|
905
|
+
// } // Hm, what did I mean with this code?
|
906
|
+
}
|
907
|
+
|
908
|
+
if (isNewDate && event) {
|
909
|
+
Calendar.selectHandler(calendar);
|
910
|
+
}
|
911
|
+
|
912
|
+
if (calendar.shouldClose && event) {
|
913
|
+
Calendar.closeHandler(calendar);
|
914
|
+
}
|
915
|
+
|
916
|
+
Event.stopObserving(document, 'mouseup', Calendar.handleMouseUpEvent);
|
917
|
+
return Event.stop(event);
|
918
|
+
}
|
919
|
+
|
920
|
+
Calendar.selectHandler = function(calendar){
|
921
|
+
|
922
|
+
// Update dateField value
|
923
|
+
calendar.updateOuterField();
|
924
|
+
|
925
|
+
|
926
|
+
// Call the close handler, if necessary
|
927
|
+
if (calendar.shouldClose) {
|
928
|
+
Calendar.closeHandler(calendar);
|
929
|
+
}
|
930
|
+
}
|
931
|
+
|
932
|
+
Calendar.closeHandler = function(calendar){
|
933
|
+
calendar.hide();
|
934
|
+
calendar.shouldClose = false;
|
935
|
+
}
|
936
|
+
|
937
|
+
|
938
|
+
|
939
|
+
// global object that remembers the calendar
|
940
|
+
window._popupCalendar = null;
|
941
|
+
|
942
|
+
|
943
|
+
//==============================================================================
|
944
|
+
//
|
945
|
+
// Date Object Patches
|
946
|
+
//
|
947
|
+
// This is pretty much untouched from the original. I really would like to get
|
948
|
+
// rid of these patches if at all possible and find a cleaner way of
|
949
|
+
// accomplishing the same things. It's a shame Prototype doesn't extend Date at
|
950
|
+
// all.
|
951
|
+
//
|
952
|
+
//==============================================================================
|
953
|
+
|
954
|
+
Date.DAYS_IN_MONTH = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
|
955
|
+
Date.SECOND = 1000 /* milliseconds */
|
956
|
+
Date.MINUTE = 60 * Date.SECOND
|
957
|
+
Date.HOUR = 60 * Date.MINUTE
|
958
|
+
Date.DAY = 24 * Date.HOUR
|
959
|
+
Date.WEEK = 7 * Date.DAY
|
960
|
+
|
961
|
+
// Parses Date
|
962
|
+
Date.parseDate = function(str, fmt) {
|
963
|
+
if (str){
|
964
|
+
str = new String(str);
|
965
|
+
}else{
|
966
|
+
str = new String('');
|
967
|
+
}
|
968
|
+
str = str.strip();
|
969
|
+
|
970
|
+
var today = new Date();
|
971
|
+
var y = 0;
|
972
|
+
var m = -1;
|
973
|
+
var d = 0;
|
974
|
+
var a = str.split(/\W+/);
|
975
|
+
var b = fmt.match(/%./g);
|
976
|
+
var i = 0, j = 0;
|
977
|
+
var hr = 0;
|
978
|
+
var min = 0;
|
979
|
+
|
980
|
+
for (i = 0; i < a.length; ++i) {
|
981
|
+
if (!a[i]) continue;
|
982
|
+
switch (b[i]) {
|
983
|
+
case "%d":
|
984
|
+
case "%e":
|
985
|
+
d = parseInt(a[i], 10);
|
986
|
+
break;
|
987
|
+
case "%m":
|
988
|
+
m = parseInt(a[i], 10) - 1;
|
989
|
+
break;
|
990
|
+
case "%Y":
|
991
|
+
case "%y":
|
992
|
+
y = parseInt(a[i], 10);
|
993
|
+
(y < 100) && (y += (y > 29) ? 1900 : 2000);
|
994
|
+
break;
|
995
|
+
case "%b":
|
996
|
+
case "%B":
|
997
|
+
for (j = 0; j < 12; ++j) {
|
998
|
+
if (Calendar.MONTH_NAMES[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) {
|
999
|
+
m = j;
|
1000
|
+
break;
|
1001
|
+
}
|
1002
|
+
}
|
1003
|
+
break;
|
1004
|
+
case "%H":
|
1005
|
+
case "%I":
|
1006
|
+
case "%k":
|
1007
|
+
case "%l":
|
1008
|
+
hr = parseInt(a[i], 10);
|
1009
|
+
break;
|
1010
|
+
case "%P":
|
1011
|
+
case "%p":
|
1012
|
+
if (/pm/i.test(a[i]) && hr < 12)
|
1013
|
+
hr += 12;
|
1014
|
+
else if (/am/i.test(a[i]) && hr >= 12)
|
1015
|
+
hr -= 12;
|
1016
|
+
break;
|
1017
|
+
case "%M":
|
1018
|
+
min = parseInt(a[i], 10);
|
1019
|
+
break;
|
1020
|
+
}
|
1021
|
+
}
|
1022
|
+
if (isNaN(y)) y = today.getFullYear();
|
1023
|
+
if (isNaN(m)) m = today.getMonth();
|
1024
|
+
if (isNaN(d)) d = today.getDate();
|
1025
|
+
if (isNaN(hr)) hr = today.getHours();
|
1026
|
+
if (isNaN(min)) min = today.getMinutes();
|
1027
|
+
if (y != 0 && m != -1 && d != 0)
|
1028
|
+
return new Date(y, m, d, hr, min, 0);
|
1029
|
+
y = 0; m = -1; d = 0;
|
1030
|
+
for (i = 0; i < a.length; ++i) {
|
1031
|
+
if (a[i].search(/[a-zA-Z]+/) != -1) {
|
1032
|
+
var t = -1;
|
1033
|
+
for (j = 0; j < 12; ++j) {
|
1034
|
+
if (Calendar.MONTH_NAMES[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
|
1035
|
+
}
|
1036
|
+
if (t != -1) {
|
1037
|
+
if (m != -1) {
|
1038
|
+
d = m+1;
|
1039
|
+
}
|
1040
|
+
m = t;
|
1041
|
+
}
|
1042
|
+
} else if (parseInt(a[i], 10) <= 12 && m == -1) {
|
1043
|
+
m = a[i]-1;
|
1044
|
+
} else if (parseInt(a[i], 10) > 31 && y == 0) {
|
1045
|
+
y = parseInt(a[i], 10);
|
1046
|
+
(y < 100) && (y += (y > 29) ? 1900 : 2000);
|
1047
|
+
} else if (d == 0) {
|
1048
|
+
d = a[i];
|
1049
|
+
}
|
1050
|
+
}
|
1051
|
+
if (y == 0)
|
1052
|
+
y = today.getFullYear();
|
1053
|
+
if (m != -1 && d != 0)
|
1054
|
+
return new Date(y, m, d, hr, min, 0);
|
1055
|
+
return today;
|
1056
|
+
};
|
1057
|
+
|
1058
|
+
// Returns the number of days in the current month
|
1059
|
+
Date.prototype.getMonthDays = function(month) {
|
1060
|
+
var year = this.getFullYear()
|
1061
|
+
if (typeof month == "undefined")
|
1062
|
+
month = this.getMonth()
|
1063
|
+
if (((0 == (year % 4)) && ( (0 != (year % 100)) || (0 == (year % 400)))) && month == 1)
|
1064
|
+
return 29
|
1065
|
+
else
|
1066
|
+
return Date.DAYS_IN_MONTH[month]
|
1067
|
+
};
|
1068
|
+
|
1069
|
+
// Returns the number of day in the year
|
1070
|
+
Date.prototype.getDayOfYear = function() {
|
1071
|
+
var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
1072
|
+
var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
|
1073
|
+
var time = now - then;
|
1074
|
+
return Math.floor(time / Date.DAY);
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
/** Returns the number of the week in year, as defined in ISO 8601. */
|
1078
|
+
Date.prototype.getWeekNumber = function() {
|
1079
|
+
var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
1080
|
+
var DoW = d.getDay();
|
1081
|
+
d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
|
1082
|
+
var ms = d.valueOf(); // GMT
|
1083
|
+
d.setMonth(0);
|
1084
|
+
d.setDate(4); // Thu in Week 1
|
1085
|
+
return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
|
1086
|
+
};
|
1087
|
+
|
1088
|
+
/** Checks date and time equality */
|
1089
|
+
Date.prototype.equalsTo = function(date) {
|
1090
|
+
return ((this.getFullYear() == date.getFullYear()) &&
|
1091
|
+
(this.getMonth() == date.getMonth()) &&
|
1092
|
+
(this.getDate() == date.getDate()) &&
|
1093
|
+
(this.getHours() == date.getHours()) &&
|
1094
|
+
(this.getMinutes() == date.getMinutes()));
|
1095
|
+
};
|
1096
|
+
|
1097
|
+
/** Set only the year, month, date parts (keep existing time) */
|
1098
|
+
Date.prototype.setDateOnly = function(date) {
|
1099
|
+
var tmp = new Date(date);
|
1100
|
+
this.setDate(1);
|
1101
|
+
this.__setFullYear(tmp.getFullYear());
|
1102
|
+
this.setMonth(tmp.getMonth());
|
1103
|
+
this.setDate(tmp.getDate());
|
1104
|
+
};
|
1105
|
+
|
1106
|
+
/** Prints the date in a string according to the given format. */
|
1107
|
+
Date.prototype.print = function (str) {
|
1108
|
+
var m = this.getMonth();
|
1109
|
+
var d = this.getDate();
|
1110
|
+
var y = this.getFullYear();
|
1111
|
+
var wn = this.getWeekNumber();
|
1112
|
+
var w = this.getDay();
|
1113
|
+
var s = {};
|
1114
|
+
var hr = this.getHours();
|
1115
|
+
var pm = (hr >= 12);
|
1116
|
+
var ir = (pm) ? (hr - 12) : hr;
|
1117
|
+
var dy = this.getDayOfYear();
|
1118
|
+
if (ir == 0)
|
1119
|
+
ir = 12;
|
1120
|
+
var min = this.getMinutes();
|
1121
|
+
var sec = this.getSeconds();
|
1122
|
+
s["%a"] = Calendar.SHORT_DAY_NAMES[w]; // abbreviated weekday name [FIXME: I18N]
|
1123
|
+
s["%A"] = Calendar.DAY_NAMES[w]; // full weekday name
|
1124
|
+
s["%b"] = Calendar.SHORT_MONTH_NAMES[m]; // abbreviated month name [FIXME: I18N]
|
1125
|
+
s["%B"] = Calendar.MONTH_NAMES[m]; // full month name
|
1126
|
+
// FIXME: %c : preferred date and time representation for the current locale
|
1127
|
+
s["%C"] = 1 + Math.floor(y / 100); // the century number
|
1128
|
+
s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
|
1129
|
+
s["%e"] = d; // the day of the month (range 1 to 31)
|
1130
|
+
// FIXME: %D : american date style: %m/%d/%y
|
1131
|
+
// FIXME: %E, %F, %G, %g, %h (man strftime)
|
1132
|
+
s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
|
1133
|
+
s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
|
1134
|
+
s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
|
1135
|
+
s["%k"] = hr; // hour, range 0 to 23 (24h format)
|
1136
|
+
s["%l"] = ir; // hour, range 1 to 12 (12h format)
|
1137
|
+
s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
|
1138
|
+
s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
|
1139
|
+
s["%n"] = "\n"; // a newline character
|
1140
|
+
s["%p"] = pm ? "PM" : "AM";
|
1141
|
+
s["%P"] = pm ? "pm" : "am";
|
1142
|
+
// FIXME: %r : the time in am/pm notation %I:%M:%S %p
|
1143
|
+
// FIXME: %R : the time in 24-hour notation %H:%M
|
1144
|
+
s["%s"] = Math.floor(this.getTime() / 1000);
|
1145
|
+
s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
|
1146
|
+
s["%t"] = "\t"; // a tab character
|
1147
|
+
// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
|
1148
|
+
s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
|
1149
|
+
s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
|
1150
|
+
s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
|
1151
|
+
// FIXME: %x : preferred date representation for the current locale without the time
|
1152
|
+
// FIXME: %X : preferred time representation for the current locale without the date
|
1153
|
+
s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
|
1154
|
+
s["%Y"] = y; // year with the century
|
1155
|
+
s["%%"] = "%"; // a literal '%' character
|
1156
|
+
|
1157
|
+
return str.gsub(/%./, function(match) { return s[match] || match });
|
1158
|
+
};
|
1159
|
+
|
1160
|
+
|
1161
|
+
Date.prototype.__setFullYear = function(y) {
|
1162
|
+
var d = new Date(this);
|
1163
|
+
d.setFullYear(y);
|
1164
|
+
if (d.getMonth() != this.getMonth())
|
1165
|
+
this.setDate(28);
|
1166
|
+
this.setFullYear(y);
|
1167
|
+
};
|
1168
|
+
|