caisson 0.0.1 → 0.0.2

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.
Files changed (43) hide show
  1. data/README.md +13 -1
  2. data/app/assets/javascripts/caisson/base.coffee +4 -0
  3. data/app/assets/javascripts/caisson/form/fields/base.coffee +115 -0
  4. data/app/assets/javascripts/caisson/form/fields/checkbox.coffee +13 -0
  5. data/app/assets/javascripts/caisson/form/fields/select.coffee +14 -0
  6. data/app/assets/javascripts/caisson/form/fields/text_field.coffee +22 -0
  7. data/app/assets/javascripts/caisson/form/fields/validator.coffee +116 -0
  8. data/app/assets/javascripts/caisson/form/form.coffee +119 -0
  9. data/app/assets/javascripts/caisson/form/form_caisson.coffee +30 -0
  10. data/app/assets/javascripts/caisson/index.js +2 -0
  11. data/app/assets/javascripts/caisson/module.coffee +8 -0
  12. data/app/assets/javascripts/caisson/orbit-slider.coffee +2 -1
  13. data/app/assets/stylesheets/caisson/base.css.scss +7 -0
  14. data/app/assets/stylesheets/caisson/index.css +3 -0
  15. data/lib/caisson/helpers/form/base.rb +195 -0
  16. data/lib/caisson/helpers/form/builder/base.rb +72 -0
  17. data/lib/caisson/helpers/form/builder/field/base.rb +168 -0
  18. data/lib/caisson/helpers/form/builder/field/checkbox.rb +15 -0
  19. data/lib/caisson/helpers/form/builder/field/money.rb +13 -0
  20. data/lib/caisson/helpers/form/builder/field/password.rb +13 -0
  21. data/lib/caisson/helpers/form/builder/field/percent.rb +13 -0
  22. data/lib/caisson/helpers/form/builder/field/select.rb +41 -0
  23. data/lib/caisson/helpers/form/builder/field/text.rb +13 -0
  24. data/lib/caisson/helpers/form/builder/field/textarea.rb +13 -0
  25. data/lib/caisson/helpers/form/builder/field_builder/base.rb +81 -0
  26. data/lib/caisson/helpers/form/builder/field_builder/nature.rb +85 -0
  27. data/lib/caisson/helpers/form/builder/interpreti.rb +107 -0
  28. data/lib/caisson/helpers/form/button.rb +62 -0
  29. data/lib/caisson/helpers/form/field/base.rb +43 -0
  30. data/lib/caisson/helpers/form/field/checkbox.rb +39 -0
  31. data/lib/caisson/helpers/form/field/money.rb +29 -0
  32. data/lib/caisson/helpers/form/field/password.rb +14 -0
  33. data/lib/caisson/helpers/form/field/percent.rb +23 -0
  34. data/lib/caisson/helpers/form/field/select.rb +34 -0
  35. data/lib/caisson/helpers/form/field/text.rb +17 -0
  36. data/lib/caisson/helpers/form/field/textarea.rb +16 -0
  37. data/lib/caisson/helpers/form.rb +30 -0
  38. data/lib/caisson/helpers/grid.rb +32 -0
  39. data/lib/caisson/helpers/orbit_slider.rb +16 -21
  40. data/lib/caisson/helpers.rb +26 -0
  41. data/lib/caisson/implants/mongoid.rb +67 -0
  42. data/lib/caisson/implants/railtie.rb +4 -0
  43. metadata +41 -6
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Caisson
2
2
  ===============
3
3
 
4
- Caisson will provide a set of tools to facilitate the integration of Zurb-Foundation to your Rails project.
4
+ Caisson provide a set of tools to facilitate the integration of Zurb-Foundation to your Rails project.
5
5
 
6
6
  Install
7
7
  -------
@@ -19,6 +19,18 @@ gem 'zurb-foundation'
19
19
  gem 'caisson'
