chr 0.2.1 → 0.2.4

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gruntfile.coffee +50 -16
  4. data/app/assets/javascripts/chr.coffee +9 -16
  5. data/app/assets/javascripts/chr/core/chr.coffee +38 -20
  6. data/app/assets/javascripts/chr/core/item.coffee +30 -24
  7. data/app/assets/javascripts/chr/core/list.coffee +30 -60
  8. data/app/assets/javascripts/chr/core/list_config.coffee +65 -0
  9. data/app/assets/javascripts/chr/core/list_pagination.coffee +27 -0
  10. data/app/assets/javascripts/chr/core/list_reorder.coffee +75 -0
  11. data/app/assets/javascripts/chr/core/list_search.coffee +41 -0
  12. data/app/assets/javascripts/chr/core/module.coffee +55 -32
  13. data/app/assets/javascripts/chr/core/utils.coffee +34 -13
  14. data/app/assets/javascripts/chr/core/view.coffee +70 -97
  15. data/app/assets/javascripts/chr/form/form.coffee +63 -49
  16. data/app/assets/javascripts/chr/form/input-checkbox.coffee +40 -27
  17. data/app/assets/javascripts/chr/form/input-color.coffee +26 -8
  18. data/app/assets/javascripts/chr/form/input-date.coffee +0 -0
  19. data/app/assets/javascripts/chr/form/input-file.coffee +81 -46
  20. data/app/assets/javascripts/chr/form/input-form.coffee +162 -0
  21. data/app/assets/javascripts/chr/form/input-form_reorder.coffee +67 -0
  22. data/app/assets/javascripts/chr/form/input-hidden.coffee +27 -11
  23. data/app/assets/javascripts/chr/form/input-list.coffee +60 -56
  24. data/app/assets/javascripts/chr/form/input-list_reorder.coffee +37 -0
  25. data/app/assets/javascripts/chr/form/input-password.coffee +31 -0
  26. data/app/assets/javascripts/chr/form/input-select.coffee +61 -35
  27. data/app/assets/javascripts/chr/form/input-string.coffee +55 -25
  28. data/app/assets/javascripts/chr/form/input-text.coffee +22 -5
  29. data/app/assets/javascripts/chr/store/mongosteen-array-store.coffee +1 -1
  30. data/app/assets/javascripts/chr/vendor/ace.js +18280 -0
  31. data/app/assets/javascripts/chr/vendor/marked.js +1272 -0
  32. data/app/assets/javascripts/chr/vendor/mode-html.js +2436 -0
  33. data/app/assets/javascripts/chr/vendor/mode-markdown.js +2820 -0
  34. data/app/assets/javascripts/chr/vendor/redactor.fixedtoolbar.js +110 -0
  35. data/app/assets/javascripts/input-html.coffee +78 -0
  36. data/app/assets/javascripts/input-markdown.coffee +88 -0
  37. data/app/assets/javascripts/input-redactor.coffee +66 -0
  38. data/app/assets/stylesheets/_chr.scss +6 -6
  39. data/app/assets/stylesheets/_input-redactor.scss +34 -0
  40. data/app/assets/stylesheets/core/_mixins.scss +75 -0
  41. data/app/assets/stylesheets/form/_input-checkbox.scss +18 -0
  42. data/app/assets/stylesheets/form/{_input_color.scss → _input-color.scss} +0 -0
  43. data/app/assets/stylesheets/form/{_input_file.scss → _input-file.scss} +1 -0
  44. data/app/assets/stylesheets/form/{_nested_form.scss → _input-form.scss} +0 -0
  45. data/app/assets/stylesheets/form/{_input_list.scss → _input-list.scss} +0 -0
  46. data/app/assets/stylesheets/form/_input-string.scss +8 -0
  47. data/bower.json +3 -2
  48. data/{app/assets/javascripts/chr-dist.js → dist/chr.js} +1472 -1337
  49. data/dist/input-ace.js +24936 -0
  50. data/dist/input-redactor.js +156 -0
  51. data/lib/chr/version.rb +1 -1
  52. data/package.json +2 -2
  53. metadata +29 -13
  54. data/app/assets/javascripts/chr/core/list-pagination.coffee +0 -26
  55. data/app/assets/javascripts/chr/core/list-reorder.coffee +0 -70
  56. data/app/assets/javascripts/chr/core/list-search.coffee +0 -37
  57. data/app/assets/javascripts/chr/form/nested-form.coffee +0 -164
  58. data/app/assets/stylesheets/form/_input_checkbox.scss +0 -91
  59. data/app/assets/stylesheets/form/_input_string.scss +0 -8
