merb-admin 0.8.1 → 0.8.3
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 +29 -27
- data/Gemfile +24 -22
- data/Gemfile.lock +86 -0
- data/LICENSE +20 -20
- data/README.rdoc +54 -58
- data/Rakefile +11 -44
- data/app/controllers/application.rb +6 -6
- data/app/controllers/main.rb +191 -191
- data/app/helpers/application_helper.rb +64 -64
- data/app/helpers/main_helper.rb +167 -167
- data/app/models/.gitkeep +0 -0
- data/app/views/layout/_message.html.erb +10 -10
- data/app/views/layout/dashboard.html.erb +34 -34
- data/app/views/layout/form.html.erb +48 -48
- data/app/views/layout/list.html.erb +42 -42
- data/app/views/main/_belongs_to.html.erb +29 -29
- data/app/views/main/_big_decimal.html.erb +12 -12
- data/app/views/main/_boolean.html.erb +7 -7
- data/app/views/main/_date.html.erb +12 -12
- data/app/views/main/_datetime.html.erb +12 -12
- data/app/views/main/_float.html.erb +12 -12
- data/app/views/main/_has_many.html.erb +16 -16
- data/app/views/main/_has_one.html.erb +30 -30
- data/app/views/main/_integer.html.erb +12 -12
- data/app/views/main/_properties.html.erb +18 -18
- data/app/views/main/_string.html.erb +15 -15
- data/app/views/main/_text.html.erb +11 -11
- data/app/views/main/_time.html.erb +12 -12
- data/app/views/main/_timestamp.html.erb +12 -12
- data/app/views/main/delete.html.erb +28 -28
- data/app/views/main/edit.html.erb +19 -19
- data/app/views/main/index.html.erb +22 -22
- data/app/views/main/list.html.erb +93 -93
- data/app/views/main/new.html.erb +16 -16
- data/config/init.rb +30 -0
- data/config/router.rb +4 -0
- data/lib/abstract_model.rb +84 -86
- data/lib/active_record_support.rb +147 -147
- data/lib/datamapper_support.rb +139 -140
- data/lib/generic_support.rb +13 -13
- data/lib/merb-admin.rb +99 -99
- data/lib/merb-admin/merbtasks.rb +103 -103
- data/lib/merb-admin/slicetasks.rb +174 -174
- data/lib/merb-admin/spectasks.rb +55 -55
- data/lib/merb-admin/version.rb +3 -0
- data/lib/sequel_support.rb +275 -275
- data/merb-admin.gemspec +42 -232
- data/public/javascripts/CollapsedFieldsets.js +85 -85
- data/public/javascripts/DateTimeShortcuts.js +255 -255
- data/public/javascripts/RelatedObjectLookups.js +96 -96
- data/public/javascripts/SelectBox.js +111 -111
- data/public/javascripts/SelectFilter2.js +113 -113
- data/public/javascripts/actions.js +39 -39
- data/public/javascripts/calendar.js +143 -143
- data/public/javascripts/core.js +176 -176
- data/public/javascripts/dateparse.js +233 -233
- data/public/javascripts/getElementsBySelector.js +167 -167
- data/public/javascripts/i18n.js +33 -33
- data/public/javascripts/ordering.js +137 -137
- data/public/javascripts/timeparse.js +94 -94
- data/public/javascripts/urlify.js +140 -140
- data/public/stylesheets/base.css +746 -746
- data/public/stylesheets/changelists.css +269 -269
- data/public/stylesheets/dashboard.css +24 -24
- data/public/stylesheets/forms.css +327 -327
- data/public/stylesheets/global.css +142 -142
- data/public/stylesheets/ie.css +50 -50
- data/public/stylesheets/layout.css +29 -29
- data/public/stylesheets/login.css +54 -54
- data/public/stylesheets/master.css +1 -1
- data/public/stylesheets/patch-iewin.css +7 -7
- data/public/stylesheets/rtl.css +206 -206
- data/public/stylesheets/widgets.css +506 -506
- data/screenshots/create.png +0 -0
- data/screenshots/delete.png +0 -0
- data/screenshots/edit.png +0 -0
- data/screenshots/index.png +0 -0
- data/screenshots/list.png +0 -0
- data/screenshots/new.png +0 -0
- data/spec/controllers/main_spec.rb +25 -25
- data/spec/migrations/activerecord/001_create_divisions_migration.rb +13 -13
- data/spec/migrations/activerecord/002_create_drafts_migration.rb +19 -19
- data/spec/migrations/activerecord/003_create_leagues_migration.rb +12 -12
- data/spec/migrations/activerecord/004_create_players_migration.rb +19 -20
- data/spec/migrations/activerecord/005_create_teams_migration.rb +22 -22
- data/spec/migrations/sequel/001_create_divisions_migration.rb +15 -15
- data/spec/migrations/sequel/002_create_drafts_migration.rb +21 -21
- data/spec/migrations/sequel/003_create_leagues_migration.rb +14 -14
- data/spec/migrations/sequel/004_create_players_migration.rb +21 -22
- data/spec/migrations/sequel/005_create_teams_migration.rb +24 -24
- data/spec/models/activerecord/division.rb +7 -7
- data/spec/models/activerecord/draft.rb +11 -11
- data/spec/models/activerecord/league.rb +6 -6
- data/spec/models/activerecord/player.rb +8 -8
- data/spec/models/activerecord/team.rb +13 -13
- data/spec/models/datamapper/division.rb +12 -12
- data/spec/models/datamapper/draft.rb +18 -18
- data/spec/models/datamapper/league.rb +11 -11
- data/spec/models/datamapper/player.rb +20 -21
- data/spec/models/datamapper/team.rb +22 -22
- data/spec/models/sequel/division.rb +15 -15
- data/spec/models/sequel/draft.rb +19 -19
- data/spec/models/sequel/league.rb +14 -14
- data/spec/models/sequel/player.rb +18 -18
- data/spec/models/sequel/team.rb +21 -21
- data/spec/requests/main_spec.rb +763 -763
- data/spec/spec_helper.rb +113 -112
- metadata +247 -41
- data/VERSION +0 -1
data/merb-admin.gemspec
CHANGED
|
@@ -1,232 +1,42 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
s.
|
|
8
|
-
s.
|
|
9
|
-
|
|
10
|
-
s.
|
|
11
|
-
s.
|
|
12
|
-
s.
|
|
13
|
-
s.
|
|
14
|
-
s.
|
|
15
|
-
s.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
]
|
|
19
|
-
s.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"app/views/main/_properties.html.erb",
|
|
44
|
-
"app/views/main/_string.html.erb",
|
|
45
|
-
"app/views/main/_text.html.erb",
|
|
46
|
-
"app/views/main/_time.html.erb",
|
|
47
|
-
"app/views/main/_timestamp.html.erb",
|
|
48
|
-
"app/views/main/delete.html.erb",
|
|
49
|
-
"app/views/main/edit.html.erb",
|
|
50
|
-
"app/views/main/index.html.erb",
|
|
51
|
-
"app/views/main/list.html.erb",
|
|
52
|
-
"app/views/main/new.html.erb",
|
|
53
|
-
"lib/abstract_model.rb",
|
|
54
|
-
"lib/active_record_support.rb",
|
|
55
|
-
"lib/datamapper_support.rb",
|
|
56
|
-
"lib/generic_support.rb",
|
|
57
|
-
"lib/merb-admin.rb",
|
|
58
|
-
"lib/merb-admin/merbtasks.rb",
|
|
59
|
-
"lib/merb-admin/slicetasks.rb",
|
|
60
|
-
"lib/merb-admin/spectasks.rb",
|
|
61
|
-
"lib/sequel_support.rb",
|
|
62
|
-
"merb-admin.gemspec",
|
|
63
|
-
"public/images/arrow-down.gif",
|
|
64
|
-
"public/images/arrow-up.gif",
|
|
65
|
-
"public/images/changelist-bg.gif",
|
|
66
|
-
"public/images/changelist-bg_rtl.gif",
|
|
67
|
-
"public/images/chooser-bg.gif",
|
|
68
|
-
"public/images/chooser_stacked-bg.gif",
|
|
69
|
-
"public/images/default-bg-reverse.gif",
|
|
70
|
-
"public/images/default-bg.gif",
|
|
71
|
-
"public/images/deleted-overlay.gif",
|
|
72
|
-
"public/images/icon-no.gif",
|
|
73
|
-
"public/images/icon-unknown.gif",
|
|
74
|
-
"public/images/icon-yes.gif",
|
|
75
|
-
"public/images/icon_addlink.gif",
|
|
76
|
-
"public/images/icon_alert.gif",
|
|
77
|
-
"public/images/icon_calendar.gif",
|
|
78
|
-
"public/images/icon_changelink.gif",
|
|
79
|
-
"public/images/icon_clock.gif",
|
|
80
|
-
"public/images/icon_deletelink.gif",
|
|
81
|
-
"public/images/icon_error.gif",
|
|
82
|
-
"public/images/icon_searchbox.png",
|
|
83
|
-
"public/images/icon_success.gif",
|
|
84
|
-
"public/images/inline-delete-8bit.png",
|
|
85
|
-
"public/images/inline-delete.png",
|
|
86
|
-
"public/images/inline-restore-8bit.png",
|
|
87
|
-
"public/images/inline-restore.png",
|
|
88
|
-
"public/images/inline-splitter-bg.gif",
|
|
89
|
-
"public/images/nav-bg-grabber.gif",
|
|
90
|
-
"public/images/nav-bg-reverse.gif",
|
|
91
|
-
"public/images/nav-bg.gif",
|
|
92
|
-
"public/images/selector-add.gif",
|
|
93
|
-
"public/images/selector-addall.gif",
|
|
94
|
-
"public/images/selector-remove.gif",
|
|
95
|
-
"public/images/selector-removeall.gif",
|
|
96
|
-
"public/images/selector-search.gif",
|
|
97
|
-
"public/images/selector_stacked-add.gif",
|
|
98
|
-
"public/images/selector_stacked-remove.gif",
|
|
99
|
-
"public/images/tool-left.gif",
|
|
100
|
-
"public/images/tool-left_over.gif",
|
|
101
|
-
"public/images/tool-right.gif",
|
|
102
|
-
"public/images/tool-right_over.gif",
|
|
103
|
-
"public/images/tooltag-add.gif",
|
|
104
|
-
"public/images/tooltag-add_over.gif",
|
|
105
|
-
"public/images/tooltag-arrowright.gif",
|
|
106
|
-
"public/images/tooltag-arrowright_over.gif",
|
|
107
|
-
"public/javascripts/CollapsedFieldsets.js",
|
|
108
|
-
"public/javascripts/DateTimeShortcuts.js",
|
|
109
|
-
"public/javascripts/RelatedObjectLookups.js",
|
|
110
|
-
"public/javascripts/SelectBox.js",
|
|
111
|
-
"public/javascripts/SelectFilter2.js",
|
|
112
|
-
"public/javascripts/actions.js",
|
|
113
|
-
"public/javascripts/calendar.js",
|
|
114
|
-
"public/javascripts/core.js",
|
|
115
|
-
"public/javascripts/dateparse.js",
|
|
116
|
-
"public/javascripts/getElementsBySelector.js",
|
|
117
|
-
"public/javascripts/i18n.js",
|
|
118
|
-
"public/javascripts/master.js",
|
|
119
|
-
"public/javascripts/ordering.js",
|
|
120
|
-
"public/javascripts/timeparse.js",
|
|
121
|
-
"public/javascripts/urlify.js",
|
|
122
|
-
"public/stylesheets/base.css",
|
|
123
|
-
"public/stylesheets/changelists.css",
|
|
124
|
-
"public/stylesheets/dashboard.css",
|
|
125
|
-
"public/stylesheets/forms.css",
|
|
126
|
-
"public/stylesheets/global.css",
|
|
127
|
-
"public/stylesheets/ie.css",
|
|
128
|
-
"public/stylesheets/layout.css",
|
|
129
|
-
"public/stylesheets/login.css",
|
|
130
|
-
"public/stylesheets/master.css",
|
|
131
|
-
"public/stylesheets/null.css",
|
|
132
|
-
"public/stylesheets/patch-iewin.css",
|
|
133
|
-
"public/stylesheets/rtl.css",
|
|
134
|
-
"public/stylesheets/widgets.css",
|
|
135
|
-
"spec/controllers/main_spec.rb",
|
|
136
|
-
"spec/migrations/activerecord/001_create_divisions_migration.rb",
|
|
137
|
-
"spec/migrations/activerecord/002_create_drafts_migration.rb",
|
|
138
|
-
"spec/migrations/activerecord/003_create_leagues_migration.rb",
|
|
139
|
-
"spec/migrations/activerecord/004_create_players_migration.rb",
|
|
140
|
-
"spec/migrations/activerecord/005_create_teams_migration.rb",
|
|
141
|
-
"spec/migrations/sequel/001_create_divisions_migration.rb",
|
|
142
|
-
"spec/migrations/sequel/002_create_drafts_migration.rb",
|
|
143
|
-
"spec/migrations/sequel/003_create_leagues_migration.rb",
|
|
144
|
-
"spec/migrations/sequel/004_create_players_migration.rb",
|
|
145
|
-
"spec/migrations/sequel/005_create_teams_migration.rb",
|
|
146
|
-
"spec/models/activerecord/division.rb",
|
|
147
|
-
"spec/models/activerecord/draft.rb",
|
|
148
|
-
"spec/models/activerecord/league.rb",
|
|
149
|
-
"spec/models/activerecord/player.rb",
|
|
150
|
-
"spec/models/activerecord/team.rb",
|
|
151
|
-
"spec/models/datamapper/division.rb",
|
|
152
|
-
"spec/models/datamapper/draft.rb",
|
|
153
|
-
"spec/models/datamapper/league.rb",
|
|
154
|
-
"spec/models/datamapper/player.rb",
|
|
155
|
-
"spec/models/datamapper/team.rb",
|
|
156
|
-
"spec/models/sequel/division.rb",
|
|
157
|
-
"spec/models/sequel/draft.rb",
|
|
158
|
-
"spec/models/sequel/league.rb",
|
|
159
|
-
"spec/models/sequel/player.rb",
|
|
160
|
-
"spec/models/sequel/team.rb",
|
|
161
|
-
"spec/requests/main_spec.rb",
|
|
162
|
-
"spec/spec_helper.rb"
|
|
163
|
-
]
|
|
164
|
-
s.homepage = %q{http://github.com/sferik/merb-admin}
|
|
165
|
-
s.post_install_message = %q{********************************************************************************
|
|
166
|
-
|
|
167
|
-
WARNING: MerbAdmin does not implement any authorization scheme.
|
|
168
|
-
Make sure to apply authorization logic before deploying to production!
|
|
169
|
-
|
|
170
|
-
********************************************************************************
|
|
171
|
-
}
|
|
172
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
|
173
|
-
s.require_paths = ["lib"]
|
|
174
|
-
s.rubygems_version = %q{1.3.6}
|
|
175
|
-
s.summary = %q{MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data.}
|
|
176
|
-
s.test_files = [
|
|
177
|
-
"spec/controllers/main_spec.rb",
|
|
178
|
-
"spec/migrations/activerecord/001_create_divisions_migration.rb",
|
|
179
|
-
"spec/migrations/activerecord/002_create_drafts_migration.rb",
|
|
180
|
-
"spec/migrations/activerecord/003_create_leagues_migration.rb",
|
|
181
|
-
"spec/migrations/activerecord/004_create_players_migration.rb",
|
|
182
|
-
"spec/migrations/activerecord/005_create_teams_migration.rb",
|
|
183
|
-
"spec/migrations/sequel/001_create_divisions_migration.rb",
|
|
184
|
-
"spec/migrations/sequel/002_create_drafts_migration.rb",
|
|
185
|
-
"spec/migrations/sequel/003_create_leagues_migration.rb",
|
|
186
|
-
"spec/migrations/sequel/004_create_players_migration.rb",
|
|
187
|
-
"spec/migrations/sequel/005_create_teams_migration.rb",
|
|
188
|
-
"spec/models/activerecord/division.rb",
|
|
189
|
-
"spec/models/activerecord/draft.rb",
|
|
190
|
-
"spec/models/activerecord/league.rb",
|
|
191
|
-
"spec/models/activerecord/player.rb",
|
|
192
|
-
"spec/models/activerecord/team.rb",
|
|
193
|
-
"spec/models/datamapper/division.rb",
|
|
194
|
-
"spec/models/datamapper/draft.rb",
|
|
195
|
-
"spec/models/datamapper/league.rb",
|
|
196
|
-
"spec/models/datamapper/player.rb",
|
|
197
|
-
"spec/models/datamapper/team.rb",
|
|
198
|
-
"spec/models/sequel/division.rb",
|
|
199
|
-
"spec/models/sequel/draft.rb",
|
|
200
|
-
"spec/models/sequel/league.rb",
|
|
201
|
-
"spec/models/sequel/player.rb",
|
|
202
|
-
"spec/models/sequel/team.rb",
|
|
203
|
-
"spec/requests/main_spec.rb",
|
|
204
|
-
"spec/spec_helper.rb"
|
|
205
|
-
]
|
|
206
|
-
|
|
207
|
-
if s.respond_to? :specification_version then
|
|
208
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
209
|
-
s.specification_version = 3
|
|
210
|
-
|
|
211
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
212
|
-
s.add_runtime_dependency(%q<merb-slices>, ["~> 1.1"])
|
|
213
|
-
s.add_runtime_dependency(%q<merb-assets>, ["~> 1.1"])
|
|
214
|
-
s.add_runtime_dependency(%q<merb-helpers>, ["~> 1.1"])
|
|
215
|
-
s.add_runtime_dependency(%q<builder>, ["~> 2.1"])
|
|
216
|
-
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
|
217
|
-
else
|
|
218
|
-
s.add_dependency(%q<merb-slices>, ["~> 1.1"])
|
|
219
|
-
s.add_dependency(%q<merb-assets>, ["~> 1.1"])
|
|
220
|
-
s.add_dependency(%q<merb-helpers>, ["~> 1.1"])
|
|
221
|
-
s.add_dependency(%q<builder>, ["~> 2.1"])
|
|
222
|
-
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
|
223
|
-
end
|
|
224
|
-
else
|
|
225
|
-
s.add_dependency(%q<merb-slices>, ["~> 1.1"])
|
|
226
|
-
s.add_dependency(%q<merb-assets>, ["~> 1.1"])
|
|
227
|
-
s.add_dependency(%q<merb-helpers>, ["~> 1.1"])
|
|
228
|
-
s.add_dependency(%q<builder>, ["~> 2.1"])
|
|
229
|
-
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.expand_path("../lib/merb-admin/version", __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.add_development_dependency("activerecord", ["~> 2.3"])
|
|
6
|
+
s.add_development_dependency("dm-core", ["~> 0.10"])
|
|
7
|
+
s.add_development_dependency("dm-aggregates", ["~> 0.10"])
|
|
8
|
+
s.add_development_dependency("dm-types", ["~> 0.10"])
|
|
9
|
+
s.add_development_dependency("dm-migrations", ["~> 0.10"])
|
|
10
|
+
s.add_development_dependency("dm-validations", ["~> 0.10"])
|
|
11
|
+
s.add_development_dependency("data_objects", ["~> 0.10"])
|
|
12
|
+
s.add_development_dependency("do_sqlite3", ["~> 0.10"])
|
|
13
|
+
s.add_development_dependency("rspec", ["~> 1.3"])
|
|
14
|
+
s.add_development_dependency("sequel", ["~> 3.6.0"])
|
|
15
|
+
s.add_development_dependency("sqlite3-ruby", ["~> 1.3"])
|
|
16
|
+
s.add_development_dependency("webrat", ["~> 0.7"])
|
|
17
|
+
s.add_runtime_dependency("builder", ["~> 2.1"])
|
|
18
|
+
s.add_runtime_dependency("json", ["~> 1.4"])
|
|
19
|
+
s.add_runtime_dependency("merb-assets", ["~> 1.1"])
|
|
20
|
+
s.add_runtime_dependency("merb-helpers", ["~> 1.1"])
|
|
21
|
+
s.add_runtime_dependency("merb-slices", ["~> 1.1"])
|
|
22
|
+
s.authors = ["Erik Michaels-Ober"]
|
|
23
|
+
s.description = %q{MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data}
|
|
24
|
+
s.email = "sferik@gmail.com"
|
|
25
|
+
s.extra_rdoc_files = ["LICENSE", "README.rdoc"]
|
|
26
|
+
s.files = `git ls-files`.split("\n")
|
|
27
|
+
s.homepage = "http://rubygems.org/gems/merb-admin"
|
|
28
|
+
s.name = "merb-admin"
|
|
29
|
+
s.post_install_message =<<eos
|
|
30
|
+
********************************************************************************
|
|
31
|
+
Make sure to add authorization logic before deploying to production!
|
|
32
|
+
WARNING: MerbAdmin does not implement any authorization scheme.
|
|
33
|
+
********************************************************************************
|
|
34
|
+
eos
|
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
36
|
+
s.require_paths = ["lib"]
|
|
37
|
+
s.required_rubygems_version = ">= 1.3.6"
|
|
38
|
+
s.rubyforge_project = "merb-admin"
|
|
39
|
+
s.summary = %q{MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data}
|
|
40
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
41
|
+
s.version = MerbAdmin::VERSION
|
|
42
|
+
end
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
// Finds all fieldsets with class="collapse", collapses them, and gives each
|
|
2
|
-
// one a "Show" link that uncollapses it. The "Show" link becomes a "Hide"
|
|
3
|
-
// link when the fieldset is visible.
|
|
4
|
-
|
|
5
|
-
function findForm(node) {
|
|
6
|
-
// returns the node of the form containing the given node
|
|
7
|
-
if (node.tagName.toLowerCase() != 'form') {
|
|
8
|
-
return findForm(node.parentNode);
|
|
9
|
-
}
|
|
10
|
-
return node;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
var CollapsedFieldsets = {
|
|
14
|
-
collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
|
|
15
|
-
collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
|
|
16
|
-
collapsed_class: 'collapsed',
|
|
17
|
-
init: function() {
|
|
18
|
-
var fieldsets = document.getElementsByTagName('fieldset');
|
|
19
|
-
var collapsed_seen = false;
|
|
20
|
-
for (var i = 0, fs; fs = fieldsets[i]; i++) {
|
|
21
|
-
// Collapse this fieldset if it has the correct class, and if it
|
|
22
|
-
// doesn't have any errors. (Collapsing shouldn't apply in the case
|
|
23
|
-
// of error messages.)
|
|
24
|
-
if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
|
|
25
|
-
collapsed_seen = true;
|
|
26
|
-
// Give it an additional class, used by CSS to hide it.
|
|
27
|
-
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
|
28
|
-
// (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>)
|
|
29
|
-
var collapse_link = document.createElement('a');
|
|
30
|
-
collapse_link.className = 'collapse-toggle';
|
|
31
|
-
collapse_link.id = 'fieldsetcollapser' + i;
|
|
32
|
-
collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;');
|
|
33
|
-
collapse_link.href = '#';
|
|
34
|
-
collapse_link.innerHTML = gettext('Show');
|
|
35
|
-
var h2 = fs.getElementsByTagName('h2')[0];
|
|
36
|
-
h2.appendChild(document.createTextNode(' ('));
|
|
37
|
-
h2.appendChild(collapse_link);
|
|
38
|
-
h2.appendChild(document.createTextNode(')'));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
if (collapsed_seen) {
|
|
42
|
-
// Expand all collapsed fieldsets when form is submitted.
|
|
43
|
-
addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
fieldset_has_errors: function(fs) {
|
|
47
|
-
// Returns true if any fields in the fieldset have validation errors.
|
|
48
|
-
var divs = fs.getElementsByTagName('div');
|
|
49
|
-
for (var i=0; i<divs.length; i++) {
|
|
50
|
-
if (divs[i].className.match(/\berrors\b/)) {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return false;
|
|
55
|
-
},
|
|
56
|
-
show: function(fieldset_index) {
|
|
57
|
-
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
|
58
|
-
// Remove the class name that causes the "display: none".
|
|
59
|
-
fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
|
|
60
|
-
// Toggle the "Show" link to a "Hide" link
|
|
61
|
-
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
|
62
|
-
collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;');
|
|
63
|
-
collapse_link.innerHTML = gettext('Hide');
|
|
64
|
-
},
|
|
65
|
-
hide: function(fieldset_index) {
|
|
66
|
-
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
|
67
|
-
// Add the class name that causes the "display: none".
|
|
68
|
-
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
|
69
|
-
// Toggle the "Hide" link to a "Show" link
|
|
70
|
-
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
|
71
|
-
collapse_link.onclick = new Function('CollapsedFieldsets.show('+fieldset_index+'); return false;');
|
|
72
|
-
collapse_link.innerHTML = gettext('Show');
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
uncollapse_all: function() {
|
|
76
|
-
var fieldsets = document.getElementsByTagName('fieldset');
|
|
77
|
-
for (var i=0; i<fieldsets.length; i++) {
|
|
78
|
-
if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
|
|
79
|
-
CollapsedFieldsets.show(i);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
addEvent(window, 'load', CollapsedFieldsets.init);
|
|
1
|
+
// Finds all fieldsets with class="collapse", collapses them, and gives each
|
|
2
|
+
// one a "Show" link that uncollapses it. The "Show" link becomes a "Hide"
|
|
3
|
+
// link when the fieldset is visible.
|
|
4
|
+
|
|
5
|
+
function findForm(node) {
|
|
6
|
+
// returns the node of the form containing the given node
|
|
7
|
+
if (node.tagName.toLowerCase() != 'form') {
|
|
8
|
+
return findForm(node.parentNode);
|
|
9
|
+
}
|
|
10
|
+
return node;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var CollapsedFieldsets = {
|
|
14
|
+
collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
|
|
15
|
+
collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
|
|
16
|
+
collapsed_class: 'collapsed',
|
|
17
|
+
init: function() {
|
|
18
|
+
var fieldsets = document.getElementsByTagName('fieldset');
|
|
19
|
+
var collapsed_seen = false;
|
|
20
|
+
for (var i = 0, fs; fs = fieldsets[i]; i++) {
|
|
21
|
+
// Collapse this fieldset if it has the correct class, and if it
|
|
22
|
+
// doesn't have any errors. (Collapsing shouldn't apply in the case
|
|
23
|
+
// of error messages.)
|
|
24
|
+
if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
|
|
25
|
+
collapsed_seen = true;
|
|
26
|
+
// Give it an additional class, used by CSS to hide it.
|
|
27
|
+
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
|
28
|
+
// (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>)
|
|
29
|
+
var collapse_link = document.createElement('a');
|
|
30
|
+
collapse_link.className = 'collapse-toggle';
|
|
31
|
+
collapse_link.id = 'fieldsetcollapser' + i;
|
|
32
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;');
|
|
33
|
+
collapse_link.href = '#';
|
|
34
|
+
collapse_link.innerHTML = gettext('Show');
|
|
35
|
+
var h2 = fs.getElementsByTagName('h2')[0];
|
|
36
|
+
h2.appendChild(document.createTextNode(' ('));
|
|
37
|
+
h2.appendChild(collapse_link);
|
|
38
|
+
h2.appendChild(document.createTextNode(')'));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (collapsed_seen) {
|
|
42
|
+
// Expand all collapsed fieldsets when form is submitted.
|
|
43
|
+
addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
fieldset_has_errors: function(fs) {
|
|
47
|
+
// Returns true if any fields in the fieldset have validation errors.
|
|
48
|
+
var divs = fs.getElementsByTagName('div');
|
|
49
|
+
for (var i=0; i<divs.length; i++) {
|
|
50
|
+
if (divs[i].className.match(/\berrors\b/)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
},
|
|
56
|
+
show: function(fieldset_index) {
|
|
57
|
+
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
|
58
|
+
// Remove the class name that causes the "display: none".
|
|
59
|
+
fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
|
|
60
|
+
// Toggle the "Show" link to a "Hide" link
|
|
61
|
+
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
|
62
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;');
|
|
63
|
+
collapse_link.innerHTML = gettext('Hide');
|
|
64
|
+
},
|
|
65
|
+
hide: function(fieldset_index) {
|
|
66
|
+
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
|
67
|
+
// Add the class name that causes the "display: none".
|
|
68
|
+
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
|
69
|
+
// Toggle the "Hide" link to a "Show" link
|
|
70
|
+
var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index);
|
|
71
|
+
collapse_link.onclick = new Function('CollapsedFieldsets.show('+fieldset_index+'); return false;');
|
|
72
|
+
collapse_link.innerHTML = gettext('Show');
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
uncollapse_all: function() {
|
|
76
|
+
var fieldsets = document.getElementsByTagName('fieldset');
|
|
77
|
+
for (var i=0; i<fieldsets.length; i++) {
|
|
78
|
+
if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
|
|
79
|
+
CollapsedFieldsets.show(i);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
addEvent(window, 'load', CollapsedFieldsets.init);
|
|
@@ -1,255 +1,255 @@
|
|
|
1
|
-
// Inserts shortcut buttons after all of the following:
|
|
2
|
-
// <input type="text" class="vDateField">
|
|
3
|
-
// <input type="text" class="vTimeField">
|
|
4
|
-
|
|
5
|
-
var DateTimeShortcuts = {
|
|
6
|
-
calendars: [],
|
|
7
|
-
calendarInputs: [],
|
|
8
|
-
clockInputs: [],
|
|
9
|
-
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
|
|
10
|
-
calendarDivName2: 'calendarin', // name of <div> that contains calendar
|
|
11
|
-
calendarLinkName: 'calendarlink',// name of the link that is used to toggle
|
|
12
|
-
clockDivName: 'clockbox', // name of clock <div> that gets toggled
|
|
13
|
-
clockLinkName: 'clocklink', // name of the link that is used to toggle
|
|
14
|
-
admin_media_prefix: '',
|
|
15
|
-
init: function() {
|
|
16
|
-
// Deduce admin_media_prefix by looking at the <script>s in the
|
|
17
|
-
// current document and finding the URL of *this* module.
|
|
18
|
-
var scripts = document.getElementsByTagName('script');
|
|
19
|
-
for (var i=0; i<scripts.length; i++) {
|
|
20
|
-
if (scripts[i].src.match(/DateTimeShortcuts/)) {
|
|
21
|
-
var idx = scripts[i].src.indexOf('DateTimeShortcuts');
|
|
22
|
-
DateTimeShortcuts.admin_media_prefix = scripts[i].src.substring(0, idx);
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
var inputs = document.getElementsByTagName('input');
|
|
28
|
-
for (i=0; i<inputs.length; i++) {
|
|
29
|
-
var inp = inputs[i];
|
|
30
|
-
if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
|
|
31
|
-
DateTimeShortcuts.addClock(inp);
|
|
32
|
-
}
|
|
33
|
-
else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
|
|
34
|
-
DateTimeShortcuts.addCalendar(inp);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
// Add clock widget to a given field
|
|
39
|
-
addClock: function(inp) {
|
|
40
|
-
var num = DateTimeShortcuts.clockInputs.length;
|
|
41
|
-
DateTimeShortcuts.clockInputs[num] = inp;
|
|
42
|
-
|
|
43
|
-
// Shortcut links (clock icon and "Now" link)
|
|
44
|
-
var shortcuts_span = document.createElement('span');
|
|
45
|
-
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
|
46
|
-
var now_link = document.createElement('a');
|
|
47
|
-
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());");
|
|
48
|
-
now_link.appendChild(document.createTextNode(gettext('Now')));
|
|
49
|
-
var clock_link = document.createElement('a');
|
|
50
|
-
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
|
|
51
|
-
clock_link.id = DateTimeShortcuts.clockLinkName + num;
|
|
52
|
-
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + '../images/icon_clock.gif', 'alt', gettext('Clock'));
|
|
53
|
-
shortcuts_span.appendChild(document.createTextNode('\240'));
|
|
54
|
-
shortcuts_span.appendChild(now_link);
|
|
55
|
-
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
|
56
|
-
shortcuts_span.appendChild(clock_link);
|
|
57
|
-
|
|
58
|
-
// Create clock link div
|
|
59
|
-
//
|
|
60
|
-
// Markup looks like:
|
|
61
|
-
// <div id="clockbox1" class="clockbox module">
|
|
62
|
-
// <h2>Choose a time</h2>
|
|
63
|
-
// <ul class="timelist">
|
|
64
|
-
// <li><a href="#">Now</a></li>
|
|
65
|
-
// <li><a href="#">Midnight</a></li>
|
|
66
|
-
// <li><a href="#">6 a.m.</a></li>
|
|
67
|
-
// <li><a href="#">Noon</a></li>
|
|
68
|
-
// </ul>
|
|
69
|
-
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
|
70
|
-
// </div>
|
|
71
|
-
|
|
72
|
-
var clock_box = document.createElement('div');
|
|
73
|
-
clock_box.style.display = 'none';
|
|
74
|
-
clock_box.style.position = 'absolute';
|
|
75
|
-
clock_box.className = 'clockbox module';
|
|
76
|
-
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
|
|
77
|
-
document.body.appendChild(clock_box);
|
|
78
|
-
addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
|
79
|
-
|
|
80
|
-
quickElement('h2', clock_box, gettext('Choose a time'));
|
|
81
|
-
time_list = quickElement('ul', clock_box, '');
|
|
82
|
-
time_list.className = 'timelist';
|
|
83
|
-
quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());")
|
|
84
|
-
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00:00');")
|
|
85
|
-
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00:00');")
|
|
86
|
-
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00:00');")
|
|
87
|
-
|
|
88
|
-
cancel_p = quickElement('p', clock_box, '');
|
|
89
|
-
cancel_p.className = 'calendar-cancel';
|
|
90
|
-
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
|
|
91
|
-
},
|
|
92
|
-
openClock: function(num) {
|
|
93
|
-
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
|
|
94
|
-
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num)
|
|
95
|
-
|
|
96
|
-
// Recalculate the clockbox position
|
|
97
|
-
// is it left-to-right or right-to-left layout ?
|
|
98
|
-
if (getStyle(document.body,'direction')!='rtl') {
|
|
99
|
-
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
// since style's width is in em, it'd be tough to calculate
|
|
103
|
-
// px value of it. let's use an estimated px for now
|
|
104
|
-
// TODO: IE returns wrong value for findPosX when in rtl mode
|
|
105
|
-
// (it returns as it was left aligned), needs to be fixed.
|
|
106
|
-
clock_box.style.left = findPosX(clock_link) - 110 + 'px';
|
|
107
|
-
}
|
|
108
|
-
clock_box.style.top = findPosY(clock_link) - 30 + 'px';
|
|
109
|
-
|
|
110
|
-
// Show the clock box
|
|
111
|
-
clock_box.style.display = 'block';
|
|
112
|
-
addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; });
|
|
113
|
-
},
|
|
114
|
-
dismissClock: function(num) {
|
|
115
|
-
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
|
116
|
-
window.document.onclick = null;
|
|
117
|
-
},
|
|
118
|
-
handleClockQuicklink: function(num, val) {
|
|
119
|
-
DateTimeShortcuts.clockInputs[num].value = val;
|
|
120
|
-
DateTimeShortcuts.dismissClock(num);
|
|
121
|
-
},
|
|
122
|
-
// Add calendar widget to a given field.
|
|
123
|
-
addCalendar: function(inp) {
|
|
124
|
-
var num = DateTimeShortcuts.calendars.length;
|
|
125
|
-
|
|
126
|
-
DateTimeShortcuts.calendarInputs[num] = inp;
|
|
127
|
-
|
|
128
|
-
// Shortcut links (calendar icon and "Today" link)
|
|
129
|
-
var shortcuts_span = document.createElement('span');
|
|
130
|
-
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
|
131
|
-
var today_link = document.createElement('a');
|
|
132
|
-
today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
|
133
|
-
today_link.appendChild(document.createTextNode(gettext('Today')));
|
|
134
|
-
var cal_link = document.createElement('a');
|
|
135
|
-
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
|
|
136
|
-
cal_link.id = DateTimeShortcuts.calendarLinkName + num;
|
|
137
|
-
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + '../images/icon_calendar.gif', 'alt', gettext('Calendar'));
|
|
138
|
-
shortcuts_span.appendChild(document.createTextNode('\240'));
|
|
139
|
-
shortcuts_span.appendChild(today_link);
|
|
140
|
-
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
|
141
|
-
shortcuts_span.appendChild(cal_link);
|
|
142
|
-
|
|
143
|
-
// Create calendarbox div.
|
|
144
|
-
//
|
|
145
|
-
// Markup looks like:
|
|
146
|
-
//
|
|
147
|
-
// <div id="calendarbox3" class="calendarbox module">
|
|
148
|
-
// <h2>
|
|
149
|
-
// <a href="#" class="link-previous">‹</a>
|
|
150
|
-
// <a href="#" class="link-next">›</a> February 2003
|
|
151
|
-
// </h2>
|
|
152
|
-
// <div class="calendar" id="calendarin3">
|
|
153
|
-
// <!-- (cal) -->
|
|
154
|
-
// </div>
|
|
155
|
-
// <div class="calendar-shortcuts">
|
|
156
|
-
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
|
157
|
-
// </div>
|
|
158
|
-
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
|
159
|
-
// </div>
|
|
160
|
-
var cal_box = document.createElement('div');
|
|
161
|
-
cal_box.style.display = 'none';
|
|
162
|
-
cal_box.style.position = 'absolute';
|
|
163
|
-
cal_box.className = 'calendarbox module';
|
|
164
|
-
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
|
|
165
|
-
document.body.appendChild(cal_box);
|
|
166
|
-
addEvent(cal_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
|
167
|
-
|
|
168
|
-
// next-prev links
|
|
169
|
-
var cal_nav = quickElement('div', cal_box, '');
|
|
170
|
-
var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');');
|
|
171
|
-
cal_nav_prev.className = 'calendarnav-previous';
|
|
172
|
-
var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');');
|
|
173
|
-
cal_nav_next.className = 'calendarnav-next';
|
|
174
|
-
|
|
175
|
-
// main box
|
|
176
|
-
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
|
|
177
|
-
cal_main.className = 'calendar';
|
|
178
|
-
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
|
|
179
|
-
DateTimeShortcuts.calendars[num].drawCurrent();
|
|
180
|
-
|
|
181
|
-
// calendar shortcuts
|
|
182
|
-
var shortcuts = quickElement('div', cal_box, '');
|
|
183
|
-
shortcuts.className = 'calendar-shortcuts';
|
|
184
|
-
quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);');
|
|
185
|
-
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
|
186
|
-
quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
|
187
|
-
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
|
188
|
-
quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);');
|
|
189
|
-
|
|
190
|
-
// cancel bar
|
|
191
|
-
var cancel_p = quickElement('p', cal_box, '');
|
|
192
|
-
cancel_p.className = 'calendar-cancel';
|
|
193
|
-
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
|
194
|
-
},
|
|
195
|
-
openCalendar: function(num) {
|
|
196
|
-
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
|
197
|
-
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
|
|
198
|
-
var inp = DateTimeShortcuts.calendarInputs[num];
|
|
199
|
-
|
|
200
|
-
// Determine if the current value in the input has a valid date.
|
|
201
|
-
// If so, draw the calendar with that date's year and month.
|
|
202
|
-
if (inp.value) {
|
|
203
|
-
var date_parts = inp.value.split('-');
|
|
204
|
-
var year = date_parts[0];
|
|
205
|
-
var month = parseFloat(date_parts[1]);
|
|
206
|
-
if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
|
|
207
|
-
DateTimeShortcuts.calendars[num].drawDate(month, year);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
// Recalculate the clockbox position
|
|
213
|
-
// is it left-to-right or right-to-left layout ?
|
|
214
|
-
if (getStyle(document.body,'direction')!='rtl') {
|
|
215
|
-
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
// since style's width is in em, it'd be tough to calculate
|
|
219
|
-
// px value of it. let's use an estimated px for now
|
|
220
|
-
// TODO: IE returns wrong value for findPosX when in rtl mode
|
|
221
|
-
// (it returns as it was left aligned), needs to be fixed.
|
|
222
|
-
cal_box.style.left = findPosX(cal_link) - 180 + 'px';
|
|
223
|
-
}
|
|
224
|
-
cal_box.style.top = findPosY(cal_link) - 75 + 'px';
|
|
225
|
-
|
|
226
|
-
cal_box.style.display = 'block';
|
|
227
|
-
addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; });
|
|
228
|
-
},
|
|
229
|
-
dismissCalendar: function(num) {
|
|
230
|
-
document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none';
|
|
231
|
-
window.document.onclick = null;
|
|
232
|
-
},
|
|
233
|
-
drawPrev: function(num) {
|
|
234
|
-
DateTimeShortcuts.calendars[num].drawPreviousMonth();
|
|
235
|
-
},
|
|
236
|
-
drawNext: function(num) {
|
|
237
|
-
DateTimeShortcuts.calendars[num].drawNextMonth();
|
|
238
|
-
},
|
|
239
|
-
handleCalendarCallback: function(num) {
|
|
240
|
-
return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = y+'-'+(m<10?'0':'')+m+'-'+(d<10?'0':'')+d; document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}";
|
|
241
|
-
},
|
|
242
|
-
handleCalendarQuickLink: function(num, offset) {
|
|
243
|
-
var d = new Date();
|
|
244
|
-
d.setDate(d.getDate() + offset)
|
|
245
|
-
DateTimeShortcuts.calendarInputs[num].value = d.getISODate();
|
|
246
|
-
DateTimeShortcuts.dismissCalendar(num);
|
|
247
|
-
},
|
|
248
|
-
cancelEventPropagation: function(e) {
|
|
249
|
-
if (!e) e = window.event;
|
|
250
|
-
e.cancelBubble = true;
|
|
251
|
-
if (e.stopPropagation) e.stopPropagation();
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
addEvent(window, 'load', DateTimeShortcuts.init);
|
|
1
|
+
// Inserts shortcut buttons after all of the following:
|
|
2
|
+
// <input type="text" class="vDateField">
|
|
3
|
+
// <input type="text" class="vTimeField">
|
|
4
|
+
|
|
5
|
+
var DateTimeShortcuts = {
|
|
6
|
+
calendars: [],
|
|
7
|
+
calendarInputs: [],
|
|
8
|
+
clockInputs: [],
|
|
9
|
+
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
|
|
10
|
+
calendarDivName2: 'calendarin', // name of <div> that contains calendar
|
|
11
|
+
calendarLinkName: 'calendarlink',// name of the link that is used to toggle
|
|
12
|
+
clockDivName: 'clockbox', // name of clock <div> that gets toggled
|
|
13
|
+
clockLinkName: 'clocklink', // name of the link that is used to toggle
|
|
14
|
+
admin_media_prefix: '',
|
|
15
|
+
init: function() {
|
|
16
|
+
// Deduce admin_media_prefix by looking at the <script>s in the
|
|
17
|
+
// current document and finding the URL of *this* module.
|
|
18
|
+
var scripts = document.getElementsByTagName('script');
|
|
19
|
+
for (var i=0; i<scripts.length; i++) {
|
|
20
|
+
if (scripts[i].src.match(/DateTimeShortcuts/)) {
|
|
21
|
+
var idx = scripts[i].src.indexOf('DateTimeShortcuts');
|
|
22
|
+
DateTimeShortcuts.admin_media_prefix = scripts[i].src.substring(0, idx);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var inputs = document.getElementsByTagName('input');
|
|
28
|
+
for (i=0; i<inputs.length; i++) {
|
|
29
|
+
var inp = inputs[i];
|
|
30
|
+
if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
|
|
31
|
+
DateTimeShortcuts.addClock(inp);
|
|
32
|
+
}
|
|
33
|
+
else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
|
|
34
|
+
DateTimeShortcuts.addCalendar(inp);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
// Add clock widget to a given field
|
|
39
|
+
addClock: function(inp) {
|
|
40
|
+
var num = DateTimeShortcuts.clockInputs.length;
|
|
41
|
+
DateTimeShortcuts.clockInputs[num] = inp;
|
|
42
|
+
|
|
43
|
+
// Shortcut links (clock icon and "Now" link)
|
|
44
|
+
var shortcuts_span = document.createElement('span');
|
|
45
|
+
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
|
46
|
+
var now_link = document.createElement('a');
|
|
47
|
+
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());");
|
|
48
|
+
now_link.appendChild(document.createTextNode(gettext('Now')));
|
|
49
|
+
var clock_link = document.createElement('a');
|
|
50
|
+
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
|
|
51
|
+
clock_link.id = DateTimeShortcuts.clockLinkName + num;
|
|
52
|
+
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + '../images/icon_clock.gif', 'alt', gettext('Clock'));
|
|
53
|
+
shortcuts_span.appendChild(document.createTextNode('\240'));
|
|
54
|
+
shortcuts_span.appendChild(now_link);
|
|
55
|
+
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
|
56
|
+
shortcuts_span.appendChild(clock_link);
|
|
57
|
+
|
|
58
|
+
// Create clock link div
|
|
59
|
+
//
|
|
60
|
+
// Markup looks like:
|
|
61
|
+
// <div id="clockbox1" class="clockbox module">
|
|
62
|
+
// <h2>Choose a time</h2>
|
|
63
|
+
// <ul class="timelist">
|
|
64
|
+
// <li><a href="#">Now</a></li>
|
|
65
|
+
// <li><a href="#">Midnight</a></li>
|
|
66
|
+
// <li><a href="#">6 a.m.</a></li>
|
|
67
|
+
// <li><a href="#">Noon</a></li>
|
|
68
|
+
// </ul>
|
|
69
|
+
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
|
70
|
+
// </div>
|
|
71
|
+
|
|
72
|
+
var clock_box = document.createElement('div');
|
|
73
|
+
clock_box.style.display = 'none';
|
|
74
|
+
clock_box.style.position = 'absolute';
|
|
75
|
+
clock_box.className = 'clockbox module';
|
|
76
|
+
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
|
|
77
|
+
document.body.appendChild(clock_box);
|
|
78
|
+
addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
|
79
|
+
|
|
80
|
+
quickElement('h2', clock_box, gettext('Choose a time'));
|
|
81
|
+
time_list = quickElement('ul', clock_box, '');
|
|
82
|
+
time_list.className = 'timelist';
|
|
83
|
+
quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());")
|
|
84
|
+
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00:00');")
|
|
85
|
+
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00:00');")
|
|
86
|
+
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00:00');")
|
|
87
|
+
|
|
88
|
+
cancel_p = quickElement('p', clock_box, '');
|
|
89
|
+
cancel_p.className = 'calendar-cancel';
|
|
90
|
+
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
|
|
91
|
+
},
|
|
92
|
+
openClock: function(num) {
|
|
93
|
+
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
|
|
94
|
+
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num)
|
|
95
|
+
|
|
96
|
+
// Recalculate the clockbox position
|
|
97
|
+
// is it left-to-right or right-to-left layout ?
|
|
98
|
+
if (getStyle(document.body,'direction')!='rtl') {
|
|
99
|
+
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// since style's width is in em, it'd be tough to calculate
|
|
103
|
+
// px value of it. let's use an estimated px for now
|
|
104
|
+
// TODO: IE returns wrong value for findPosX when in rtl mode
|
|
105
|
+
// (it returns as it was left aligned), needs to be fixed.
|
|
106
|
+
clock_box.style.left = findPosX(clock_link) - 110 + 'px';
|
|
107
|
+
}
|
|
108
|
+
clock_box.style.top = findPosY(clock_link) - 30 + 'px';
|
|
109
|
+
|
|
110
|
+
// Show the clock box
|
|
111
|
+
clock_box.style.display = 'block';
|
|
112
|
+
addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; });
|
|
113
|
+
},
|
|
114
|
+
dismissClock: function(num) {
|
|
115
|
+
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
|
116
|
+
window.document.onclick = null;
|
|
117
|
+
},
|
|
118
|
+
handleClockQuicklink: function(num, val) {
|
|
119
|
+
DateTimeShortcuts.clockInputs[num].value = val;
|
|
120
|
+
DateTimeShortcuts.dismissClock(num);
|
|
121
|
+
},
|
|
122
|
+
// Add calendar widget to a given field.
|
|
123
|
+
addCalendar: function(inp) {
|
|
124
|
+
var num = DateTimeShortcuts.calendars.length;
|
|
125
|
+
|
|
126
|
+
DateTimeShortcuts.calendarInputs[num] = inp;
|
|
127
|
+
|
|
128
|
+
// Shortcut links (calendar icon and "Today" link)
|
|
129
|
+
var shortcuts_span = document.createElement('span');
|
|
130
|
+
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
|
131
|
+
var today_link = document.createElement('a');
|
|
132
|
+
today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
|
133
|
+
today_link.appendChild(document.createTextNode(gettext('Today')));
|
|
134
|
+
var cal_link = document.createElement('a');
|
|
135
|
+
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
|
|
136
|
+
cal_link.id = DateTimeShortcuts.calendarLinkName + num;
|
|
137
|
+
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + '../images/icon_calendar.gif', 'alt', gettext('Calendar'));
|
|
138
|
+
shortcuts_span.appendChild(document.createTextNode('\240'));
|
|
139
|
+
shortcuts_span.appendChild(today_link);
|
|
140
|
+
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
|
141
|
+
shortcuts_span.appendChild(cal_link);
|
|
142
|
+
|
|
143
|
+
// Create calendarbox div.
|
|
144
|
+
//
|
|
145
|
+
// Markup looks like:
|
|
146
|
+
//
|
|
147
|
+
// <div id="calendarbox3" class="calendarbox module">
|
|
148
|
+
// <h2>
|
|
149
|
+
// <a href="#" class="link-previous">‹</a>
|
|
150
|
+
// <a href="#" class="link-next">›</a> February 2003
|
|
151
|
+
// </h2>
|
|
152
|
+
// <div class="calendar" id="calendarin3">
|
|
153
|
+
// <!-- (cal) -->
|
|
154
|
+
// </div>
|
|
155
|
+
// <div class="calendar-shortcuts">
|
|
156
|
+
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
|
157
|
+
// </div>
|
|
158
|
+
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
|
159
|
+
// </div>
|
|
160
|
+
var cal_box = document.createElement('div');
|
|
161
|
+
cal_box.style.display = 'none';
|
|
162
|
+
cal_box.style.position = 'absolute';
|
|
163
|
+
cal_box.className = 'calendarbox module';
|
|
164
|
+
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
|
|
165
|
+
document.body.appendChild(cal_box);
|
|
166
|
+
addEvent(cal_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
|
167
|
+
|
|
168
|
+
// next-prev links
|
|
169
|
+
var cal_nav = quickElement('div', cal_box, '');
|
|
170
|
+
var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');');
|
|
171
|
+
cal_nav_prev.className = 'calendarnav-previous';
|
|
172
|
+
var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');');
|
|
173
|
+
cal_nav_next.className = 'calendarnav-next';
|
|
174
|
+
|
|
175
|
+
// main box
|
|
176
|
+
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
|
|
177
|
+
cal_main.className = 'calendar';
|
|
178
|
+
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
|
|
179
|
+
DateTimeShortcuts.calendars[num].drawCurrent();
|
|
180
|
+
|
|
181
|
+
// calendar shortcuts
|
|
182
|
+
var shortcuts = quickElement('div', cal_box, '');
|
|
183
|
+
shortcuts.className = 'calendar-shortcuts';
|
|
184
|
+
quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);');
|
|
185
|
+
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
|
186
|
+
quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
|
187
|
+
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
|
188
|
+
quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);');
|
|
189
|
+
|
|
190
|
+
// cancel bar
|
|
191
|
+
var cancel_p = quickElement('p', cal_box, '');
|
|
192
|
+
cancel_p.className = 'calendar-cancel';
|
|
193
|
+
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
|
194
|
+
},
|
|
195
|
+
openCalendar: function(num) {
|
|
196
|
+
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
|
197
|
+
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
|
|
198
|
+
var inp = DateTimeShortcuts.calendarInputs[num];
|
|
199
|
+
|
|
200
|
+
// Determine if the current value in the input has a valid date.
|
|
201
|
+
// If so, draw the calendar with that date's year and month.
|
|
202
|
+
if (inp.value) {
|
|
203
|
+
var date_parts = inp.value.split('-');
|
|
204
|
+
var year = date_parts[0];
|
|
205
|
+
var month = parseFloat(date_parts[1]);
|
|
206
|
+
if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
|
|
207
|
+
DateTimeShortcuts.calendars[num].drawDate(month, year);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
// Recalculate the clockbox position
|
|
213
|
+
// is it left-to-right or right-to-left layout ?
|
|
214
|
+
if (getStyle(document.body,'direction')!='rtl') {
|
|
215
|
+
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// since style's width is in em, it'd be tough to calculate
|
|
219
|
+
// px value of it. let's use an estimated px for now
|
|
220
|
+
// TODO: IE returns wrong value for findPosX when in rtl mode
|
|
221
|
+
// (it returns as it was left aligned), needs to be fixed.
|
|
222
|
+
cal_box.style.left = findPosX(cal_link) - 180 + 'px';
|
|
223
|
+
}
|
|
224
|
+
cal_box.style.top = findPosY(cal_link) - 75 + 'px';
|
|
225
|
+
|
|
226
|
+
cal_box.style.display = 'block';
|
|
227
|
+
addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; });
|
|
228
|
+
},
|
|
229
|
+
dismissCalendar: function(num) {
|
|
230
|
+
document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none';
|
|
231
|
+
window.document.onclick = null;
|
|
232
|
+
},
|
|
233
|
+
drawPrev: function(num) {
|
|
234
|
+
DateTimeShortcuts.calendars[num].drawPreviousMonth();
|
|
235
|
+
},
|
|
236
|
+
drawNext: function(num) {
|
|
237
|
+
DateTimeShortcuts.calendars[num].drawNextMonth();
|
|
238
|
+
},
|
|
239
|
+
handleCalendarCallback: function(num) {
|
|
240
|
+
return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = y+'-'+(m<10?'0':'')+m+'-'+(d<10?'0':'')+d; document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}";
|
|
241
|
+
},
|
|
242
|
+
handleCalendarQuickLink: function(num, offset) {
|
|
243
|
+
var d = new Date();
|
|
244
|
+
d.setDate(d.getDate() + offset)
|
|
245
|
+
DateTimeShortcuts.calendarInputs[num].value = d.getISODate();
|
|
246
|
+
DateTimeShortcuts.dismissCalendar(num);
|
|
247
|
+
},
|
|
248
|
+
cancelEventPropagation: function(e) {
|
|
249
|
+
if (!e) e = window.event;
|
|
250
|
+
e.cancelBubble = true;
|
|
251
|
+
if (e.stopPropagation) e.stopPropagation();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
addEvent(window, 'load', DateTimeShortcuts.init);
|