anjlab-widgets 0.0.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Anjlab::Widgets
2
2
 
3
- TODO: Write a gem description
3
+ Bootstrap date and time pickers for rails (ready for rails 4).
4
+
5
+ Note: `simple_form` gem is supported.
6
+
7
+ Currently `en` and `ru` locales supported.
4
8
 
5
9
  ## Installation
6
10
 
@@ -12,13 +16,84 @@ And then execute:
12
16
 
13
17
  $ bundle
14
18
 
15
- Or install it yourself as:
19
+ ## Usage
20
+
21
+ Add date and time pickers to your application.js
16
22
 
17
- $ gem install anjlab-widgets
23
+ ```javascript
24
+ //= require anjlab/datepicker
25
+ //= require anjlab/timepicker
26
+ ```
18
27
 
19
- ## Usage
28
+ Add date and time pickers to your application.css.scss
29
+
30
+ ```scss
31
+ @import 'twitter/bootstrap';
32
+
33
+ @import 'anjlab/datepicker';
34
+ @import 'anjlab/timepicker';
35
+ ```
36
+
37
+ ### With FormBuilder
38
+
39
+ ```erb
40
+ <%= f.text_field :updated_at, value: Anjlab::Widgets.format_date(f.object.updated_at), "data-widget"=>"datepicker" %>
41
+ <%= f.text_field :updated_at, value: Anjlab::Widgets.format_time(f.object.updated_at), "data-widget"=>"timepicker" %>
42
+ ```
43
+
44
+ ### With simple_form!
45
+
46
+ You have two options here:
47
+
48
+ Overwrite standart :date, :datetime and :time inputs:
49
+
50
+ ```ruby
51
+ # config/initializers/simple_form.rb
52
+ SimpleForm.setup do |config|
53
+ Anjlab::Widgets.simple_form as_default: true
54
+ #...
55
+ end
56
+ ```
57
+ In your forms:
58
+
59
+ ```erb
60
+ <%= f.input :created_at # :datetime %>
61
+ <%= f.input :created_at, as: :date %>
62
+ <%= f.input :created_at, as: :time %>
63
+ ```
64
+
65
+ Or use prefixed input types:
66
+
67
+ ```ruby
68
+ # config/initializers/simple_form.rb
69
+ SimpleForm.setup do |config|
70
+ Anjlab::Widgets.simple_form
71
+ #...
72
+ end
73
+ ```
74
+
75
+ In your forms:
76
+
77
+ ```erb
78
+ <%= f.input :created_at, as: :anjlab_datetime %>
79
+ <%= f.input :created_at, as: :anjlab_date %>
80
+ <%= f.input :created_at, as: :anjlab_time %>
81
+ ```
82
+
83
+ ## Screen shots
84
+
85
+ ### Desktop
86
+ ![date picker](https://raw.github.com/anjlab/anjlab-widgets/master/date_pic.png)
87
+
88
+ ![time picker](https://raw.github.com/anjlab/anjlab-widgets/master/time_pic.png)
89
+
90
+ ### Mobile native
91
+
92
+ Converts to native controls if possible (except Chrome - it has ugly native controls).
93
+
94
+ ![native date picker](https://raw.github.com/anjlab/anjlab-widgets/master/native_date_pic.PNG)
20
95
 
21
- TODO: Write usage instructions here
96
+ ![native time picker](https://raw.github.com/anjlab/anjlab-widgets/master/native_time_pic.PNG)
22
97
 
23
98
  ## Contributing
24
99
 
File without changes
@@ -125,10 +125,40 @@ DateTools.template = '<div class="datepicker dropdown-menu">'+
125
125
  '</div>'+
126
126
  '</div>'
127
127
 
128
- class Datepicker
129
-
128
+ class NativeRailsDatepicker
130
129
  constructor: (element, options)->
131
130
  @element = $(element)
131
+ @rails = options.rails ? @element.data('rails') ? false
132
+
133
+ @element.on {
134
+ keyup: $.proxy(@update, this)
135
+ change: $.proxy(@update, this)
136
+ }
137
+
138
+ update: ->
139
+ @date = DateTools.parseDate @element.val(), {
140
+ separator: '-'
141
+ parts: ["yyyy", "mm", "dd"]
142
+ }
143
+
144
+ @updateRails()
145
+
146
+ updateRails: ->
147
+ return if !@rails
148
+
149
+ parent = @element.closest('.controls, form, div')
150
+ if @date == null
151
+ parent.find('.js-aw-1i, .js-aw-2i, .js-aw-3i').val('')
152
+ else
153
+ parent.find('.js-aw-1i').val(@date.getFullYear())
154
+ parent.find('.js-aw-2i').val(@date.getMonth() + 1)
155
+ parent.find('.js-aw-3i').val(@date.getDate())
156
+
157
+
158
+ class Datepicker extends NativeRailsDatepicker
159
+
160
+ constructor: (element, options)->
161
+ super(element, options)
132
162
  @locale = options.locale || @element.data('date-locale') || DateTools.getLocale()
133
163
  @format = DateTools.parseFormat(options.format || @element.data('date-format') || Locales[@locale].dates.format);
134
164
  @allowBlank = options.allowBlank ? @element.data('date-allow-blank') ? true
@@ -143,8 +173,9 @@ class Datepicker
143
173
  if @isInput
144
174
  @element.on {
145
175
  focus: $.proxy(@show, this)
176
+ click: $.proxy(@show, this)
146
177
  blur: $.proxy(@hide, this)
147
- keyup: $.proxy(@update, this)
178
+ keyup: $.proxy(@update, this)
148
179
  }
149
180
  else
150
181
  if @component
@@ -243,6 +274,7 @@ class Datepicker
243
274
  year = d.getFullYear()
244
275
  month = d.getMonth()
245
276
 
277
+ @updateRails()
246
278
  date = if @date != null then @date else DateTools.today()
247
279
  currentDate = if @date != null then @date.valueOf() else 0
248
280
 
@@ -363,12 +395,13 @@ $.fn.datepicker = (option) ->
363
395
  $this = $(this)
364
396
  data = $this.data('datepicker')
365
397
  options = typeof option == 'object' && option
366
- if nativePicker
367
- convertToNative($this, options)
368
- else
369
- if !data
398
+ if !data
399
+ if nativePicker
400
+ convertToNative($this, options)
401
+ $this.data('datepicker', (data = new NativeRailsDatepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
402
+ else
370
403
  $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))))
371
- data[option]() if typeof option == 'string'
404
+ data[option]() if typeof option == 'string'
372
405
 
373
406
  $.fn.datepicker.defaults = { }
374
407
  $.fn.datepicker.Constructor = Datepicker
@@ -377,7 +410,8 @@ $ ->
377
410
  input = document.createElement("input")
378
411
  input.setAttribute("type", "date")
379
412
  # Chrome has ugly native date picker so we show ours
413
+ # nativePicker = input.type == "date"
380
414
  nativePicker = input.type == "date" && !navigator.userAgent.match(/chrome/i)
381
415
 
382
416
  $("input[data-widget=datepicker]").datepicker()
383
-
417
+ $(document).on 'focus.data-api click.data-api touchstart.data-api', 'input[data-widget=datepicker]', (e)-> $(e.target).datepicker()
@@ -2,10 +2,35 @@ TimeTools =
2
2
 
3
3
  template: "<div class='timepicker dropdown-menu'><div class='times'></div></div>"
4
4
 
5
- class Timepicker
6
-
5
+ class NativeRailsTimepicker
7
6
  constructor: (element, options)->
8
7
  @element = $(element)
8
+ @rails = options.rails ? @element.data('rails') ? false
9
+
10
+ @element.on {
11
+ keyup: $.proxy(@update, this)
12
+ change: $.proxy(@update, this)
13
+ }
14
+
15
+ update: ->
16
+ @time = @element.val()
17
+ @updateRails()
18
+
19
+ updateRails: ->
20
+ return if !@rails
21
+ parent = @element.closest('.controls, form, div')
22
+ parts = @time.split(':')
23
+ if parts.length == 2
24
+ parent.find('.js-aw-4i').val(parts[0])
25
+ parent.find('.js-aw-5i').val(parts[1])
26
+ else
27
+ parent.find('.js-aw-4i, .js-aw-5i').val('')
28
+
29
+ class Timepicker extends NativeRailsTimepicker
30
+
31
+ constructor: (element, options)->
32
+ super(element, options)
33
+
9
34
  @picker = $(TimeTools.template).appendTo('body').on({
10
35
  click: $.proxy(@click, this)
11
36
  mousedown: $.proxy(@mousedown, this)
@@ -13,13 +38,15 @@ class Timepicker
13
38
 
14
39
  @element.on {
15
40
  focus: $.proxy(@show, this)
41
+ click: $.proxy(@show, this)
16
42
  blur: $.proxy(@hide, this)
17
- keyup: $.proxy(@update, this)
43
+
18
44
  }
19
45
 
20
46
  @step = options.step || @element.data('date-time-step') || 30
21
47
  @minTime = options.minTime || @element.data('date-time-min') || 9 * 60
22
48
  @maxTime = options.maxTime || @element.data('date-time-max') || 20 * 60
49
+
23
50
 
24
51
  @fillTimes()
25
52
  @update()
@@ -45,13 +72,14 @@ class Timepicker
45
72
  type: 'changeDate'
46
73
  date: @time
47
74
  }
75
+ @hide()
48
76
 
49
77
  mousedown: (e)->
50
78
  e.stopPropagation()
51
79
  e.preventDefault()
52
80
 
53
81
  update: ->
54
- @time = this.element.val()
82
+ super()
55
83
  @picker.find('a.active').removeClass('active')
56
84
  @picker.find("a[data-time='#{@time}']").addClass('active')
57
85
 
@@ -113,23 +141,24 @@ nativePicker = false
113
141
  $.fn.timepicker = (option) ->
114
142
  @each ->
115
143
  $this = $(this)
116
- if nativePicker
117
- $this.prop("type", "time")
118
- else
119
- data = $this.data('timepicker')
120
- options = typeof option == 'object' && option
121
- if !data
144
+ data = $this.data('timepicker')
145
+ options = typeof option == 'object' && option
146
+ if !data
147
+ if nativePicker
148
+ $this.prop('type', 'time')
149
+ $this.data('timepicker', (data = new NativeRailsTimepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
150
+ else
122
151
  $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
123
- data[option]() if typeof option == 'string'
152
+ data[option]() if typeof option == 'string'
124
153
 
125
154
  $.fn.timepicker.defaults = { }
126
155
  $.fn.timepicker.Constructor = Timepicker
127
156
 
128
157
  $ ->
129
- input = document.createElement("input")
130
- input.setAttribute("type", "time")
131
- nativePicker = input.type == "time"
158
+ input = document.createElement('input')
159
+ input.setAttribute('type', 'time')
160
+ # skip ugly chrome native control for now
161
+ nativePicker = input.type == 'time' && !navigator.userAgent.match(/chrome/i)
132
162
 
133
163
  $("input[data-widget=timepicker]").timepicker()
134
-
135
-
164
+ $(document).on 'focus.data-api click.data-api touchstart.data-api', 'input[data-widget=timepicker]', (e)-> $(e.target).timepicker()
@@ -15,6 +15,8 @@
15
15
 
16
16
  a {
17
17
  @include border-radius(4px);
18
+ display: block;
19
+ padding: 0 1em;
18
20
 
19
21
  &:hover {
20
22
  background: $grayLighter;
data/date_pic.png ADDED
Binary file
@@ -0,0 +1,53 @@
1
+ module Anjlab
2
+ module Widgets
3
+ class DateTimeInput < SimpleForm::Inputs::DateTimeInput
4
+
5
+ def label_target
6
+ attribute_name
7
+ end
8
+
9
+ def input
10
+ time = options[:value] || @builder.object[attribute_name]
11
+
12
+ html = ''
13
+
14
+ allow_blank = !options[:required]
15
+
16
+ date_data = {
17
+ "data-widget" => "datepicker",
18
+ "data-rails" => true,
19
+ "data-date-allow-blank" => allow_blank,
20
+ :value => Widgets::format_date(time),
21
+ :required => input_html_options[:required],
22
+ :class => "#{input_html_options[:date_class] || 'input-small'}"
23
+ }
24
+
25
+ time_data = {
26
+ "data-widget" => "timepicker",
27
+ "data-rails" => true,
28
+ :value => Widgets::format_time(time),
29
+ :required => input_html_options[:required],
30
+ :class => "#{input_html_options[:time_class] || 'input-small'}"
31
+ }
32
+
33
+ case input_type
34
+ when :datetime, :anjlab_datetime
35
+ html << @builder.text_field(attribute_name, date_data)
36
+ html << '&nbsp;&nbsp;&nbsp;'
37
+ html << @builder.text_field(attribute_name, time_data)
38
+ when :date, :anjlab_date
39
+ html << @builder.text_field(attribute_name, date_data)
40
+ when :time, :anjlab_time
41
+ html << @builder.text_field(attribute_name, time_data)
42
+ end
43
+
44
+ values = time ? [time.year, time.month, time.day, time.hour, time.min] : [''] * 5
45
+ values.each_with_index do |v, index|
46
+ i = index + 1
47
+ html << @builder.hidden_field("#{attribute_name}(#{i}i)", value: v, class: "js-aw-#{i}i")
48
+ end
49
+ html
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,5 +1,5 @@
1
1
  module Anjlab
2
2
  module Widgets
3
- VERSION = "0.0.8"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -67,8 +67,16 @@ module Anjlab
67
67
  end
68
68
 
69
69
  def self.format_time time
70
- nil if time.nil?
70
+ return '' if time.nil?
71
71
  time.strftime "%H:%M"
72
72
  end
73
+
74
+ def self.simple_form options={}
75
+ require 'anjlab-widgets/simple_form'
76
+ SimpleForm::FormBuilder.map_type :anjlab_date, :anjlab_time, :anjlab_datetime, to: DateTimeInput
77
+ if options[:as_default]
78
+ SimpleForm::FormBuilder.map_type :date, :time, :datetime, to: DateTimeInput
79
+ end
80
+ end
73
81
  end
74
82
  end
Binary file
Binary file
data/time_pic.png ADDED
Binary file
metadata CHANGED
@@ -2,94 +2,94 @@
2
2
  name: anjlab-widgets
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.8
5
+ version: 1.0.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Yury Korolev
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
12
+ date: 2013-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
+ name: anjlab-bootstrap-rails
15
16
  version_requirements: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: 2.0.3
20
- none: false
21
- prerelease: false
22
- name: anjlab-bootstrap-rails
23
22
  requirement: !ruby/object:Gem::Requirement
23
+ none: false
24
24
  requirements:
25
25
  - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: 2.0.3
28
- none: false
28
+ prerelease: false
29
29
  type: :runtime
30
30
  - !ruby/object:Gem::Dependency
31
+ name: rails
31
32
  version_requirements: !ruby/object:Gem::Requirement
33
+ none: false
32
34
  requirements:
33
35
  - - ! '>='
34
36
  - !ruby/object:Gem::Version
35
37
  version: '3.2'
36
- none: false
37
- prerelease: false
38
- name: rails
39
38
  requirement: !ruby/object:Gem::Requirement
39
+ none: false
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
43
  version: '3.2'
44
- none: false
44
+ prerelease: false
45
45
  type: :development
46
46
  - !ruby/object:Gem::Dependency
47
+ name: bundler
47
48
  version_requirements: !ruby/object:Gem::Requirement
49
+ none: false
48
50
  requirements:
49
51
  - - ! '>='
50
52
  - !ruby/object:Gem::Version
51
53
  version: '1.0'
52
- none: false
53
- prerelease: false
54
- name: bundler
55
54
  requirement: !ruby/object:Gem::Requirement
55
+ none: false
56
56
  requirements:
57
57
  - - ! '>='
58
58
  - !ruby/object:Gem::Version
59
59
  version: '1.0'
60
- none: false
60
+ prerelease: false
61
61
  type: :development
62
62
  - !ruby/object:Gem::Dependency
63
+ name: sqlite3
63
64
  version_requirements: !ruby/object:Gem::Requirement
65
+ none: false
64
66
  requirements:
65
67
  - - ! '>='
66
68
  - !ruby/object:Gem::Version
67
69
  version: '0'
68
- none: false
69
- prerelease: false
70
- name: sqlite3
71
70
  requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
72
  requirements:
73
73
  - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- none: false
76
+ prerelease: false
77
77
  type: :development
78
78
  - !ruby/object:Gem::Dependency
79
+ name: rspec-rails
79
80
  version_requirements: !ruby/object:Gem::Requirement
81
+ none: false
80
82
  requirements:
81
83
  - - ! '>='
82
84
  - !ruby/object:Gem::Version
83
85
  version: 2.9.0
84
- none: false
85
- prerelease: false
86
- name: rspec-rails
87
86
  requirement: !ruby/object:Gem::Requirement
87
+ none: false
88
88
  requirements:
89
89
  - - ! '>='
90
90
  - !ruby/object:Gem::Version
91
91
  version: 2.9.0
92
- none: false
92
+ prerelease: false
93
93
  type: :development
94
94
  description: Collection of UI widgets on top of anjlab-bootstrap-rails. Datepicker
95
95
  and Timepicker for now.
@@ -105,9 +105,21 @@ files:
105
105
  - README.md
106
106
  - Rakefile
107
107
  - anjlab-widgets.gemspec
108
+ - app/assets/images/ajax-loader.gif
109
+ - app/assets/javascripts/anjlab/datepicker.js.coffee
110
+ - app/assets/javascripts/anjlab/timepicker.js.coffee
111
+ - app/assets/javascripts/bootstrap-modal.js
112
+ - app/assets/javascripts/bootstrap-modalmanager.js
113
+ - app/assets/stylesheets/anjlab/datepicker.css.scss
114
+ - app/assets/stylesheets/anjlab/timepicker.css.scss
115
+ - app/assets/stylesheets/bootstrap-modal.css
116
+ - date_pic.png
108
117
  - lib/anjlab-widgets.rb
109
118
  - lib/anjlab-widgets/engine.rb
119
+ - lib/anjlab-widgets/simple_form.rb
110
120
  - lib/anjlab-widgets/version.rb
121
+ - native_date_pic.PNG
122
+ - native_time_pic.PNG
111
123
  - spec/dummy/README.rdoc
112
124
  - spec/dummy/Rakefile
113
125
  - spec/dummy/app/assets/javascripts/application.js
@@ -147,14 +159,7 @@ files:
147
159
  - spec/dummy/script/rails
148
160
  - spec/spec_helper.rb
149
161
  - spec/views/widgets/datepicker_spec.rb
150
- - vendor/assets/images/ajax-loader.gif
151
- - vendor/assets/javascripts/anjlab/datepicker.js.coffee
152
- - vendor/assets/javascripts/anjlab/timepicker.js.coffee
153
- - vendor/assets/javascripts/bootstrap-modal.js
154
- - vendor/assets/javascripts/bootstrap-modalmanager.js
155
- - vendor/assets/stylesheets/anjlab/datepicker.css.scss
156
- - vendor/assets/stylesheets/anjlab/timepicker.css.scss
157
- - vendor/assets/stylesheets/bootstrap-modal.css
162
+ - time_pic.png
158
163
  homepage: https://github.com/anjlab/anjlab-widgets
159
164
  licenses: []
160
165
  post_install_message:
@@ -162,23 +167,23 @@ rdoc_options: []
162
167
  require_paths:
163
168
  - lib
164
169
  required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
165
171
  requirements:
166
172
  - - ! '>='
167
173
  - !ruby/object:Gem::Version
168
174
  version: '0'
175
+ hash: 1068616150774873195
169
176
  segments:
170
177
  - 0
171
- hash: 2463130067864864405
172
- none: false
173
178
  required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
174
180
  requirements:
175
181
  - - ! '>='
176
182
  - !ruby/object:Gem::Version
177
183
  version: '0'
184
+ hash: 1068616150774873195
178
185
  segments:
179
186
  - 0
180
- hash: 2463130067864864405
181
- none: false
182
187
  requirements: []
183
188
  rubyforge_project:
184
189
  rubygems_version: 1.8.24