@@ -0,0 +1,162 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT "NESTED" FORM
11
+ # -----------------------------------------------------------------------------
12
+ # Name for this input comes from the Rails gem 'nested_forms'.
13
+ #
14
+ # Public methods:
15
+ # initialize()
16
+ # hash(hash)
17
+ # updateValue(@value)
18
+ # showErrorMessage(message)
19
+ # hideErrorMessage()
20
+ # addNewForm(object)
21
+ #
22
+ # Dependencies:
23
+ #= require ./input-form_reorder
24
+ #
25
+ # -----------------------------------------------------------------------------
26
+
27
+ class @InputForm
28
+ constructor: (@name, @nestedObjects, @config, @object) ->
29
+ @forms = []
30
+
31
+ @config.namePrefix ||= name
32
+ @config.removeButton = true
33
+ @config.formSchema._id = { type: 'hidden', name: 'id' }
34
+ @reorderContainerClass = "nested-forms-#{@config.klassName}"
35
+
36
+ @_create_el()
37
+
38
+ @_add_label()
39
+ @_add_forms()
40
+ @_add_new_button()
41
+
42
+ return this
43
+
44
+
45
+ # PRIVATE ===============================================
46
+
47
+ _create_el: ->
48
+ @$el =$ "<div class='input-stacked nested-forms #{ @config.klassName }'>"
49
+
50
+
51
+ _add_label: ->
52
+ @$label =$ "<span class='label'>#{ @config.label }</span>"
53
+ @$errorMessage =$ "<span class='error-message'></span>"
54
+ @$label.append(@$errorMessage)
55
+ @$el.append(@$label)
56
+
57
+
58
+ _add_forms: ->
59
+ @$forms =$ "<ul>"
60
+ @$label.after @$forms
61
+
62
+ # if not default value which means no objects
63
+ if @nestedObjects != ''
64
+ @_sort_nested_objects()
65
+
66
+ for i, object of @nestedObjects
67
+ namePrefix = "#{ @config.namePrefix }[#{ i }]"
68
+ @forms.push @_render_form(object, namePrefix, @config)
69
+
70
+ @_bind_forms_reorder()
71
+
72
+
73
+ _sort_nested_objects: ->
74
+ if @config.sortBy
75
+ @config.formSchema[@config.sortBy] = { type: 'hidden' }
76
+ if @nestedObjects
77
+ # this is not required but make things a bit easier on the backend
78
+ # as object don't have to be in a specific order.
79
+ @nestedObjects.sort (a, b) => parseFloat(a[@config.sortBy]) - parseFloat(b[@config.sortBy])
80
+ # normalizes nested objects positions
81
+ (o[@config.sortBy] = parseInt(i) + 1) for i, o of @nestedObjects
82
+
83
+
84
+ _render_form: (object, namePrefix, config) ->
85
+ formConfig = $.extend {}, config,
86
+ namePrefix: namePrefix
87
+ rootEl: "<li>"
88
+
89
+ form = new Form(object, formConfig)
90
+ @$forms.append form.$el
91
+
92
+ return form
93
+
94
+
95
+ _add_new_button: ->
96
+ label = @config.newButtonLabel || "Add"
97
+ @$newButton =$ """<a href='#' class='nested-form-new'>#{ label }</a>"""
98
+ @$el.append @$newButton
99
+ @$newButton.on 'click', (e) => e.preventDefault() ; @addNewForm()
100
+
101
+
102
+ # PUBLIC ================================================
103
+
104
+ initialize: ->
105
+ for nestedForm in @forms
106
+ nestedForm.initializePlugins()
107
+ @config.onInitialize?(this)
108
+
109
+
110
+ hash: (hash={})->
111
+ hash[@config.klassName] = []
112
+ for form in @forms
113
+ hash[@config.klassName].push form.hash()
114
+ return hash
115
+
116
+
117
+ showErrorMessage: (message) ->
118
+ @$el.addClass 'error'
119
+ @$errorMessage.html(message)
120
+
121
+
122
+ hideErrorMessage: ->
123
+ @$el.removeClass 'error'
124
+ @$errorMessage.html('')
125
+
126
+
127
+ addNewForm: (object=null) ->
128
+ namePrefix = "#{ @config.namePrefix }[#{ Date.now() }]"
129
+ newFormConfig = $.extend({}, @config)
130
+
131
+ delete newFormConfig.formSchema._id
132
+
133
+ form = @_render_form(object, namePrefix, newFormConfig)
134
+ form.initializePlugins()
135
+
136
+ if @config.sortBy
137
+ @_add_form_reorder_button(form)
138
+ prevForm = _last(@forms)
139
+ position = if prevForm then prevForm.inputs[@config.sortBy].value + 1 else 1
140
+ form.inputs[@config.sortBy].updateValue(position)
141
+
142
+ @forms.push(form)
143
+
144
+ @config.onNew?(form)
145
+
146
+ return form
147
+
148
+
149
+ updateValue: (@nestedObjects, @object) ->
150
+ @$forms.remove()
151
+ @forms = []
152
+ @_add_forms()
153
+
154
+
155
+ include(InputForm, inputFormReorder)
156
+
157
+
158
+ chr.formInputs['form'] = InputForm
159
+
160
+
161
+
162
+
@@ -0,0 +1,67 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT "NESTED" FORM REORDER
11
+ # -----------------------------------------------------------------------------
12
+
13
+ @inputFormReorder =
14
+ # PRIVATE ===============================================
15
+
16
+ _bind_forms_reorder: ->
17
+ if @config.sortBy
18
+ list = @$forms.addClass(@reorderContainerClass).get(0)
19
+
20
+ new Slip(list)
21
+
22
+ list.addEventListener 'slip:beforeswipe', (e) -> e.preventDefault()
23
+
24
+ list.addEventListener 'slip:beforewait', ((e) ->
25
+ if $(e.target).hasClass("icon-reorder") then e.preventDefault()
26
+ ), false
27
+
28
+ list.addEventListener 'slip:beforereorder', ((e) ->
29
+ if not $(e.target).hasClass("icon-reorder") then e.preventDefault()
30
+ ), false
31
+
32
+ list.addEventListener 'slip:reorder', ((e) =>
33
+ # this event called for all parent lists, add a check for context:
34
+ # process this event only if target form is in the @forms list.
35
+ targetForm = @_find_form_by_target(e.target)
36
+ if targetForm
37
+ # when `e.detail.insertBefore` is null, item put to the end of the list.
38
+ e.target.parentNode.insertBefore(e.target, e.detail.insertBefore)
39
+
40
+ $targetForm =$ e.target
41
+ prevForm = @_find_form_by_target($targetForm.prev().get(0))
42
+ nextForm = @_find_form_by_target($targetForm.next().get(0))
43
+
44
+ prevFormPosition = if prevForm then prevForm.inputs[@config.sortBy].value else 0
45
+ nextFormPosition = if nextForm then nextForm.inputs[@config.sortBy].value else 0
46
+ newTargetFormPosition = prevFormPosition + Math.abs(nextFormPosition - prevFormPosition) / 2.0
47
+
48
+ targetForm.inputs[@config.sortBy].updateValue(newTargetFormPosition)
49
+
50
+ return false
51
+ ), false
52
+
53
+ @_add_form_reorder_button(form) for form in @forms
54
+
55
+
56
+ _add_form_reorder_button: (form) ->
57
+ form.$el.append("""<div class='icon-reorder' data-container-class='#{@reorderContainerClass}'></div>""").addClass('reorderable')
58
+
59
+
60
+ _find_form_by_target: (el) ->
61
+ if el
62
+ for form in @forms
63
+ if form.$el.get(0) == el then return form
64
+ return null
65
+
66
+
67
+
@@ -1,40 +1,56 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
1
9
  # -----------------------------------------------------------------------------
