formagic 0.1.0

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/CONTRIBUTING.md +24 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.md +21 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/app/assets/images/datedropper/done.png +0 -0
  9. data/app/assets/images/datedropper/done.svg +1 -0
  10. data/app/assets/images/datedropper/next.png +0 -0
  11. data/app/assets/images/datedropper/next.svg +1 -0
  12. data/app/assets/images/datedropper/prev.png +0 -0
  13. data/app/assets/images/datedropper/prev.svg +1 -0
  14. data/app/assets/javascripts/formagic/form.coffee +229 -0
  15. data/app/assets/javascripts/formagic/group.coffee +28 -0
  16. data/app/assets/javascripts/formagic/inputs/checkbox.coffee +83 -0
  17. data/app/assets/javascripts/formagic/inputs/color.coffee +55 -0
  18. data/app/assets/javascripts/formagic/inputs/date.coffee +69 -0
  19. data/app/assets/javascripts/formagic/inputs/datetime.coffee +130 -0
  20. data/app/assets/javascripts/formagic/inputs/document.coffee +0 -0
  21. data/app/assets/javascripts/formagic/inputs/documents.coffee +173 -0
  22. data/app/assets/javascripts/formagic/inputs/documents_reorder.coffee +67 -0
  23. data/app/assets/javascripts/formagic/inputs/file.coffee +114 -0
  24. data/app/assets/javascripts/formagic/inputs/hidden.coffee +57 -0
  25. data/app/assets/javascripts/formagic/inputs/html.coffee +81 -0
  26. data/app/assets/javascripts/formagic/inputs/image.coffee +28 -0
  27. data/app/assets/javascripts/formagic/inputs/list.coffee +154 -0
  28. data/app/assets/javascripts/formagic/inputs/list_reorder.coffee +39 -0
  29. data/app/assets/javascripts/formagic/inputs/list_typeahead.coffee +55 -0
  30. data/app/assets/javascripts/formagic/inputs/markdown.coffee +93 -0
  31. data/app/assets/javascripts/formagic/inputs/password.coffee +32 -0
  32. data/app/assets/javascripts/formagic/inputs/redactor.coffee +53 -0
  33. data/app/assets/javascripts/formagic/inputs/redactor_character.coffee +75 -0
  34. data/app/assets/javascripts/formagic/inputs/redactor_images.coffee +166 -0
  35. data/app/assets/javascripts/formagic/inputs/select.coffee +84 -0
  36. data/app/assets/javascripts/formagic/inputs/select2.coffee +33 -0
  37. data/app/assets/javascripts/formagic/inputs/string.coffee +160 -0
  38. data/app/assets/javascripts/formagic/inputs/text.coffee +43 -0
  39. data/app/assets/javascripts/formagic/inputs/time.coffee +0 -0
  40. data/app/assets/javascripts/formagic.coffee +22 -0
  41. data/app/assets/javascripts/vendor/ace.js +18280 -0
  42. data/app/assets/javascripts/vendor/datedropper.js +1005 -0
  43. data/app/assets/javascripts/vendor/jquery.scrollparent.js +14 -0
  44. data/app/assets/javascripts/vendor/jquery.textarea_autosize.js +55 -0
  45. data/app/assets/javascripts/vendor/jquery.typeahead.js +1782 -0
  46. data/app/assets/javascripts/vendor/marked.js +1272 -0
  47. data/app/assets/javascripts/vendor/mode-html.js +2436 -0
  48. data/app/assets/javascripts/vendor/mode-markdown.js +2820 -0
  49. data/app/assets/javascripts/vendor/moment.js +3083 -0
  50. data/app/assets/javascripts/vendor/redactor.fixedtoolbar.js +107 -0
  51. data/app/assets/javascripts/vendor/select2.js +5274 -0
  52. data/app/assets/stylesheets/formagic/checkbox.scss +8 -0
  53. data/app/assets/stylesheets/formagic/color.scss +12 -0
  54. data/app/assets/stylesheets/formagic/date.scss +37 -0
  55. data/app/assets/stylesheets/formagic/file.scss +29 -0
  56. data/app/assets/stylesheets/formagic/form.scss +36 -0
  57. data/app/assets/stylesheets/formagic/group.scss +22 -0
  58. data/app/assets/stylesheets/formagic/image.scss +19 -0
  59. data/app/assets/stylesheets/formagic/list.scss +39 -0
  60. data/app/assets/stylesheets/formagic/nested-form.scss +23 -0
  61. data/app/assets/stylesheets/formagic/redactor.scss +41 -0
  62. data/app/assets/stylesheets/formagic/select.scss +5 -0
  63. data/app/assets/stylesheets/formagic/select2.scss +95 -0
  64. data/app/assets/stylesheets/formagic/string.scss +14 -0
  65. data/app/assets/stylesheets/formagic/switch.scss +86 -0
  66. data/app/assets/stylesheets/formagic/text.scss +9 -0
  67. data/app/assets/stylesheets/formagic.scss +15 -0
  68. data/app/assets/stylesheets/vendor/datedropper.scss +523 -0
  69. data/app/assets/stylesheets/vendor/select2.scss +258 -0
  70. data/formagic.gemspec +30 -0
  71. data/lib/formagic/engine.rb +5 -0
  72. data/lib/formagic/version.rb +3 -0
  73. data/lib/formagic.rb +5 -0
  74. metadata +146 -0
