bootstrap_datepicker 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,98 @@
1
+ = Bootstrap Datepicker Rails plugin
2
+
3
+ This simple gem allows you to add a date picker field into your views.
4
+
5
+ == Getting Started
6
+
7
+ Pre Rails 3.1:
8
+
9
+ 1. Add into your Gemfile:
10
+
11
+ gem 'jquery-rails'
12
+
13
+ 2. Execute this command to install the needed js files:
14
+
15
+ rails generate jquery:install --ui
16
+
17
+
18
+ 3. Insert into your Gemfile:
19
+
20
+ gem 'bootstrap_datepicker'
21
+
22
+ Don't forget to install the CSS!
23
+
24
+ Rails 3.1:
25
+
26
+ 1. Insert into your Gemfile:
27
+
28
+ gem 'bootstrap_datepicker'
29
+
30
+ 2. If you are using Rails 3.1 with the asset pipeline enabled (default), the necessary files are already in your asset pipeline. Just add (if they are not already there) to your app/assets/javascripts/application.js:
31
+
32
+ //= require jquery
33
+ //= require jquery-ujs
34
+ //= require jquery-ui
35
+
36
+ (if you are using datetime picker, add also)
37
+
38
+ //= require jquery-ui-timepicker-addon.js
39
+
40
+ You can find it here:
41
+
42
+ https://github.com/trentrichardson/jQuery-Timepicker-Addon
43
+
44
+
45
+ == Usage
46
+
47
+ Add this to your view.
48
+
49
+ <%= datepicker_input "user","birthday" %>
50
+
51
+
52
+ Where "user" is your model name and "birthday" the name of the datefield.
53
+
54
+ You can also use it with the form helper like:
55
+
56
+ <% form_for(@user) do |f| %>
57
+ <%= f.datepicker 'birthday' %>
58
+ <%= f.submit 'Create' %>
59
+ <% end %>
60
+
61
+ Nested attributes are permitted as well:
62
+
63
+ <% form_for(@user) do |f| %>
64
+ <% f.fields_for(@nested) do |f2| %>
65
+ <%= f2.datepicker 'birthday' %>
66
+ <% end %>
67
+ <%= f.submit 'Create' %>
68
+ <% end %>
69
+
70
+ You can pass options as it would be a normal text_field, plus all the datepicker options available (http://jqueryui.com/demos/datepicker/#options)
71
+
72
+ <%= datepicker_input(:foo, :att1, :minDate => -20, :maxDate => "+1M +10D", :tabindex => 70) %>
73
+
74
+ == Use DateTime picker
75
+
76
+ If you want to use a datatime picker, download this plugin
77
+
78
+ https://github.com/trentrichardson/jQuery-Timepicker-Addon
79
+
80
+ and add it to your project (in the assets pipeline if you are using Rails 3.1 or manually otherwise).
81
+ Don't forget the CSS! This plugin assume you have installed a jquery-ui theme.
82
+
83
+ Then you can use in your views:
84
+
85
+ <%= datetime_picker_input "user","loged_in", :dateFormat => "yy-mm-dd" %>
86
+
87
+ or
88
+
89
+ <% form_for(@user) do |f| %>
90
+ <%= f.datetime_picker 'loged_in', :dateFormat => "yy-mm-dd" %>
91
+ <%= f.submit 'Create' %>
92
+ <% end %>
93
+
94
+ Important! Be aware the way Rails stores the datetime fields cause you'll need to specify the dateFormat to "yy-mm-dd" or pre-process your field value on the controller. The default format won't work.
95
+
96
+ == Support
97
+
98
+ Open an issue in https://github.com/albertopq/jquery_datepicker if you need further support or want to report a bug
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Echoe.new('bootstrap_datepicker', '0.4') do |p|
7
+ p.description = "View helper that allows to select dates from a calendar (using jQuery and Twitter Bootstrap styles)"
8
+ p.url = "http://github.com/derekstavis/bootstrap_datepicker"
9
+ p.author = "Derek Stavis"
10
+ p.email = "dekestavis@gmail.com"
11
+ p.ignore_pattern = ["tmp/*", "script/*", "spec/*"]
12
+ p.development_dependencies = ['twitter-bootstrap-rails']
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:spec)
16
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "bootstrap_datepicker"
5
+ s.version = "0.5"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Alberto Pastor", "Derek Willian Stavis"]
9
+ s.date = "2012-08-07"
10
+ s.description = "View helper that allows to select dates from a calendar (using jQuery and Twitter Bootstrap styles)"
11
+ s.email = "dekestavis@gmail.com"
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/app/helpers/datepicker_helper.rb", "lib/app/helpers/form_helper.rb", "lib/bootstrap_datepicker.rb"]
13
+ s.files = ["README.rdoc", "Rakefile", "init.rb", "bootstrap_datepicker.gemspec", "lib/app/helpers/datepicker_helper.rb", "lib/app/helpers/form_helper.rb", "lib/bootstrap_datepicker.rb", "lib/engine.rb", "vendor/assets/javascripts/bootstrap-datepicker.js", "vendor/assets/javascripts/index.js", "vendor/assets/stylesheets/bootstrap-datepicker.css"]
14
+
15
+ s.homepage = "http://github.com/derekstavis/bootstrap_datepicker"
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "bootstrap_datepicker", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = "bootstrap_datepicker"
19
+ s.rubygems_version = "1.8.10"
20
+ s.summary = "View helper that allows to select dates from a calendar (using jQuery and Twitter Bootstrap styles)"
21
+ s.add_dependency "twitter-bootstrap-rails", "~> 2.1.1"
22
+
23
+ if s.respond_to? :specification_version then
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'bootstrap_datepicker'
@@ -0,0 +1,18 @@
1
+ require 'app/helpers/form_helper'
2
+
3
+ module BootstrapDatepicker
4
+ module DatepickerHelper
5
+
6
+ include BootstrapDatepicker::FormHelper
7
+
8
+ # Helper method that creates a datepicker input field
9
+ def datepicker_input(object_name, method, options = {})
10
+ datepicker(object_name, method, options)
11
+ end
12
+
13
+ def datetime_picker_input(object_name, method, options = {})
14
+ datepicker(object_name, method, options, true)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,84 @@
1
+ require 'date'
2
+
3
+ module BootstrapDatepicker
4
+ module FormHelper
5
+
6
+ include ActionView::Helpers::JavaScriptHelper
7
+
8
+ # Mehtod that generates datepicker input field inside a form
9
+ def datepicker(object_name, method, options = {}, timepicker = false)
10
+ input_tag = BootstrapDatepicker::InstanceTag.new(object_name, method, self, options.delete(:object))
11
+ dp_options, tf_options = input_tag.baked_options(options)
12
+ # tf_options[:value] = input_tag.format_date(tf_options[:value], String.new(dp_options[:dateFormat])) if tf_options[:value] && !tf_options[:value].empty? && dp_options.has_key?(:dateFormat)
13
+ html = input_tag.to_input_field_tag("text", tf_options)
14
+ method = timepicker ? "datetimepicker" : "datepicker"
15
+ # html += javascript_tag("jQuery(document).ready(function(){jQuery('##{input_tag.get_name_and_id["id"]}').#{method}(#{dp_options.to_json})});")
16
+ html.html_safe
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ module BootstrapDatepicker::FormBuilder
24
+ def datepicker(method, options = {})
25
+ @template.datepicker(@object_name, method, objectify_options(options))
26
+ end
27
+
28
+ def datetime_picker(method, options = {})
29
+ @template.datepicker(@object_name, method, objectify_options(options), true)
30
+ end
31
+ end
32
+
33
+ class BootstrapDatepicker::InstanceTag < ActionView::Helpers::InstanceTag
34
+
35
+ FORMAT_REPLACEMENTES = { "yy" => "%Y", "mm" => "%m", "dd" => "%d", "d" => "%-d", "m" => "%-m", "y" => "%y", "M" => "%b"}
36
+
37
+ # Extending ActionView::Helpers::InstanceTag module to make Rails build the name and id
38
+ # Just returns the options before generate the HTML in order to use the same id and name (see to_input_field_tag mehtod)
39
+
40
+ def get_name_and_id(options = {})
41
+ add_default_name_and_id(options)
42
+ options
43
+ end
44
+
45
+ def available_datepicker_options
46
+ [:format, :week_start, :view_mode, :min_view_mode, :class]
47
+ end
48
+
49
+ def baked_options(options)
50
+ tf_options = Hash.new
51
+
52
+ options.each do |key, value|
53
+ if available_datepicker_options.include? key
54
+ if key.to_s === "class"
55
+ tf_options[key.to_s] = value
56
+ else
57
+ new_key = ("data-" << key.to_s)
58
+ tf_options[new_key] = value
59
+ end
60
+ end
61
+ end
62
+
63
+ puts 'options'
64
+ puts options
65
+ puts 'tf_options'
66
+ puts tf_options
67
+
68
+ return options, tf_options
69
+ end
70
+
71
+ def format_date(tb_formatted, format)
72
+ new_format = translate_format(format)
73
+ Date.parse(tb_formatted).strftime(new_format)
74
+ end
75
+
76
+ # Method that translates the datepicker date formats, defined in (http://docs.jquery.com/UI/Datepicker/formatDate)
77
+ # to the ruby standard format (http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime).
78
+ # This gem is not going to support all the options, just the most used.
79
+
80
+ def translate_format(format)
81
+ format.gsub!(/#{FORMAT_REPLACEMENTES.keys.join("|")}/) { |match| FORMAT_REPLACEMENTES[match] }
82
+ end
83
+
84
+ end
@@ -0,0 +1,15 @@
1
+ # BootstrapDatepicker
2
+ require "app/helpers/datepicker_helper.rb"
3
+ require "app/helpers/form_helper.rb"
4
+ require "engine.rb"
5
+
6
+ module BootstrapDatepicker
7
+ class Railtie < Rails::Railtie
8
+ initializer "BootstrapDatepicker" do
9
+ ActionController::Base.helper(BootstrapDatepicker::DatepickerHelper)
10
+ ActionView::Helpers::FormHelper.send(:include, BootstrapDatepicker::FormHelper)
11
+ ActionView::Base.send(:include, BootstrapDatepicker::DatepickerHelper)
12
+ ActionView::Helpers::FormBuilder.send(:include,BootstrapDatepicker::FormBuilder)
13
+ end
14
+ end
15
+ end
data/lib/engine.rb ADDED
@@ -0,0 +1,5 @@
1
+ module BootstrapDatepicker
2
+ class Engine < ::Rails::Engine
3
+ # auto wire
4
+ end
5
+ end
@@ -0,0 +1,416 @@
1
+ /* =========================================================
2
+ * bootstrap-datepicker.js
3
+ * http://www.eyecon.ro/bootstrap-datepicker
4
+ * =========================================================
5
+ * Copyright 2012 Stefan Petre
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ========================================================= */
19
+
20
+ $(function() {
21
+ $('.datetime_select').each(function(index, element) {
22
+ attributes = $(element).data()
23
+
24
+ console.log(attributes)
25
+
26
+ delete attributes.datepicker
27
+
28
+ console.log(attributes)
29
+
30
+ $(element).datepicker(attributes)
31
+ })
32
+
33
+ })
34
+
35
+ !function( $ ) {
36
+
37
+ // Picker object
38
+
39
+ var Datepicker = function(element, options){
40
+ this.element = $(element);
41
+ this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
42
+ this.picker = $(DPGlobal.template)
43
+ .appendTo('body')
44
+ .on({
45
+ click: $.proxy(this.click, this),
46
+ mousedown: $.proxy(this.mousedown, this)
47
+ });
48
+ this.isInput = this.element.is('input');
49
+ this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
50
+
51
+ if (this.isInput) {
52
+ this.element.on({
53
+ focus: $.proxy(this.show, this),
54
+ blur: $.proxy(this.hide, this),
55
+ keyup: $.proxy(this.update, this)
56
+ });
57
+ } else {
58
+ if (this.component){
59
+ this.component.on('click', $.proxy(this.show, this));
60
+ } else {
61
+ this.element.on('click', $.proxy(this.show, this));
62
+ }
63
+ }
64
+
65
+ this.viewMode = 0;
66
+ this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
67
+ this.weekEnd = this.weekStart == 0 ? 6 : this.weekStart - 1;
68
+ this.fillDow();
69
+ this.fillMonths();
70
+ this.update();
71
+ this.showMode();
72
+ };
73
+
74
+ Datepicker.prototype = {
75
+ constructor: Datepicker,
76
+
77
+ show: function(e) {
78
+ this.picker.show();
79
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
80
+ this.place();
81
+ $(window).on('resize', $.proxy(this.place, this));
82
+ if (e ) {
83
+ e.stopPropagation();
84
+ e.preventDefault();
85
+ }
86
+ if (!this.isInput) {
87
+ $(document).on('mousedown', $.proxy(this.hide, this));
88
+ }
89
+ this.element.trigger({
90
+ type: 'show',
91
+ date: this.date
92
+ });
93
+ },
94
+
95
+ hide: function(){
96
+ this.picker.hide();
97
+ $(window).off('resize', this.place);
98
+ this.viewMode = 0;
99
+ this.showMode();
100
+ if (!this.isInput) {
101
+ $(document).off('mousedown', this.hide);
102
+ }
103
+ this.setValue();
104
+ this.element.trigger({
105
+ type: 'hide',
106
+ date: this.date
107
+ });
108
+ },
109
+
110
+ setValue: function() {
111
+ var formated = DPGlobal.formatDate(this.date, this.format);
112
+ if (!this.isInput) {
113
+ if (this.component){
114
+ this.element.find('input').prop('value', formated);
115
+ }
116
+ this.element.data('date', formated);
117
+ } else {
118
+ this.element.prop('value', formated);
119
+ }
120
+ },
121
+
122
+ place: function(){
123
+ var offset = this.component ? this.component.offset() : this.element.offset();
124
+ this.picker.css({
125
+ top: offset.top + this.height,
126
+ left: offset.left
127
+ });
128
+ },
129
+
130
+ update: function(){
131
+ this.date = DPGlobal.parseDate(
132
+ this.isInput ? this.element.prop('value') : this.element.data('date'),
133
+ this.format
134
+ );
135
+ this.viewDate = new Date(this.date);
136
+ this.fill();
137
+ },
138
+
139
+ fillDow: function(){
140
+ var dowCnt = this.weekStart;
141
+ var html = '<tr>';
142
+ while (dowCnt < this.weekStart + 7) {
143
+ html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
144
+ }
145
+ html += '</tr>';
146
+ this.picker.find('.datepicker-days thead').append(html);
147
+ },
148
+
149
+ fillMonths: function(){
150
+ var html = '';
151
+ var i = 0
152
+ while (i < 12) {
153
+ html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
154
+ }
155
+ this.picker.find('.datepicker-months td').append(html);
156
+ },
157
+
158
+ fill: function() {
159
+ var d = new Date(this.viewDate),
160
+ year = d.getFullYear(),
161
+ month = d.getMonth(),
162
+ currentDate = this.date.valueOf();
163
+ this.picker.find('.datepicker-days th:eq(1)')
164
+ .text(DPGlobal.dates.months[month]+' '+year);
165
+ var prevMonth = new Date(year, month-1, 28,0,0,0,0),
166
+ day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
167
+ prevMonth.setDate(day);
168
+ prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
169
+ var nextMonth = new Date(prevMonth);
170
+ nextMonth.setDate(nextMonth.getDate() + 42);
171
+ nextMonth = nextMonth.valueOf();
172
+ html = [];
173
+ var clsName;
174
+ while(prevMonth.valueOf() < nextMonth) {
175
+ if (prevMonth.getDay() == this.weekStart) {
176
+ html.push('<tr>');
177
+ }
178
+ clsName = '';
179
+ if (prevMonth.getMonth() < month) {
180
+ clsName += ' old';
181
+ } else if (prevMonth.getMonth() > month) {
182
+ clsName += ' new';
183
+ }
184
+ if (prevMonth.valueOf() == currentDate) {
185
+ clsName += ' active';
186
+ }
187
+ html.push('<td class="day'+clsName+'">'+prevMonth.getDate() + '</td>');
188
+ if (prevMonth.getDay() == this.weekEnd) {
189
+ html.push('</tr>');
190
+ }
191
+ prevMonth.setDate(prevMonth.getDate()+1);
192
+ }
193
+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
194
+ var currentYear = this.date.getFullYear();
195
+
196
+ var months = this.picker.find('.datepicker-months')
197
+ .find('th:eq(1)')
198
+ .text(year)
199
+ .end()
200
+ .find('span').removeClass('active');
201
+ if (currentYear == year) {
202
+ months.eq(this.date.getMonth()).addClass('active');
203
+ }
204
+
205
+ html = '';
206
+ year = parseInt(year/10, 10) * 10;
207
+ var yearCont = this.picker.find('.datepicker-years')
208
+ .find('th:eq(1)')
209
+ .text(year + '-' + (year + 9))
210
+ .end()
211
+ .find('td');
212
+ year -= 1;
213
+ for (var i = -1; i < 11; i++) {
214
+ html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' active' : '')+'">'+year+'</span>';
215
+ year += 1;
216
+ }
217
+ yearCont.html(html);
218
+ },
219
+
220
+ click: function(e) {
221
+ e.stopPropagation();
222
+ e.preventDefault();
223
+ var target = $(e.target).closest('span, td, th');
224
+ if (target.length == 1) {
225
+ switch(target[0].nodeName.toLowerCase()) {
226
+ case 'th':
227
+ switch(target[0].className) {
228
+ case 'switch':
229
+ this.showMode(1);
230
+ break;
231
+ case 'prev':
232
+ case 'next':
233
+ this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
234
+ this.viewDate,
235
+ this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
236
+ DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1)
237
+ );
238
+ this.fill();
239
+ break;
240
+ }
241
+ break;
242
+ case 'span':
243
+ if (target.is('.month')) {
244
+ var month = target.parent().find('span').index(target);
245
+ this.viewDate.setMonth(month);
246
+ } else {
247
+ var year = parseInt(target.text(), 10)||0;
248
+ this.viewDate.setFullYear(year);
249
+ }
250
+ this.showMode(-1);
251
+ this.fill();
252
+ break;
253
+ case 'td':
254
+ if (target.is('.day')){
255
+ var day = parseInt(target.text(), 10)||1;
256
+ var month = this.viewDate.getMonth();
257
+ if (target.is('.old')) {
258
+ month -= 1;
259
+ } else if (target.is('.new')) {
260
+ month += 1;
261
+ }
262
+ var year = this.viewDate.getFullYear();
263
+ this.date = new Date(year, month, day,0,0,0,0);
264
+ this.viewDate = new Date(year, month, day,0,0,0,0);
265
+ this.fill();
266
+ this.setValue();
267
+ this.element.trigger({
268
+ type: 'changeDate',
269
+ date: this.date
270
+ });
271
+ }
272
+ break;
273
+ }
274
+ }
275
+ },
276
+
277
+ mousedown: function(e){
278
+ e.stopPropagation();
279
+ e.preventDefault();
280
+ },
281
+
282
+ showMode: function(dir) {
283
+ if (dir) {
284
+ this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
285
+ }
286
+ this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
287
+ }
288
+ };
289
+
290
+ $.fn.datepicker = function ( option ) {
291
+ return this.each(function () {
292
+ var $this = $(this),
293
+ data = $this.data('datepicker'),
294
+ options = typeof option == 'object' && option;
295
+ if (!data) {
296
+ $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
297
+ }
298
+ if (typeof option == 'string') data[option]();
299
+ });
300
+ };
301
+
302
+ $.fn.datepicker.defaults = {
303
+ };
304
+ $.fn.datepicker.Constructor = Datepicker;
305
+
306
+ var DPGlobal = {
307
+ modes: [
308
+ {
309
+ clsName: 'days',
310
+ navFnc: 'Month',
311
+ navStep: 1
312
+ },
313
+ {
314
+ clsName: 'months',
315
+ navFnc: 'FullYear',
316
+ navStep: 1
317
+ },
318
+ {
319
+ clsName: 'years',
320
+ navFnc: 'FullYear',
321
+ navStep: 10
322
+ }],
323
+ dates:{
324
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
325
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
326
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
327
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
328
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
329
+ },
330
+ isLeapYear: function (year) {
331
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
332
+ },
333
+ getDaysInMonth: function (year, month) {
334
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
335
+ },
336
+ parseFormat: function(format){
337
+ var separator = format.match(/[.\/-].*?/),
338
+ parts = format.split(/\W+/);
339
+ if (!separator || !parts || parts.length == 0){
340
+ throw new Error("Invalid date format.");
341
+ }
342
+ return {separator: separator, parts: parts};
343
+ },
344
+ parseDate: function(date, format) {
345
+ var parts = date.split(format.separator),
346
+ date = new Date(1970, 1, 1, 0, 0, 0),
347
+ val;
348
+ if (parts.length == format.parts.length) {
349
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
350
+ val = parseInt(parts[i], 10)||1;
351
+ switch(format.parts[i]) {
352
+ case 'dd':
353
+ case 'd':
354
+ date.setDate(val);
355
+ break;
356
+ case 'mm':
357
+ case 'm':
358
+ date.setMonth(val - 1);
359
+ break;
360
+ case 'yy':
361
+ date.setFullYear(2000 + val);
362
+ break;
363
+ case 'yyyy':
364
+ date.setFullYear(val);
365
+ break;
366
+ }
367
+ }
368
+ }
369
+ return date;
370
+ },
371
+ formatDate: function(date, format){
372
+ var val = {
373
+ d: date.getDate(),
374
+ m: date.getMonth() + 1,
375
+ yy: date.getFullYear().toString().substring(2),
376
+ yyyy: date.getFullYear()
377
+ };
378
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
379
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
380
+ var date = [];
381
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
382
+ date.push(val[format.parts[i]]);
383
+ }
384
+ return date.join(format.separator);
385
+ },
386
+ headTemplate: '<thead>'+
387
+ '<tr>'+
388
+ '<th class="prev"><i class="icon-arrow-left"/></th>'+
389
+ '<th colspan="5" class="switch"></th>'+
390
+ '<th class="next"><i class="icon-arrow-right"/></th>'+
391
+ '</tr>'+
392
+ '</thead>',
393
+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
394
+ };
395
+ DPGlobal.template = '<div class="datepicker dropdown-menu">'+
396
+ '<div class="datepicker-days">'+
397
+ '<table class=" table-condensed">'+
398
+ DPGlobal.headTemplate+
399
+ '<tbody></tbody>'+
400
+ '</table>'+
401
+ '</div>'+
402
+ '<div class="datepicker-months">'+
403
+ '<table class="table-condensed">'+
404
+ DPGlobal.headTemplate+
405
+ DPGlobal.contTemplate+
406
+ '</table>'+
407
+ '</div>'+
408
+ '<div class="datepicker-years">'+
409
+ '<table class="table-condensed">'+
410
+ DPGlobal.headTemplate+
411
+ DPGlobal.contTemplate+
412
+ '</table>'+
413
+ '</div>'+
414
+ '</div>';
415
+
416
+ }( window.jQuery )
@@ -0,0 +1 @@
1
+ //= require ./bootstrap-datepicker
@@ -0,0 +1,156 @@
1
+ /*!
2
+ * Datepicker for Bootstrap
3
+ *
4
+ * Copyright 2012 Stefan Petre
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ */
9
+ .datepicker {
10
+ top: 0;
11
+ left: 0;
12
+ padding: 4px;
13
+ margin-top: 1px;
14
+ -webkit-border-radius: 4px;
15
+ -moz-border-radius: 4px;
16
+ border-radius: 4px;
17
+ /*.dow {
18
+ border-top: 1px solid #ddd !important;
19
+ }*/
20
+ }
21
+ .datepicker:before {
22
+ content: '';
23
+ display: inline-block;
24
+ border-left: 7px solid transparent;
25
+ border-right: 7px solid transparent;
26
+ border-bottom: 7px solid #ccc;
27
+ border-bottom-color: rgba(0, 0, 0, 0.2);
28
+ position: absolute;
29
+ top: -7px;
30
+ left: 6px;
31
+ }
32
+ .datepicker:after {
33
+ content: '';
34
+ display: inline-block;
35
+ border-left: 6px solid transparent;
36
+ border-right: 6px solid transparent;
37
+ border-bottom: 6px solid #ffffff;
38
+ position: absolute;
39
+ top: -6px;
40
+ left: 7px;
41
+ }
42
+ .datepicker > div {
43
+ display: none;
44
+ }
45
+ .datepicker table {
46
+ width: 100%;
47
+ margin: 0;
48
+ }
49
+ .datepicker td, .datepicker th {
50
+ text-align: center;
51
+ width: 20px;
52
+ height: 20px;
53
+ -webkit-border-radius: 4px;
54
+ -moz-border-radius: 4px;
55
+ border-radius: 4px;
56
+ }
57
+ .datepicker td.day:hover {
58
+ background: #eeeeee;
59
+ cursor: pointer;
60
+ }
61
+ .datepicker td.old, .datepicker td.new {
62
+ color: #999999;
63
+ }
64
+ .datepicker td.active, .datepicker td.active:hover {
65
+ background-color: #006dcc;
66
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
67
+ background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
68
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
69
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
70
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
71
+ background-image: linear-gradient(top, #0088cc, #0044cc);
72
+ background-repeat: repeat-x;
73
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
74
+ border-color: #0044cc #0044cc #002a80;
75
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
76
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
77
+ color: #fff;
78
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
79
+ }
80
+ .datepicker td.active:hover,
81
+ .datepicker td.active:hover:hover,
82
+ .datepicker td.active:active,
83
+ .datepicker td.active:hover:active,
84
+ .datepicker td.active.active,
85
+ .datepicker td.active:hover.active,
86
+ .datepicker td.active.disabled,
87
+ .datepicker td.active:hover.disabled,
88
+ .datepicker td.active[disabled],
89
+ .datepicker td.active:hover[disabled] {
90
+ background-color: #0044cc;
91
+ }
92
+ .datepicker td.active:active,
93
+ .datepicker td.active:hover:active,
94
+ .datepicker td.active.active,
95
+ .datepicker td.active:hover.active {
96
+ background-color: #003399 \9;
97
+ }
98
+ .datepicker td span {
99
+ display: block;
100
+ width: 47px;
101
+ height: 54px;
102
+ line-height: 54px;
103
+ float: left;
104
+ margin: 2px;
105
+ cursor: pointer;
106
+ -webkit-border-radius: 4px;
107
+ -moz-border-radius: 4px;
108
+ border-radius: 4px;
109
+ }
110
+ .datepicker td span:hover {
111
+ background: #eeeeee;
112
+ }
113
+ .datepicker td span.active {
114
+ background-color: #006dcc;
115
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
116
+ background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
117
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
118
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
119
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
120
+ background-image: linear-gradient(top, #0088cc, #0044cc);
121
+ background-repeat: repeat-x;
122
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
123
+ border-color: #0044cc #0044cc #002a80;
124
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
125
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
126
+ color: #fff;
127
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
128
+ }
129
+ .datepicker td span.active:hover,
130
+ .datepicker td span.active:active,
131
+ .datepicker td span.active.active,
132
+ .datepicker td span.active.disabled,
133
+ .datepicker td span.active[disabled] {
134
+ background-color: #0044cc;
135
+ }
136
+ .datepicker td span.active:active, .datepicker td span.active.active {
137
+ background-color: #003399 \9;
138
+ }
139
+ .datepicker td span.old {
140
+ color: #999999;
141
+ }
142
+ .datepicker th.switch {
143
+ width: 145px;
144
+ }
145
+ .datepicker thead tr:first-child th {
146
+ cursor: pointer;
147
+ }
148
+ .datepicker thead tr:first-child th:hover {
149
+ background: #eeeeee;
150
+ }
151
+ .input-append.date .add-on i, .input-prepend.date .add-on i {
152
+ display: block;
153
+ cursor: pointer;
154
+ width: 16px;
155
+ height: 16px;
156
+ }
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bootstrap_datepicker
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.5'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alberto Pastor
9
+ - Derek Willian Stavis
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-08-07 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: twitter-bootstrap-rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 2.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 2.1.1
31
+ description: View helper that allows to select dates from a calendar (using jQuery
32
+ and Twitter Bootstrap styles)
33
+ email: dekestavis@gmail.com
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files:
37
+ - README.rdoc
38
+ - lib/app/helpers/datepicker_helper.rb
39
+ - lib/app/helpers/form_helper.rb
40
+ - lib/bootstrap_datepicker.rb
41
+ files:
42
+ - README.rdoc
43
+ - Rakefile
44
+ - init.rb
45
+ - bootstrap_datepicker.gemspec
46
+ - lib/app/helpers/datepicker_helper.rb
47
+ - lib/app/helpers/form_helper.rb
48
+ - lib/bootstrap_datepicker.rb
49
+ - lib/engine.rb
50
+ - vendor/assets/javascripts/bootstrap-datepicker.js
51
+ - vendor/assets/javascripts/index.js
52
+ - vendor/assets/stylesheets/bootstrap-datepicker.css
53
+ homepage: http://github.com/derekstavis/bootstrap_datepicker
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --line-numbers
58
+ - --inline-source
59
+ - --title
60
+ - bootstrap_datepicker
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '1.2'
77
+ requirements: []
78
+ rubyforge_project: bootstrap_datepicker
79
+ rubygems_version: 1.8.24
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: View helper that allows to select dates from a calendar (using jQuery and
83
+ Twitter Bootstrap styles)
84
+ test_files: []