20
20
  ```
21
21
 
22
+ In your application.js
23
+
24
+ ```javascript
25
+ //= require foundation
26
+ //= require caisson
27
+ ```
28
+
29
+ In your application.scss
30
+ ```css
31
+ @import "foundation";
32
+ ```
33
+
22
34
  Orbit Slider
23
35
  -----
24
36
 
@@ -1,5 +1,9 @@
1
1
  class Caisson
2
2
  constructor: () ->
3
+ $(document).foundation()
4
+
5
+ FormCaisson.load()
6
+
3
7
  $('div[data-caisson]').each (i, component) =>
4
8
  switch $(component).data('caisson')
5
9
  when 'orbit-slider' then new OrbitSlider $(component)
@@ -0,0 +1,115 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ @caissonMod "Field", ->
6
+ class @Base
7
+ #*************************************************************************************
8
+ # CONSTRUCTOR
9
+ #*************************************************************************************
10
+ constructor: (@field) ->
11
+ @build()
12
+
13
+ #*************************************************************************************
14
+ # PUBLIC INSTANCE METHODS
15
+ #*************************************************************************************
16
+ build: () ->
17
+ @initPlaceholder()
18
+ @tagField()
19
+
20
+ @field.on('validate', (e) => @validate())
21
+ @field.blur (e) => @validate() if @hasErrors()
22
+
23
+
24
+ closest: (path) -> @field.closest(path)
25
+
26
+ data: (key, val) -> @field.data key, val
27
+
28
+
29
+ hasApproximateName: (names) ->
30
+ return name for name in names when name is @field.attr('name') or @field.attr('name').indexOf("[#{name}]") > 0
31
+
32
+ return ''
33
+
34
+
35
+ hideErrors: ->
36
+ @wrapper().removeClass('errors')
37
+ @wrapper().find('div.error-messages').fadeOut 500, -> $(this).remove()
38
+ $('#form-caisson-flash-' + @id()).fadeOut 500, -> $(this).remove()
39
+
40
+
41
+ find: (key) -> @field.find key
42
+
43
+ hasErrors: -> @wrapper().hasClass('errors')
44
+
45
+ id: () -> @field.attr('id')
46
+
47
+ input: () -> if @field[0].tagName.toLowerCase() == 'input' then @field else $(@field.find('input'))
48
+
49
+ isPlaceholder: () -> @field.attr('placeholder') isnt undefined
50
+
51
+ isSubmitAuto: () -> @field.data('submit') is 1
52
+
53
+ label: () -> @wrapper().find('label')
54
+
55
+ labelText: () -> @label().text()
56
+
57
+ showErrors: (messages) ->
58
+ @removeErrorMessages()
59
+ @wrapper().addClass('errors')
60
+ @popErrors messages
61
+
62
+
63
+ validate: () ->
64
+ v = @validator()
65
+
66
+ if v.validate() then @hideErrors() else @showErrors v.messages
67
+
68
+
69
+ validateWithAjax: (url, caller, callback) ->
70
+ $.getJSON url, (data) =>
71
+ if data['state'] is 'error' then @showErrors([data['message']])
72
+ caller[callback]()
73
+
74
+
75
+ validator: () -> new FormCaisson.Field.Validator(@field.data('validations'), @field.val())
76
+
77
+ wrapper: () -> @field.closest('div.field')
78
+
79
+
80
+ #*************************************************************************************
81
+ # PRIVATE INSTANCE METHODS
82
+ #*************************************************************************************
83
+ initPlaceholder: () ->
84
+ if @isPlaceholder()
85
+ @input().placeholder()
86
+ @input().focus (e) => $(@wrapper().find('.ui-placeholder')).addClass('focus')
87
+ @input().blur (e) => $(@wrapper().find('.ui-placeholder')).removeClass('focus')
88
+
89
+
90
+ removeErrorMessages: () ->
91
+ @wrapper().find('div.error-messages').remove()
92
+ $('#form-caisson-flash-' + @id()).remove()
93
+
94
+
95
+ popErrors: (messages) ->
96
+ content = ''
97
+ content += '<span class="text">' + message + '</span>' for message in messages
98
+
99
+ flashPop = $('<div class="form-caisson-flash error" id="form-caisson-flash-' + @id() + '">').html(content)
100
+
101
+ flashPop.click () -> $(@).fadeOut(700)
102
+
103
+ if @hasErrors() then $('body').append(flashPop) else $('body').append(flashPop.hide().fadeIn(700))
104
+
105
+ align = ((@field.outerHeight() - flashPop.outerHeight()) / 2)
106
+
107
+ flashPop.css
108
+ "left": (@field.offset().left + (@field.outerWidth())) + "px"
109
+ "top": (@field.offset().top + align) + "px"
110
+
111
+
112
+ tagField: () ->
113
+ @field.data('caisson', 'field')
114
+ @field.attr('data-caisson', 'field')
115
+ @field.attr('id', 'field-caisson-' + Math.floor(Math.random()*10000)) if not @field.attr('id')
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ @caissonMod "Field", ->
6
+ class @Checkbox extends FormCaisson.Field.Base
7
+ #*************************************************************************************
8
+ # CONSTRUCTOR
9
+ #*************************************************************************************
10
+ constructor: (@field) ->
11
+ if @isSubmitAuto() then @input().change (event) => @closest('form').submit()
12
+
13
+ super @field
@@ -0,0 +1,14 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ # TODO : Add keyboard shortcuts
4
+ #*************************************************************************************
5
+ @caissonMod "FormCaisson", ->
6
+ @caissonMod "Field", ->
7
+ class @SelectField extends FormCaisson.Field.Base
8
+ #*************************************************************************************
9
+ # CONSTRUCTOR
10
+ #*************************************************************************************
11
+ constructor: (@field) ->
12
+ if @isSubmitAuto() then $(@field).change (event) => @closest('form').submit()
13
+
14
+ super @field
@@ -0,0 +1,22 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ @caissonMod "Field", ->
6
+ class @TextField extends FormCaisson.Field.Base
7
+ #*************************************************************************************
8
+ # CONSTRUCTOR
9
+ #*************************************************************************************
10
+ constructor: (@field) ->
11
+ super @field
12
+
13
+
14
+ #*************************************************************************************
15
+ # PUBLIC INSTANCE METHODS
16
+ #*************************************************************************************
17
+ #getCreditCardType: () -> @validator().getCreditCardType @field.val()
18
+
19
+
20
+ #*************************************************************************************
21
+ # PRIVATE INSTANCE METHODS
22
+ #*************************************************************************************
@@ -0,0 +1,116 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ @caissonMod "Field", ->
6
+ class @Validator
7
+ #*************************************************************************************
8
+ # CONSTRUCTOR
9
+ #*************************************************************************************
10
+ constructor: (specs, @value) ->
11
+ @specs = if specs then specs.split(' ') else []
12
+ @messages = []
13
+
14
+
15
+ #*************************************************************************************
16
+ # PUBLIC INSTANCE METHODS
17
+ #*************************************************************************************
18
+ checkSpec: (spec) ->
19
+ stripped_spec = spec.split('-')[0]
20
+
21
+ if stripped_spec is 'blank'
22
+ @isBlank()
23
+ else if @notBlank()
24
+ switch stripped_spec
25
+ when 'confirm' then @isConfirmed spec
26
+ when 'creditcard' then @isCreditCard spec
27
+ when 'creditcardname' then @isCreditCardName()
28
+ when 'creditcardexpiration' then @isCreditCardExpiration()
29
+ when 'email' then @isEmail()
30
+ when 'length' then @isLengthEql spec
31
+ when 'max' then @isMax spec
32
+ when 'min' then @isMin spec
33
+ when 'numeric' then @isNumeric()
34
+ when 'within' then @isWithin spec
35
+ else
36
+
37
+
38
+ getCreditCardType: (rawCCNumber) ->
39
+ ccNumber = rawCCNumber.replace(/(\s|-)/g, '')
40
+
41
+ if /^4[0-9]{12}(?:[0-9]{3})?$/.test(ccNumber)
42
+ 'visa'
43
+ else if /^5[1-5][0-9]{14}$/.test(ccNumber)
44
+ 'mastercard'
45
+ else if /^3[47][0-9]{13}$/.test(ccNumber)
46
+ 'amex'
47
+ else
48
+ ''
49
+
50
+
51
+ isValid: () -> @messages.length is 0
52
+
53
+ validate: () ->
54
+ @checkSpec spec for spec in @specs if @specs
55
+
56
+ return @isValid()
57
+
58
+
59
+ #*************************************************************************************
60
+ # PRIVATE INSTANCE METHODS
61
+ #*************************************************************************************
62
+ isBlank: () -> if @value is "" then @messages.push 'Le champ ne peut être vide.'
63
+
64
+ isConfirmed: (spec) ->
65
+ [tag, idOtherField] = spec.split('-')
66
+
67
+ if @value isnt $('#' + idOtherField).val() then @messages.push 'La confirmation est erronée'
68
+
69
+
70
+ isCreditCard: (spec) ->
71
+ types = spec.replace('creditcard-', '').split('-')
72
+ currentType = @getCreditCardType @value
73
+ if $.inArray(currentType, types) is -1 then @messages.push "Le numéro de carte de crédit est invalide."
74
+
75
+
76
+ isCreditCardName: () -> if not /^\S+ \S+/.test(@value) then @messages.push "Entrez le nom complet figurant sur votre carte."
77
+
78
+ isCreditCardExpiration: () ->
79
+ value = @value.replace('/', '').replace('-', '').replace(' ', '')
80
+
81
+ value = value.slice(0,2) + '20' + value.slice(2,4) if value.length is 4
82
+
83
+ if value.length is 6 and /^[0-9]*$/.test value
84
+ expiration = new Date(value.slice(2,6), Number(value.slice(0,2)) - 1, 31)
85
+
86
+ if expiration < new Date() then @messages.push "Votre carte de crédit est expirée."
87
+ else
88
+ @messages.push "La date d'expiration est doit avoir un format MM/AA."
89
+
90
+
91
+ isEmail: () -> if not /^[a-zA-Z0-9.\$#%+-\/=?_]+@([a-zA-Z0-9.\-]+\.)+[a-zA-Z0-9.\-]{2,6}$/.test(@value) then @messages.push 'Le courriel est invalide.'
92
+
93
+ isLengthEql: (spec) ->
94
+ [tag, length] = spec.split('-')
95
+ if @value.length != Number(length) then @messages.push "Le champ doit contenir #{length} caractères."
96
+
97
+ isMax: (spec) ->
98
+ [tag, max] = spec.split('-')
99
+ if @value.length > Number(max) then @messages.push "Le champ doit contenir moins de #{max} caractères."
100
+
101
+
102
+ isMin: (spec) ->
103
+ [tag, min] = spec.split('-')
104
+ if @value.length < Number(min) then @messages.push "Le champ doit contenir plus de #{min} caractères."
105
+
106
+
107
+ isNumeric: -> if not /^$|^([\-]?[0-9]*)?([\.,][0-9]*)?$/.test(@value) then @messages.push 'Le champ doit être numérique.'
108
+
109
+ isWithin: (spec) ->
110
+ [tag, min, max] = spec.split('-')
111
+
112
+ @isMin "min-#{min}"
113
+ @isMax "max-#{max}"
114
+
115
+
116
+ notBlank: () -> @value isnt ""
@@ -0,0 +1,119 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ class @Form
6
+ #*************************************************************************************
7
+ # CONSTRUCTOR
8
+ #*************************************************************************************
9
+ constructor: (@form) ->
10
+ @fields = []
11
+
12
+ @initFormId()
13
+ @initEvents()
14
+ @initFields()
15
+
16
+
17
+ #*************************************************************************************
18
+ # PUBLIC INSTANCE METHODS
19
+ #*************************************************************************************
20
+ field: (id) -> return f for f in @fields when f.id() is id
21
+
22
+ hasErrors: () -> @form.find('div.field.errors').length > 0
23
+
24
+ hasField: (id) -> if @field(id) then true else false
25
+
26
+ hideErrors: () -> field.hideErrors() for field in @fields
27
+
28
+ id: () -> @form.attr('id')
29
+
30
+ send: (callback) ->
31
+ if @validate()
32
+ callback = {} if not callback
33
+ callback['loading'](true) if callback['loading']
34
+
35
+ $.ajax(
36
+ type: @form.attr('method')
37
+ url: @form.attr("action") + '.json'
38
+ dataType: "json"
39
+ data: @form.serialize()
40
+ complete: (data) -> callback['loading'](false) if callback['loading']
41
+ error: (xhr, ajax_error) =>
42
+ switch xhr.status
43
+ when 400 then @setFieldErrors $.parseJSON(xhr.responseText)
44
+ when 401 then #alert '401'
45
+ else @showAjaxError xhr.responseText, ajax_error
46
+ statusCode: callback
47
+ )
48
+
49
+
50
+ validate: () ->
51
+ field.validate() for field in @fields
52
+
53
+ if @hasErrors()
54
+ @form.find('div.field.errors:first input').focus()
55
+ return false
56
+ else
57
+ return true
58
+
59
+
60
+ #*************************************************************************************
61
+ # PRIVATE INSTANCE METHODS
62
+ #*************************************************************************************
63
+ initEvents: () ->
64
+ @form.on('validate', (e) => @validate())
65
+ @form.on('send', (e) => @send())
66
+
67
+ @form.submit (e) =>
68
+ if @validate()
69
+ field.input().trigger 'before-submit-form' for field in @fields
70
+
71
+ $(e.target).find('input[type=submit]').attr 'disabled', 'disabled'
72
+ $(e.target).find('button').attr 'disabled', 'disabled'
73
+
74
+ return true
75
+ else
76
+ return false
77
+
78
+
79
+ initField: (path, fieldClass) -> @form.find(path).each (i, elem) => @fields.push new fieldClass $(elem)
80
+
81
+
82
+ initFields: ->
83
+ @initField 'input.checkbox', FormCaisson.Field.Checkbox
84
+ @initField 'select', FormCaisson.Field.SelectField
85
+ #@_initField 'div.switch-field', FormCaisson.Field.SwitchField
86
+ @initField 'input.text-field', FormCaisson.Field.TextField
87
+ #@_initField 'input.percent-field', FormCaisson.Field.PercentField
88
+ #@_initField 'input.money-field', FormCaisson.Field.MoneyField
89
+ #@_initField 'div.time-field', FormCaisson.Field.TimeField
90
+
91
+
92
+ initFormId: ->
93
+ @form.data('caisson', 'form')
94
+ @form.attr('data-caisson', 'form')
95
+ @form.attr('id', 'form-caisson-' + Math.floor(Math.random()*10000)) if not @form.attr('id')
96
+
97
+
98
+ setFieldErrors: (errors) ->
99
+ names = (k for k,v of errors)
100
+
101
+ for field in @fields
102
+ errorKey = field.hasApproximateName names
103
+
104
+ if errorKey
105
+ field.showErrors $.flatten(errors[errorKey])
106
+ else if field.hasErrors()
107
+ field.hideErrors()
108
+
109
+ return errors
110
+
111
+
112
+ showAjaxError: (message, ajax_error) ->
113
+ left = ($('body').width() - 700) / 2
114
+
115
+ pop = $('<div id="ajax-error" style="display:none;margin-left:' + left + 'px"><h1>AJAX : ' + ajax_error + '</h1>' + message + '</div>')
116
+ pop.dblclick (e) -> $(e.target).closest('div#ajax-error').remove()
117
+
118
+ $('body').before pop
119
+ pop.fadeIn(500)
@@ -0,0 +1,30 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ @caissonMod "FormCaisson", ->
5
+ #*************************************************************************************
6
+ # PUBLIC MODULE METHODS
7
+ #*************************************************************************************
8
+ @findFormById = (id) -> return form for form in @forms when form.id() is id
9
+
10
+ @findFieldById = (id) -> return form.field(id) for form in @forms when form.hasField(id)
11
+
12
+ @initForms = () -> $('form').each (i, form) => @forms.push new FormCaisson.Form $(form)
13
+
14
+ @initHelpers = () ->
15
+ $.fn.caisson = () ->
16
+ switch $(this).data('caisson')
17
+ when "form" then FormCaisson.findFormById $(this).attr('id')
18
+ when "field" then FormCaisson.findFieldById $(this).attr('id')
19
+ else FormCaisson.findFieldById $(this).closest('div[data-caisson]').attr('id') if $(this).closest('div[data-caisson]')
20
+
21
+
22
+ @load = () ->
23
+ @forms = []
24
+ @initForms()
25
+ @initHelpers()
26
+
27
+
28
+ @reload = () -> @load()
29
+
30
+
@@ -1,2 +1,4 @@
1
+ //= require ./module
1
2
  //= require ./base
3
+ //= require_tree ./form
2
4
  //= require ./orbit-slider
@@ -0,0 +1,8 @@
1
+ @caissonMod = (names, fn) ->
2
+ names = names.split '.' if typeof names is 'string'
3
+ space = @[names.shift()] ||= {}
4
+ space.caissonMod ||= @caissonMod
5
+ if names.length
6
+ space.caissonMod names, fn
7
+ else
8
+ fn.call space
@@ -3,7 +3,8 @@
3
3
  #*************************************************************************************
4
4
  class @OrbitSlider
5
5
  constructor: (@holder) ->
6
- @holder.orbit @buildAttributes()
6
+ # DEPRECATED IN VERSION 4
7
+ #@holder.orbit @buildAttributes()
7
8
 
8
9
 
9
10
  buildAttributes: () ->
@@ -0,0 +1,7 @@
1
+ @import "foundation";
2
+
3
+ div.line-checkbox{margin-bottom:1em;}
4
+ div.field-percent{
5
+ input{float:left;width:6em;}
6
+ span.postfix{float:left;width:3em;}
7
+ }
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree .
3
+ */