@@ -0,0 +1,130 @@
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 DATE
11
+ # -----------------------------------------------------------------------------
12
+ #
13
+ # Dependencies:
14
+ #= require vendor/datedropper
15
+ #= require vendor/moment
16
+ #
17
+ # -----------------------------------------------------------------------------
18
+ class @InputDatetime extends InputDate
19
+
20
+ # PRIVATE ===============================================
21
+
22
+ _update_value: ->
23
+ mt = moment(@$inputTime.val(), 'LT')
24
+ if ! mt.isValid()
25
+ mt = moment('1:00 pm', 'LT')
26
+
27
+ time_string = mt.utcOffset(@tzOffset).format().split('T')[1]
28
+ date_string = @$inputDate.val()
29
+
30
+ value = [ date_string, time_string ].join('T')
31
+
32
+ @$input.val(value)
33
+
34
+
35
+ _update_date_input: ->
36
+ m = moment(@$input.val()).utcOffset(@tzOffset)
37
+ @$inputDate.val ( if m.isValid() then m.format('YYYY-MM-DD') else '' )
38
+
39
+
40
+ _update_time_input: ->
41
+ m = moment(@$input.val()).utcOffset(@tzOffset)
42
+ @$inputTime.val ( if m.isValid() then m.format('h:mm a') else '' )
43
+
44
+
45
+ _update_date_label: ->
46
+ m = moment(@$inputDate.val()).utcOffset(@tzOffset)
47
+ @$dateLabel.html ( if m.isValid() then m.format('dddd, MMM D, YYYY') else 'Pick a date' )
48
+
49
+
50
+ _normalized_value: ->
51
+ # -- use local timezone to represent time
52
+ @tzOffset = @config.timezoneOffset
53
+ @tzOffset ?= (new Date()).getTimezoneOffset() * -1
54
+
55
+ @value = moment(@value).utcOffset(@tzOffset).format()
56
+
57
+
58
+ _add_input: ->
59
+ @_normalized_value()
60
+
61
+ # -- hidden
62
+ @$input =$ "<input type='hidden' name='#{ @name }' value='#{ @value }' />"
63
+ @$el.append @$input
64
+
65
+ # -- date
66
+ @$inputDate =$ "<input type='text' class='input-datetime-date' />"
67
+ @$el.append @$inputDate
68
+ @$inputDate.on 'change', (e) =>
69
+ @_update_date_label()
70
+ @_update_value()
71
+
72
+ @_update_date_input()
73
+
74
+ # -- date label
75
+ @$dateLabel =$ "<div class='input-date-label'>"
76
+ @$el.append @$dateLabel
77
+ @$dateLabel.on 'click', (e) => @$inputDate.trigger 'click'
78
+
79
+ @_update_date_label()
80
+
81
+ # -- @
82
+ @$el.append "<span class='input-timedate-at'>@</span>"
83
+
84
+ # -- time
85
+ @$inputTime =$ "<input type='text' class='input-datetime-time' placeholder='1:00 pm' />"
86
+ @$el.append @$inputTime
87
+ @$inputTime.on 'change, keyup', (e) => @_update_value() ; @$input.trigger('change')
88
+
89
+ @_update_time_input()
90
+
91
+
92
+ # PUBLIC ================================================
93
+
94
+ initialize: ->
95
+ @config.beforeInitialize?(this)
96
+
97
+ # http://felicegattuso.com/projects/datedropper/
98
+ @config.pluginConfig ?= {}
99
+
100
+ config =
101
+ animation: 'fadein'
102
+ format: 'Y-m-d'
103
+ animate_current: false
104
+ textColor: '#333'
105
+ borderColor: '#f6f6f6'
106
+ boxShadow: '0 0 2px rgba(0, 0, 0, 0.2)'
107
+ borderRadius: 4
108
+ maxYear: 2020
109
+
110
+ $.extend(config, @config.pluginConfig)
111
+
112
+ @$inputDate.dateDropper(config)
113
+
114
+ @config.onInitialize?(this)
115
+
116
+
117
+ updateValue: (@value) ->
118
+ @_normalized_value()
119
+ @$input.val(@value)
120
+
121
+ @_update_date_input()
122
+ @_update_date_label()
123
+ @_update_time_input()
124
+
125
+
126
+ chr.formInputs['datetime'] = InputDatetime
127
+
128
+
129
+
130
+
@@ -0,0 +1,173 @@
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 ./documents_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 input-#{ @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
+ @config.beforeInitialize?(this)
106
+
107
+ for nestedForm in @forms
108
+ nestedForm.initializePlugins()
109
+
110
+ @config.onInitialize?(this)
111
+
112
+
113
+ hash: (hash={}) ->
114
+ objects = []
115
+ objects.push(form.hash()) for form in @forms
116
+ hash[@config.fieldName] = objects
117
+ return hash
118
+
119
+
120
+ showErrorMessage: (message) ->
121
+ @$el.addClass 'error'
122
+ @$errorMessage.html(message)
123
+
124
+
125
+ hideErrorMessage: ->
126
+ @$el.removeClass 'error'
127
+ @$errorMessage.html('')
128
+
129
+
130
+ addNewForm: (object=null) ->
131
+ namePrefix = "#{ @config.namePrefix }[#{ Date.now() }]"
132
+ newFormConfig = $.extend({}, @config)
133
+
134
+ delete newFormConfig.formSchema._id
135
+
136
+ form = @_render_form(object, namePrefix, newFormConfig)
137
+ form.initializePlugins()
138
+
139
+ if @config.sortBy
140
+ @_add_form_reorder_button(form)
141
+ prevForm = _last(@forms)
142
+ position = if prevForm then prevForm.inputs[@config.sortBy].value + 1 else 1
143
+
144
+ # @TODO: having an issue here for scenario when no nested object are there for new object
145
+ # form.inputs doesn't include sortBy field
146
+ console.log @config
147
+ console.log @config.sortBy
148
+ console.log form.inputs
149
+
150
+ form.inputs[@config.sortBy].updateValue(position)
151
+
152
+ @forms.push(form)
153
+
154
+ @config.onNew?(form)
155
+
156
+ return form
157
+
158
+
159
+ updateValue: (@nestedObjects, @object) ->
160
+ @$forms.remove()
161
+ @forms = []
162
+ @_add_forms()
163
+
164
+
165
+ include(InputForm, inputFormReorder)
166
+
167
+
168
+ chr.formInputs['form'] = InputForm
169
+ chr.formInputs['documents'] = InputForm
170
+
171
+
172
+
173
+
@@ -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
+
@@ -0,0 +1,114 @@
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 FILE
11
+ # -----------------------------------------------------------------------------
12
+ # @TODO: add clear button when file is picked for the first time and you want
13
+ # to cancel that pick
14
+ # -----------------------------------------------------------------------------
15
+ class @InputFile extends InputString
16
+ constructor: (@name, @value, @config, @object) ->
17
+ @_create_el()
18
+
19
+ @_add_label()
20
+ @_add_input()
21
+ @_update_state()
22
+ @_add_required()
23
+
24
+ return this
25
+
26
+
27
+ # PRIVATE ===============================================
28
+
29
+ _create_el: ->
30
+ @$el =$ "<div class='input-#{ @config.type } input-#{ @config.klass } input-#{ @config.klassName }'>"
31
+
32
+
33
+ _add_input: ->
34
+ @$link =$ "<a href='#' target='_blank' title=''></a>"
35
+ @$el.append(@$link)
36
+
37
+ @$input =$ "<input type='file' name='#{ @name }' id='#{ @name }'>"
38
+ @$el.append @$input
39
+
40
+ @_add_clear_button()
41
+ @_add_remove_checkbox()
42
+
43
+
44
+ _add_clear_button: ->
45
+ @$clearButton =$ "<a href='#' class='input-file-clear'></a>"
46
+ @$input.after @$clearButton
47
+ @$clearButton.hide()
48
+
49
+ @$clearButton.on 'click', (e) =>
50
+ # clear file input:
51
+ # http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
52
+ @$input.replaceWith(@$input = @$input.clone(true))
53
+ @$clearButton.hide()
54
+ e.preventDefault()
55
+
56
+ @$input.on 'change', (e) =>
57
+ @$clearButton.show()
58
+
59
+
60
+ _add_remove_checkbox: ->
61
+ removeInputName = @removeName()
62
+ @$removeLabel =$ "<label for='#{ removeInputName }'>Remove</label>"
63
+ @$hiddenRemoveInput =$ "<input type='hidden' name='#{ removeInputName }' value='false'>"
64
+ @$removeInput =$ "<input type='checkbox' name='#{ removeInputName }' id='#{ removeInputName }' value='true'>"
65
+ @$link.after(@$removeLabel)
66
+ @$link.after(@$removeInput)
67
+ @$link.after(@$hiddenRemoveInput)
68
+
69
+
70
+ _update_inputs: ->
71
+ @$link.html(@filename).attr('title', @filename).attr('href', @value.url)
72
+
73
+
74
+ _update_state: (@filename=null) ->
75
+ @$input.val('')
76
+ @$removeInput.prop('checked', false)
77
+
78
+ if @value.url
79
+ @filename = _last(@value.url.split('/'))
80
+ if @filename == '_old_' then @filename = null # carrierwave filename workaround
81
+
82
+ if @filename
83
+ @$el.removeClass('empty')
84
+ @_update_inputs()
85
+ else
86
+ @$el.addClass('empty')
87
+
88
+
89
+ # PUBLIC ================================================
90
+
91
+ # when no file uploaded and no file selected, send remove flag so
92
+ # carrierwave does not catch _old_ value
93
+ isEmpty: ->
94
+ ( ! @$input.get()[0].files[0] && ! @filename )
95
+
96
+
97
+ removeName: ->
98
+ @name.reverse().replace('[', '[remove_'.reverse()).reverse()
99
+
100
+
101
+ updateValue: (@value, @object) ->
102
+ @_update_state()
103
+
104
+
105
+ hash: (hash={})->
106
+ # @TODO: file input type does not support caching and versioning as of now
107
+ return hash
108
+
109
+
110
+ chr.formInputs['file'] = InputFile
111
+
112
+
113
+
114
+
@@ -0,0 +1,57 @@
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 HIDDEN
11
+ # -----------------------------------------------------------------------------
12
+ class @InputHidden
13
+ constructor: (@name, @value, @config, @object) ->
14
+ @_create_el()
15
+
16
+ return this
17
+
18
+
19
+ # PRIVATE ===============================================
20
+
21
+ _create_el: ->
22
+ @$el =$ "<input type='hidden' name='#{ @name }' value='#{ @_safe_value() }' />"
23
+
24
+
25
+ _safe_value: ->
26
+ if typeof(@value) == 'object'
27
+ return JSON.stringify(@value)
28
+ else
29
+ _escapeHtml(@value)
30
+
31
+
32
+ # PUBLIC ================================================
33
+
34
+ showErrorMessage: (message) -> ;
35
+
36
+
37
+ hideErrorMessage: -> ;
38
+
39
+
40
+ initialize: ->
41
+ @config.onInitialize?(this)
42
+
43
+
44
+ hash: (hash={}) ->
45
+ hash[@config.klassName] = @$el.val()
46
+ return hash
47
+
48
+
49
+ updateValue: (@value) ->
50
+ @$el.val(@value)
51
+
52
+
53
+ chr.formInputs['hidden'] = InputHidden
54
+
55
+
56
+
57
+
@@ -0,0 +1,81 @@
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 HTML
11
+ # -----------------------------------------------------------------------------
12
+ #
13
+ # Config options:
14
+ # label - Input label
15
+ # aceOptions - Custom options for overriding default ones
16
+ #
17
+ # Input config example:
18
+ # body_html: { type: 'html', label: 'Article' }
19
+ #
20
+ # Dependencies:
21
+ #= require vendor/ace
22
+ #= require vendor/mode-html
23
+ #
24
+ # -----------------------------------------------------------------------------
25
+
26
+ class @InputHtml extends InputString
27
+
28
+ # PRIVATE ===============================================
29
+
30
+ _add_input: ->
31
+ @$input =$ "<input type='hidden' name='#{ @name }' value='#{ @_safe_value() }' />"
32
+ @$el.append @$input
33
+
34
+ @$editor =$ "<div></div>"
35
+ @$el.append @$editor
36
+
37
+
38
+ _update_inputs: ->
39
+ @value = @editor.getSession().getValue()
40
+ @$input.val(@value)
41
+ @$input.trigger('change')
42
+
43
+
44
+ # PUBLIC ================================================
45
+
46
+ initialize: ->
47
+ @config.beforeInitialize?(this)
48
+
49
+ @editor = ace.edit(@$editor.get(0))
50
+ @editor.$blockScrolling = Infinity
51
+
52
+ @session = @editor.getSession()
53
+ @session.setValue(@$input.val())
54
+ @session.setUseWrapMode(true)
55
+ @session.setMode("ace/mode/html")
56
+
57
+ # ace options: https://github.com/ajaxorg/ace/wiki/Configuring-Ace
58
+ @editor.setOptions
59
+ autoScrollEditorIntoView: true
60
+ minLines: 5
61
+ maxLines: Infinity
62
+ showLineNumbers: false
63
+ showGutter: false
64
+ highlightActiveLine: false
65
+ showPrintMargin: false
66
+
67
+ @session.on 'change', (e) => @_update_inputs()
68
+
69
+ @config.onInitialize?(this)
70
+
71
+
72
+ updateValue: (@value) ->
73
+ @editor.getSession().setValue(@value)
74
+ @$input.val(@value)
75
+
76
+
77
+ chr.formInputs['html'] = InputHtml
78
+
79
+
80
+
81
+
@@ -0,0 +1,28 @@
1
+ # -----------------------------------------------------------------------------
2
+ # INPUT FILE IMAGE
3
+ # -----------------------------------------------------------------------------
4
+ # Config options:
5
+ # thumbnail(object) - method that returns thumbnail for input
6
+ # -----------------------------------------------------------------------------
7
+ class @InputFileImage extends InputFile
8
+ _add_input: ->
9
+ @$link =$ "<a href='#' target='_blank' title=''></a>"
10
+ @$el.append @$link
11
+
12
+ @$thumb =$ "<img src='' />"
13
+ @$el.append @$thumb
14
+
15
+ @$input =$ "<input type='file' name='#{ @name }' id='#{ @name }' />"
16
+ @$el.append @$input
17
+
18
+ @_add_clear_button()
19
+ @_add_remove_checkbox()
20
+
21
+
22
+ _update_inputs: ->
23
+ @$link.html(@filename).attr('title', @filename).attr('href', @value.url)
24
+ image_thumb_url = if @config.thumbnail then @config.thumbnail(@object) else @value.url
25
+ @$thumb.attr('src', image_thumb_url).attr('alt', @filename)
26
+
27
+
28
+ chr.formInputs['image'] = InputFileImage