2
10
  # INPUT HIDDEN
3
11
  # -----------------------------------------------------------------------------
4
12
  class @InputHidden
5
13
  constructor: (@name, @value, @config, @object) ->
6
- @$el = $("<input type='hidden' name='#{ @name }' value='#{ @_valueSafe() }' id='#{ @name }' />")
14
+ @_create_el()
7
15
 
8
16
  return this
9
17
 
10
- _valueSafe: ->
18
+
19
+ # PRIVATE ===============================================
20
+
21
+ _create_el: ->
22
+ @$el =$ "<input type='hidden' name='#{ @name }' value='#{ @_safe_value() }' />"
23
+
24
+
25
+ _safe_value: ->
11
26
  if typeof(@value) == 'object'
12
27
  JSON.stringify(@value)
13
28
  else
14
29
  _escapeHtml(@value)
15
30
 
16
- #
17
- # PUBLIC
18
- #
31
+
32
+ # PUBLIC ================================================
19
33
 
20
34
  initialize: ->
21
35
  @config.onInitialize?(this)
22
36
 
37
+
23
38
  updateValue: (@value) ->
24
- @$el.val(@_valueSafe())
39
+ @$el.val(@_safe_value())
40
+
25
41
 
26
42
  hash: (hash={}) ->
27
43
  hash[@config.klassName] = @$el.val()
28
44
  return hash
29
45
 
30
- showErrorMessage: (message) ->
31
- ;
32
46
 
33
- hideErrorMessage: ->
34
- ;
47
+ showErrorMessage: (message) -> ;
48
+
49
+
50
+ hideErrorMessage: -> ;
35
51
 
36
52
 
37
- _chrFormInputs['hidden'] = InputHidden
53
+ chr.formInputs['hidden'] = InputHidden
38
54
 
39
55
 
40
56
 
@@ -1,28 +1,63 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
1
9
  # -----------------------------------------------------------------------------
2
10
  # INPUT LIST
11
+ # -----------------------------------------------------------------------------
3
12
  # Allows to create/delete/reorder list items connected to dynamic or static
4
13
  # collection. Value should be an array of objects.
5
14
  #
6
15
  # Dependencies:
7
- # - jquery.typeahead
8
- # - slip
16
+ #= require ./input-list_reorder
17
+ #
9
18
  # -----------------------------------------------------------------------------
19
+
10
20
  class @InputList extends InputString
11
- _updateInputValue: ->
21
+
22
+ # PRIVATE ===============================================
23
+
24
+ _add_input: ->
25
+ # hidden input that stores ids
26
+ # we use __LIST__ prefix to identify ARRAY input type and
27
+ # process it's value while form submission.
28
+ name = if @config.namePrefix then "#{@config.namePrefix}[__LIST__#{@config.target}]" else "[__LIST__#{@config.target}]"
29
+
30
+ @$input =$ "<input type='hidden' name='#{ name }' value='' />"
31
+ @$el.append @$input
32
+
33
+ # other options might be added here (static collection)
34
+ if @config.typeahead
35
+ # typeahead input for adding new items
36
+ placeholder = @config.typeahead.placeholder
37
+ @typeaheadInput =$ "<input type='text' placeholder='#{ placeholder }' />"
38
+ @$el.append @typeaheadInput
39
+
40
+ @_add_items()
41
+ @_update_input_value()
42
+
43
+
44
+ _update_input_value: ->
12
45
  ids = []
13
46
  @$items.children('li').each (i, el)->
14
47
  ids.push $(el).attr('data-id')
15
48
  value = ids.join(',')
16
49
  @$input.val(value)
17
50
 
18
- _removeItem: ($el) ->
51
+
52
+ _remove_item: ($el) ->
19
53
  id = $el.attr('data-id')
20
54
  delete @objects[id]
21
55
 
22
56
  $el.parent().remove()
23
- @_updateInputValue()
57
+ @_update_input_value()
58
+
24
59
 
25
- _addItem: (o) ->
60
+ _add_item: (o) ->
26
61
  id = o['_id']
27
62
 
28
63
  @objects[id] = o
@@ -38,40 +73,21 @@ class @InputList extends InputString
38
73
  <a href='#' class='action_remove'>Remove</a>
39
74
  </li>"""
40
75
  @$items.append listItem
41
- @_updateInputValue()
76
+ @_update_input_value()
42
77
 
43
- _addItems: ->
78
+
79
+ _add_items: ->
44
80
  @reorderContainerClass = @config.klassName
45
81
  @objects = {}
46
82
  @$items =$ "<ul class='#{ @reorderContainerClass }'></ul>"
47
83
 
48
84
  for o in @value
49
- @_addItem(o)
85
+ @_add_item(o)
50
86
 
51
87
  @typeaheadInput.before @$items
52
88
 
53
- _addInput: ->
54
- # hidden input that stores ids
55
- # NOTE: we use __LIST__ prefix to identify ARRAY input type and
56
- # process it's value while form submission.
57
- name = if @config.namePrefix then "#{@config.namePrefix}[__LIST__#{@config.target}]" else "[__LIST__#{@config.target}]"
58
-
59
- @$input =$ "<input type='hidden' name='#{ name }' value='' />"
60
- @$el.append @$input
61
-
62
- # NOTE: other options might be added here (static collection)
63
- if @config.typeahead
64
- # typeahead input for adding new items
65
- placeholder = @config.typeahead.placeholder
66
- @typeaheadInput =$ "<input type='text' placeholder='#{ placeholder }' />"
67
- @$el.append @typeaheadInput
68
-
69
- @_addItems()
70
- @_updateInputValue()
71
89
 
72
- #
73
- # PUBLIC
74
- #
90
+ # PUBLIC ================================================
75
91
 
76
92
  initialize: ->
77
93
  # typeahead
@@ -95,39 +111,18 @@ class @InputList extends InputString
95
111
  })
96
112
 
97
113
  @typeaheadInput.on 'typeahead:selected', (e, object, dataset) =>
98
- @_addItem(object)
114
+ @_add_item(object)
99
115
  @typeaheadInput.typeahead('val', '')
100
116
 
101
- # events
117
+ # remove
102
118
  @$items.on 'click', '.action_remove', (e) =>
103
119
  e.preventDefault()
104
- if confirm('Are you sure?')
105
- @_removeItem($(e.currentTarget))
106
-
107
- # reorder
108
- list = @$items.get(0)
109
- new Slip(list)
110
-
111
- list.addEventListener 'slip:beforeswipe', (e) -> e.preventDefault()
120
+ if confirm('Are you sure?') then @_remove_item($(e.currentTarget))
112
121
 
113
- list.addEventListener 'slip:beforewait', ((e) ->
114
- if $(e.target).hasClass("icon-reorder") then e.preventDefault()
115
- ), false
116
-
117
- list.addEventListener 'slip:beforereorder', ((e) ->
118
- if not $(e.target).hasClass("icon-reorder") then e.preventDefault()
119
- ), false
120
-
121
- list.addEventListener 'slip:reorder', ((e) =>
122
- e.target.parentNode.insertBefore(e.target, e.detail.insertBefore)
123
- @_updateInputValue()
124
- return false
125
- ), false
122
+ @_bind_reorder()
126
123
 
127
124
  @config.onInitialize?(this)
128
125
 
129
- # TODO: add support
130
- updateValue: (@value) ->
131
126
 
132
127
  hash: (hash={}) ->
133
128
  hash[@config.klassName] = []
@@ -135,7 +130,16 @@ class @InputList extends InputString
135
130
  hash[@config.klassName].push(@objects[id]) for id in ids
136
131
  return hash
137
132
 
138
- _chrFormInputs['list'] = InputList
133
+
134
+ updateValue: (@value) ->
135
+ @$items.html('')
136
+ @_add_item(o) for o in @value
137
+
138
+
139
+ include(InputList, inputListReorder)
140
+
141
+
142
+ chr.formInputs['list'] = InputList
139
143
 
140
144
 
141
145