binda 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +83 -25
  3. data/app/assets/javascripts/binda/application.js +3 -3
  4. data/app/assets/javascripts/binda/components/bootstrap.js +3 -4
  5. data/app/assets/javascripts/binda/components/field_group_editor.js +10 -10
  6. data/app/assets/javascripts/binda/components/field_setting_choices.js +61 -49
  7. data/app/assets/javascripts/binda/components/fileupload.js +135 -118
  8. data/app/assets/javascripts/binda/components/form_item.js +65 -65
  9. data/app/assets/javascripts/binda/components/form_item_editor.js +19 -19
  10. data/app/assets/javascripts/binda/components/form_item_image.js +11 -13
  11. data/app/assets/javascripts/binda/components/form_item_repeater.js +77 -71
  12. data/app/assets/javascripts/binda/components/login-shader.js +171 -164
  13. data/app/assets/javascripts/binda/components/login_form.js +65 -73
  14. data/app/assets/javascripts/binda/components/radio-toggle.js +8 -12
  15. data/app/assets/javascripts/binda/components/select2.js +19 -14
  16. data/app/assets/javascripts/binda/components/sortable.js +76 -71
  17. data/app/assets/javascripts/binda/dist/binda.bundle.js +735 -727
  18. data/app/assets/javascripts/binda/index.js +49 -35
  19. data/app/assets/stylesheets/binda/components/assets_manager.scss +13 -22
  20. data/app/assets/stylesheets/binda/components/b-alert.scss +18 -14
  21. data/app/assets/stylesheets/binda/components/b-btn.scss +24 -43
  22. data/app/assets/stylesheets/binda/components/field_setting_choices.scss +16 -31
  23. data/app/assets/stylesheets/binda/components/fileupload.scss +25 -42
  24. data/app/assets/stylesheets/binda/components/form_item.scss +51 -93
  25. data/app/assets/stylesheets/binda/components/form_item_choices.scss +7 -10
  26. data/app/assets/stylesheets/binda/components/login.scss +2 -2
  27. data/app/assets/stylesheets/binda/components/main_header.scss +5 -10
  28. data/app/assets/stylesheets/binda/components/main_sidebar.scss +42 -46
  29. data/app/assets/stylesheets/binda/components/main_sortable_table.scss +12 -21
  30. data/app/assets/stylesheets/binda/components/main_table.scss +18 -35
  31. data/app/assets/stylesheets/binda/components/popup_warning.scss +14 -27
  32. data/app/assets/stylesheets/binda/components/select2.scss +46 -48
  33. data/app/assets/stylesheets/binda/components/sortable.scss +25 -45
  34. data/app/assets/stylesheets/binda/components/standard-form.scss +43 -73
  35. data/app/assets/stylesheets/binda/controllers/users_sessions_new.scss +52 -89
  36. data/app/assets/stylesheets/binda/index.scss +0 -1
  37. data/app/assets/stylesheets/binda/settings/buttons.scss +9 -10
  38. data/app/assets/stylesheets/binda/settings/common.scss +17 -22
  39. data/app/assets/stylesheets/binda/settings/fonts.scss +112 -67
  40. data/app/assets/stylesheets/binda/settings/tiny_mce_overrides.scss +20 -36
  41. data/app/assets/stylesheets/binda/settings/variables.scss +38 -43
  42. data/app/controllers/binda/choices_controller.rb +14 -11
  43. data/app/controllers/binda/components_controller.rb +6 -4
  44. data/app/controllers/binda/structures_controller.rb +7 -3
  45. data/app/helpers/binda/components_helper.rb +69 -3
  46. data/app/helpers/binda/field_groups_helper.rb +16 -6
  47. data/app/helpers/binda/structures_helper.rb +1 -4
  48. data/app/models/binda/application_record.rb +4 -1
  49. data/app/models/binda/asset.rb +3 -1
  50. data/app/models/binda/b.rb +1 -0
  51. data/app/models/binda/category.rb +1 -0
  52. data/app/models/binda/checkbox.rb +2 -0
  53. data/app/models/binda/choice.rb +74 -41
  54. data/app/models/binda/component.rb +1 -1
  55. data/app/models/binda/date.rb +4 -0
  56. data/app/models/binda/deprecation.rb +7 -0
  57. data/app/models/binda/field_group.rb +16 -3
  58. data/app/models/binda/field_setting.rb +168 -41
  59. data/app/models/binda/image.rb +1 -0
  60. data/app/models/binda/radio.rb +2 -0
  61. data/app/models/binda/relation.rb +3 -0
  62. data/app/models/binda/repeater.rb +3 -0
  63. data/app/models/binda/selection.rb +237 -0
  64. data/app/models/binda/string.rb +4 -0
  65. data/app/models/binda/structure.rb +25 -14
  66. data/app/models/binda/text.rb +9 -0
  67. data/app/models/binda/video.rb +1 -0
  68. data/app/models/concerns/binda/default_helpers.rb +40 -31
  69. data/app/models/concerns/binda/deprecations.rb +6 -0
  70. data/app/models/concerns/binda/fieldable_association_helpers.rb +366 -0
  71. data/app/models/concerns/binda/fieldable_associations.rb +32 -369
  72. data/app/views/binda/boards/edit.html.erb +15 -2
  73. data/app/views/binda/categories/_form.html.erb +24 -51
  74. data/app/views/binda/categories/edit.html.erb +23 -3
  75. data/app/views/binda/categories/index.html.erb +49 -25
  76. data/app/views/binda/categories/new.html.erb +21 -2
  77. data/app/views/binda/components/edit.html.erb +27 -4
  78. data/app/views/binda/components/index.html.erb +47 -50
  79. data/app/views/binda/components/new.html.erb +12 -2
  80. data/app/views/binda/components/sort_index.html.erb +28 -13
  81. data/app/views/binda/field_groups/_form_body.html.erb +43 -82
  82. data/app/views/binda/field_groups/_form_item.html.erb +3 -120
  83. data/app/views/binda/field_groups/_form_section.html.erb +11 -16
  84. data/app/views/binda/field_groups/_form_section_repeater.html.erb +7 -15
  85. data/app/views/binda/field_groups/edit.html.erb +14 -2
  86. data/app/views/binda/field_groups/form_item/_form_item_choice_editor.html.erb +11 -0
  87. data/app/views/binda/field_groups/form_item/_form_item_editor.html.erb +14 -0
  88. data/app/views/binda/field_groups/form_item/_form_item_header.html.erb +25 -0
  89. data/app/views/binda/field_groups/form_item/_form_item_new_editor.html.erb +8 -0
  90. data/app/views/binda/field_groups/form_item/_form_item_persisted_editor.html.erb +27 -0
  91. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_allow_null_choice.html.erb +11 -0
  92. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_choice_header.html.erb +11 -0
  93. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_default_choice.html.erb +11 -0
  94. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_new_choice.html.erb +16 -0
  95. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_persisted_choices.html.erb +16 -0
  96. data/app/views/binda/field_groups/new.html.erb +14 -2
  97. data/app/views/binda/field_settings/_form_body.html.erb +1 -3
  98. data/app/views/binda/field_settings/edit.html.erb +1 -1
  99. data/app/views/binda/field_settings/new.html.erb +1 -1
  100. data/app/views/binda/fieldable/_form_body.html.erb +24 -72
  101. data/app/views/binda/fieldable/_form_item_date.html.erb +1 -4
  102. data/app/views/binda/fieldable/_form_item_image.html.erb +3 -7
  103. data/app/views/binda/fieldable/_form_item_new_repeater.html.erb +0 -13
  104. data/app/views/binda/fieldable/_form_item_selections.html.erb +20 -112
  105. data/app/views/binda/fieldable/form_item_selections/_form_item_checkbox.html.erb +34 -0
  106. data/app/views/binda/fieldable/form_item_selections/_form_item_radio.html.erb +28 -0
  107. data/app/views/binda/fieldable/form_item_selections/_form_item_selection.html.erb +30 -0
  108. data/app/views/binda/manage/users/_form_body.html.erb +1 -31
  109. data/app/views/binda/manage/users/edit.html.erb +12 -2
  110. data/app/views/binda/manage/users/index.html.erb +36 -19
  111. data/app/views/binda/manage/users/new.html.erb +14 -3
  112. data/app/views/binda/structures/_form_body.html.erb +2 -25
  113. data/app/views/binda/structures/_form_section.html.erb +43 -65
  114. data/app/views/binda/structures/_form_sidebar.html.erb +19 -12
  115. data/app/views/binda/structures/edit.html.erb +20 -3
  116. data/app/views/binda/structures/index.html.erb +46 -26
  117. data/app/views/binda/structures/new.html.erb +13 -2
  118. data/app/views/binda/structures/sort_index.html.erb +37 -17
  119. data/app/views/binda/users/sessions/new.html.erb +25 -20
  120. data/app/views/layouts/binda/_form_errors.html.erb +10 -0
  121. data/app/views/layouts/binda/_sidebar.html.erb +6 -6
  122. data/app/views/layouts/binda/application.html.erb +1 -1
  123. data/config/initializers/carrierwave.rb +3 -2
  124. data/config/locales/en.yml +56 -12
  125. data/config/tinymce.yml +2 -2
  126. data/db/migrate/1_create_binda_tables.rb +1 -1
  127. data/lib/binda/version.rb +1 -1
  128. data/lib/generators/binda/setup/setup_generator.rb +2 -2
  129. data/lib/tasks/add_default_choice_to_all_selections_with_no_choices_task.rake +6 -0
  130. metadata +58 -8
  131. data/app/assets/stylesheets/binda/components/form_item_image.scss +0 -0
  132. data/app/views/binda/field_groups/_form_item_choice.erb +0 -104
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5694e1440f4d1444a866b3585c015a505b1916c9
4
- data.tar.gz: fbb826b32c32544817670db8c40b2c17b4e0fa0d
3
+ metadata.gz: 0595e8ebcd16b13684f90a7329163fee69a897f7
4
+ data.tar.gz: df0c48d8da9db4f7fb62a08ac1e45c29419b09f7
5
5
  SHA512:
6
- metadata.gz: 8e6fad4efa8654fd96281eba1cc2d952b06ab2c295e8c5647578dcf9fca72a9c56ac2815531f7a3a63bec2691e771181084b8f0bf5891f5cbfd5e6f470b0038e
7
- data.tar.gz: 8e0b3daf423b42e5a0b381678ddd41f62d79dc54c99f359fdf5dbad30958c6f31c38a0d005717b18c77c8279e989f481d532c6e61610334440dc4883814a151f
6
+ metadata.gz: ddec158c8a7577054ae0f190f712a1bed77cd856e8347b3b2e0b7e0d3674d3b3bb55bc574990264144f244f45439be03087cf18bf2882b46809449b0d66a2d1f
7
+ data.tar.gz: 632f2a5422638d97db475735c4e0af4a0aa9801abe52b7ec3ec5687cea0490d38bea4d19ecebb8888496b3ea5892ee74fc060a071057e8b6db7aef0b9f20cee2
data/README.md CHANGED
@@ -138,7 +138,7 @@ Once the _structure_ has been created it's possible to add field groups. By defa
138
138
 
139
139
  In order to add _field settings_ that will let you add content to your _component_ (or _board_) you need to enter on of the _structure's field groups_.
140
140
 
141
- ## Retrieve a structure
141
+ ## Retrieve structure elements
142
142
 
143
143
  Once you create a _structure_ you can call it from your controller like so:
144
144
 
@@ -149,16 +149,21 @@ Once you create a _structure_ you can call it from your controller like so:
149
149
  From that you can do all sorts of things.
150
150
 
151
151
  ```ruby
152
- # get all field groups
152
+ # get all field groups:
153
153
  @field_groups = @my_structure.field_groups
154
154
 
155
- # get all field settings
155
+ # get all field settings:
156
+ # (loop method) (returns an Array object)
156
157
  @field_settings = []
157
158
  @field_groups.each do |group|
158
159
  group.field_settings.each do |setting|
159
160
  @field_settings << setting
160
161
  end
161
162
  end
163
+ # (single query method) (returns an ActiveRelation object)
164
+ @field_settings = Binda::FieldSetting
165
+ .includes(field_group: [:structure])
166
+ .where(binda_field_groups: {structure_id: @my_structure.id})
162
167
  ```
163
168
 
164
169
  Depending on the structure type, to retrieve all related _components_ or the related _board_ you can use the Binda helper (which is suggested if you care about performance, see [component](#Components) or [board](#Boards)) or do it the usual Ruby on Rails way like so:
@@ -171,6 +176,20 @@ Depending on the structure type, to retrieve all related _components_ or the rel
171
176
  @board = @my_structure.board
172
177
  ```
173
178
 
179
+ To retrieve _field groups_ or a _structure_ from a _field setting_ you can do the following:
180
+
181
+ ```Ruby
182
+ @field_setting = Binda::FieldSetting.find_by(slug: 'my-field')
183
+
184
+ # Get the field group
185
+ @field_setting.field_group
186
+
187
+ # Get the structure
188
+ @field_setting.structure
189
+ ```
190
+
191
+ Note that `@field_setting.structure` is a convenient method Binda offers to get the structure, but don't over think: this doesn't mean there is a association `Binda::Structure --has_many--> Binda::FieldSetting`! The association is always mediated by `Binda::FieldGroup`.
192
+
174
193
  ---
175
194
 
176
195
 
@@ -258,9 +277,9 @@ You can add any other option to the query then:
258
277
 
259
278
  ## Enable preview
260
279
 
261
- When you created the component structure you might have enabled the **preview mode**. The easiest way to integrate the preview with yor application is to update the `config/routes.rb` file with a redirect that binds the component preview url to the controller that is in chardge of showing that component in your application.
280
+ When you created the _component structure_ you might want to enable the **preview mode**. The easiest way to integrate the preview with yor application is to update the `config/routes.rb` file with a redirect that binds the _component_ preview url to the controller that is in chardge of showing that _component_ in your application.
262
281
 
263
- For example let's say you have a *animal* structure with slug `animal`:
282
+ For example let's say you have a *animal* _structure_ with `slug = animal`:
264
283
 
265
284
  ```ruby
266
285
  # your application single animal route
@@ -278,11 +297,11 @@ get "admin_panel/animal/:slug", to: redirect('/animals/%{slug}')
278
297
 
279
298
  _Boards_ give you the possibility to have a panel where to list some specific settings.
280
299
 
281
- A great example of a _board_ is the _Dashboard_. This board is useful to store the generic data which can be used throughout the application, like the website name and description.
300
+ A great example of a _board_ is the _Dashboard_. This _board_ is useful to store the generic data which can be used throughout the application, like the website name and description.
282
301
 
283
- You can create as many _boards_ you like and add any field you want. To set up a _board_ go to _Structures_ and create a new _structure_ with type "_board_". The name of the structure will determine also the name of the board. Once created a new tab will appear on the main sidebar. The newly created structure is already populated with the _General Details_ field group which is initially empty. To add new field settings you can decide to edit this field group or create a new field group.
302
+ You can create as many _boards_ you like and add any field you want. To set up a _board_ go to _Structures_ and create a new _structure_ with type "_board_". The name of the _structure_ will determine also the name of the _board_. Once created a new tab will appear on the main sidebar. The newly created _structure_ is already populated with the _General Details_ _field group_ which is initially empty. To add new _field settings_ you can decide to edit this _field group_ or create a new _field group_.
284
303
 
285
- Once ready you can head to the _board_ page by clicking the tab on the main sidebar and populate the fields with your content.
304
+ Once ready you can head to the _board_ page by clicking the tab on the main sidebar and populate the _fields_ with your content.
286
305
 
287
306
  To retrieve _board_ content you can use one of those methods:
288
307
 
@@ -333,18 +352,43 @@ Every _field setting_ is based on a field type. You can create several field set
333
352
 
334
353
  Here below a list of field types available and their use:
335
354
 
336
- | Field setting | Use details |
337
- |---|---|
338
- | String | Store a string. No formatting options available. |
339
- | Text | Store a text. TinyMCE let's you format the text as you like. |
340
- | Image | Store image. |
341
- | Video | Store video. |
342
- | Date | Store a date. |
343
- | Radio | Select one choice amongst a custom set. |
344
- | Selection | Select one or more choices amongst a custom set. |
345
- | Check Box | Select one or more choices amongst a custom set. |
346
- | Repeater | Store multiple instances of a field or a collection of fields. |
347
- | Relation | Connect multiple instances of a _component_ or _board_ to each other. |
355
+ | Field type | Usage | |
356
+ |---|---|---|
357
+ | string | Store a string. No formatting options available. | [source](http://www.rubydoc.info/gems/binda/Binda/String) |
358
+ | text | Store a text. TinyMCE let's you format the text as you like. | [source](http://www.rubydoc.info/gems/binda/Binda/Text) |
359
+ | image | Store image. | [source](http://www.rubydoc.info/gems/binda/Binda/Image) |
360
+ | video | Store video. | [source](http://www.rubydoc.info/gems/binda/Binda/Video) |
361
+ | date | Store a date. | [source](http://www.rubydoc.info/gems/binda/Binda/Date) |
362
+ | radio | Select one choice amongst a custom set. | [source](http://www.rubydoc.info/gems/binda/Binda/Radio) |
363
+ | selection | Select one or more choices amongst a custom set. | [source](http://www.rubydoc.info/gems/binda/Binda/Selection) |
364
+ | checkbox | Select one or more choices amongst a custom set. | [source](http://www.rubydoc.info/gems/binda/Binda/Checkbox) |
365
+ | repeater | Store multiple instances of a field or a collection of fields. | [source](http://www.rubydoc.info/gems/binda/Binda/Repeater) |
366
+ | relation | Connect multiple instances of a _component_ or _board_ to each other. | [source](http://www.rubydoc.info/gems/binda/Binda/Relation) |
367
+
368
+ ## Available setting and customization
369
+
370
+ Sometime you might want to specify a behaviour or a restriction for a specific _field_.
371
+ To konw more about a specific _field_ click on the **source** link where you can find a more comprehensive documentation.
372
+
373
+ ## Reload!
374
+
375
+ In order to keep consistency between _fields_ and their own _settings_ Binda use **callbacks**.
376
+
377
+ For example the following line will create a _field setting_, but under the hood it provide each _component_ with the relative _field_:
378
+
379
+ ```ruby
380
+ # Create a field setting
381
+ @structure.field_groups_first.field_settings.create(name: 'my text', field_type: 'text')
382
+ # => <Binda::FieldSetting id: 1, ...>
383
+
384
+ # You don't have to create a text field for each component, it's alreay been done for you
385
+ @structure.components.first.texts.first
386
+ # => <Binda::Text id: 1, field_setting_id: 1, ...>
387
+ ```
388
+
389
+ IMPORTANT: Sometimes callbacks run and the `ActiveRecord` object stored in your variable might get outdated. Use `reload` to make sure the `ActiveRecord` in your variable correspond to the real database record. (run `mycomponent.reload`)
390
+
391
+ Some callbacks can a bit sneaky. For example _field settings_ with `field_type='radio'` cannot have `allow_null=true` so no matter how many times you try to update `allow_null=true` it will never change.
348
392
 
349
393
  ## How to get field content
350
394
 
@@ -371,7 +415,7 @@ Here below a list of helpers.
371
415
 
372
416
  You can retrieve field content from a instance of `Binda::Component`, `Binda::Board` or `Binda::Repeater`. See [How to get field content](#How_to_get_field_content).
373
417
 
374
- **NOTE: source links are based on the latest public version.** If you are using an older version or a specific branch please refer to the [source](https://github.com/lacolonia/binda/blob/master/app/models/concerns/binda/fieldable_associations.rb) switching to the branch/tag you are looking for.
418
+ **NOTE: source links are based on the latest public version.** If you are using an older version or a specific branch please refer to the [source on github](https://github.com/lacolonia/binda/blob/master/app/models/concerns/binda/fieldable_associations.rb) and switch to the branch/tag you are looking for.
375
419
 
376
420
  | Helper |||
377
421
  |---|---|---|
@@ -518,6 +562,22 @@ To change appereance and behaviour of the page add your styles to `app/assets/st
518
562
 
519
563
  ---
520
564
 
565
+ # Field settings and field groups
566
+
567
+ ---
568
+
569
+ ## Orphans
570
+
571
+ Sometime playing with Rails console you might end up creating orphans, which basically are components without a field setting parent. They might cause errors in some queries and they hard to track down.
572
+
573
+ To avoid the problem run the following command from your shell:
574
+
575
+ ```bash
576
+ rails binda:remove_orphan_fields
577
+ ```
578
+
579
+ ---
580
+
521
581
 
522
582
  # Plugins
523
583
 
@@ -531,10 +591,7 @@ Here a list of useful plugins:
531
591
 
532
592
  # Upgrade
533
593
 
534
- Here some upgrade instruction.
535
-
536
-
537
- To upgrade from 0.0.6 to 0.0.7 please refer to the [release documentation](https://github.com/lacolonia/binda/releases/tag/0.0.7)
594
+ If you are going to upgrade from a previous version please check the guidelines attached to the version release which can be found on this [Github page](https://github.com/lacolonia/binda/releases).
538
595
 
539
596
  ---
540
597
 
@@ -755,6 +812,7 @@ To contribute [fork this project](https://github.com/lacolonia/binda/wiki/_new#f
755
812
  - if you are not adding a core feature consider writing a plugin instead
756
813
  - improve and/or add new I18n translations
757
814
  - when fixing a bug, provide a failing test case that your patch solves
815
+ - write deprecation warning for methods instead of deleting them (`app/models/concerns/binda/deprecations.rb`)
758
816
 
759
817
  ## How to work locally
760
818
  Ensure you have installed Binda dependencies.
@@ -17,9 +17,6 @@
17
17
  //= require jquery-ui/widgets/sortable
18
18
  //= require jquery-ui/widget
19
19
 
20
- // TinyMCE
21
- //= require tinymce-jquery
22
-
23
20
  // Bootstrap dependency
24
21
  // https://v4-alpha.getbootstrap.com/components/tooltips/
25
22
  // require tether.min
@@ -36,6 +33,9 @@
36
33
  // GSAP/ScrollToPlugin.min
37
34
  // GSAP/TweenLite.min
38
35
 
36
+ // TinyMCE
37
+ //= require tinymce-jquery
38
+
39
39
  // Binda scripts
40
40
  //= require binda/dist/binda.bundle.js
41
41
 
@@ -2,8 +2,7 @@
2
2
  * BOOSTRAP SCRIPT
3
3
  */
4
4
 
5
- export default function()
6
- {
5
+ export default function() {
7
6
  // See https://v4-alpha.getbootstrap.com/components/tooltips/#example-enable-tooltips-everywhere
8
- $('[data-toggle="tooltip"]').tooltip()
9
- }
7
+ $('[data-toggle="tooltip"]').tooltip();
8
+ }
@@ -2,17 +2,17 @@
2
2
  * FIELD GROUP EDITOR
3
3
  */
4
4
 
5
- export default function()
6
- {
7
- $('.field_groups-edit #save').on('click', function(event)
8
- {
9
- let instanceType = $(this).data('instance-type')
10
- let entriesNumber = $(this).data('entries-number')
5
+ export default function() {
6
+ $(".field_groups-edit #save").on("click", function(event) {
7
+ let instanceType = $(this).data("instance-type");
8
+ let entriesNumber = $(this).data("entries-number");
11
9
 
12
10
  // If the current structure have many entries updating the field group
13
11
  // might be a slow operation, therefore it's good practice to inform the user
14
- if ( entriesNumber > 500 ) {
15
- alert(`You have ${entriesNumber} ${instanceType}. This operation might take some time to complete. To avoid unexpected behaviour don't leave or refresh the page`)
12
+ if (entriesNumber > 500) {
13
+ alert(
14
+ `You have ${entriesNumber} ${instanceType}. This operation might take some time to complete. To avoid unexpected behaviour don't leave or refresh the page`
15
+ );
16
16
  }
17
- })
18
- }
17
+ });
18
+ }
@@ -2,75 +2,87 @@
2
2
  * FORM ITEM CHOICE
3
3
  */
4
4
 
5
- import { _FormItemEditor } from './form_item_editor'
6
-
5
+ import { _FormItemEditor } from "./form_item_editor";
7
6
 
8
7
  class FieldSettingChoices {
9
-
10
- constructor()
11
- {
12
- this.target = '.field-setting-choices--choice'
8
+ constructor() {
9
+ this.target = ".field-setting-choices--choice";
13
10
  }
14
11
 
15
- isSet()
16
- {
17
- if ( $( this.target ).length > 0 ) { return true }
18
- else { return false }
12
+ isSet() {
13
+ if ($(this.target).length > 0) {
14
+ return true;
15
+ } else {
16
+ return false;
17
+ }
19
18
  }
20
19
 
21
- setEvents()
22
- {
23
- $(document).on('click', '.field-setting-choices--add-choice', addChoice )
24
-
25
- $(document).on('click', '.field-setting-choices--delete-choice', deleteChoice )
26
- $(document).on('click', '.field-setting-choices--js-delete-choice', function( event )
27
- {
28
- event.preventDefault()
29
- $( this ).closest('.field-setting-choices--choice').remove()
30
- // Update form item editor size
31
- _FormItemEditor.resize()
32
- })
20
+ setEvents() {
21
+ $(document).on(
22
+ "click",
23
+ ".field-setting-choices--add-choice",
24
+ addChoice
25
+ );
26
+
27
+ $(document).on(
28
+ "click",
29
+ ".field-setting-choices--delete-choice",
30
+ deleteChoice
31
+ );
32
+
33
+ $(document).on(
34
+ "click",
35
+ ".field-setting-choices--js-delete-choice",
36
+ function(event) {
37
+ event.preventDefault();
38
+ $(this)
39
+ .closest(".field-setting-choices--choice")
40
+ .remove();
41
+ // Update form item editor size
42
+ _FormItemEditor.resize();
43
+ }
44
+ );
33
45
  }
34
46
  }
35
47
 
36
- export let _FieldSettingChoices = new FieldSettingChoices()
37
-
48
+ export let _FieldSettingChoices = new FieldSettingChoices();
38
49
 
39
50
  /**
40
51
  * HELPER FUNCTIONS
41
52
  */
42
53
 
43
- function addChoice(event)
44
- {
45
- event.preventDefault()
54
+ function addChoice(event) {
55
+ event.preventDefault();
46
56
  // Clone the new choice field
47
- var choices_id = $( this ).data('choices-id')
48
- var choices = $(`#${choices_id}`)
49
- var newchoice = choices.find('.field-setting-choices--new-choice')
50
- var clone = newchoice.clone().removeClass('field-setting-choices--new-choice').toggle()
51
- clone.find('.field-setting-choices--toggle-choice').toggle()
57
+ var choices_id = $(this).data("choices-id");
58
+ var choices = $(`#${choices_id}`);
59
+ var newchoice = choices.find(".field-setting-choices--new-choice");
60
+ var clone = newchoice
61
+ .clone()
62
+ .removeClass("field-setting-choices--new-choice")
63
+ .toggle();
64
+ clone.find(".field-setting-choices--toggle-choice").toggle();
52
65
  // Append the clone right after
53
- choices.prepend( clone )
66
+ choices.prepend(clone);
54
67
  // Update form item editor size
55
- _FormItemEditor.resize()
68
+ _FormItemEditor.resize();
56
69
  }
57
70
 
71
+ function deleteChoice(event) {
72
+ event.preventDefault();
58
73
 
59
- function deleteChoice( event )
60
- {
61
- event.preventDefault()
62
-
63
- var choice = $( this ).closest('.field-setting-choices--choice')
64
- var destination = $( this ).attr('href')
65
- var self = this
74
+ var choice = $(this).closest(".field-setting-choices--choice");
75
+ var destination = $(this).attr("href");
76
+ var self = this;
66
77
 
67
78
  $.ajax({
68
79
  url: destination,
69
- type: 'DELETE',
70
- success: function() {
71
- choice.remove()
72
- // Update form item editor size
73
- _FormItemEditor.resize()
74
- }
75
- })
76
- }
80
+ type: "DELETE"
81
+ }).done(function() {
82
+ choice.remove();
83
+ // Update form item editor size
84
+ _FormItemEditor.resize();
85
+ }).fail(function(data){
86
+ alert(data.responseJSON.errors);
87
+ });
88
+ }
@@ -1,76 +1,70 @@
1
1
  /**
2
2
  * FILE UPLOAD
3
- *
3
+ *
4
4
  * see https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/
5
- *
5
+ *
6
6
  */
7
7
 
8
8
  class FileUpload {
9
-
10
- constructor(){
11
- this.target = '.fileupload'
9
+ constructor() {
10
+ this.target = ".fileupload";
12
11
  }
13
12
 
14
- isSet()
15
- {
16
- if ( $( this.target ).length > 0 ) { return true }
17
- else { return false }
13
+ isSet() {
14
+ if ($(this.target).length > 0) {
15
+ return true;
16
+ } else {
17
+ return false;
18
+ }
18
19
  }
19
20
 
20
- setEvents()
21
- {
22
- let self = this
21
+ setEvents() {
22
+ let self = this;
23
23
 
24
- $(document).on('click', '.fileupload--remove-image-btn', remove_preview)
24
+ $(document).on("click", ".fileupload--remove-image-btn", remove_preview);
25
25
 
26
- $(document).on('change', `${this.target} input.file`, handle_file)
26
+ $(document).on("change", `${this.target} input.file`, handle_file);
27
27
  }
28
28
  }
29
29
 
30
- export let _FileUpload = new FileUpload()
31
-
30
+ export let _FileUpload = new FileUpload();
32
31
 
33
32
  /**
34
33
  * HELPER FUNCTIONS
35
34
  */
36
35
 
37
36
  // Reference --> http://blog.teamtreehouse.com/uploading-files-ajax
38
- function handle_file(event)
39
- {
40
- let id = event.target.getAttribute('data-id')
41
- let $parent = $('#fileupload-'+id)
37
+ function handle_file(event) {
38
+ let id = event.target.getAttribute("data-id");
39
+ let $parent = $("#fileupload-" + id);
42
40
 
43
41
  // Get the selected file from the input
44
42
  // This script doesn't consider multiple files upload
45
- let file = event.target.files[0]
43
+ let file = event.target.files[0];
46
44
 
47
45
  // Don't go any further if no file has been selected
48
- if ( typeof file === 'undefined' ) { return }
46
+ if (typeof file == "undefined") {
47
+ return;
48
+ }
49
49
 
50
50
  // Create a new FormData object which will be sent to the server
51
- let formData = new FormData()
51
+ let formData = new FormData();
52
52
 
53
53
  // Get data from the input element
54
- $parent.find('input').each(function()
55
- {
56
- if ( this.isSameNode(event.target) )
57
- {
54
+ $parent.find("input").each(function() {
55
+ if (this.isSameNode(event.target)) {
58
56
  // Add the file to the request
59
- formData.append(this.getAttribute('name'), file, file.name)
57
+ formData.append(this.getAttribute("name"), file, file.name);
60
58
  } else {
61
59
  // Add secondary values to the request
62
- formData.append(this.getAttribute('name'), this.getAttribute('value'))
60
+ formData.append(this.getAttribute("name"), this.getAttribute("value"));
63
61
  }
64
- })
62
+ });
65
63
 
66
64
  // If it's inside a repeater add repeater parameters
67
- let $parent_repeater = $parent.closest('.form-item--repeater-fields')
68
- if ( $parent.closest('.form-item--repeater-fields').length > 0 )
69
- {
70
- $parent_repeater.children('.form-group').find('input').each(function()
71
- {
72
- formData.append(this.getAttribute('name'), this.getAttribute('value'))
73
- })
65
+ let $parent_repeater = $parent.closest(".form-item--repeater-fields");
66
+ if ($parent.closest(".form-item--repeater-fields").length > 0) {
67
+ gatherData($parent_repeater, formData);
74
68
  }
75
69
 
76
70
  // Is this needed? Apparently it works without it. Is it a security issue?
@@ -78,117 +72,140 @@ function handle_file(event)
78
72
  // formData.append('authenticity_token', token)
79
73
 
80
74
  // Display loader
81
- $('.popup-warning--message').text( $parent.data('message') )
82
- $('.popup-warning').removeClass('popup-warning--hidden')
75
+ $(".popup-warning--message").text($parent.data("message"));
76
+ $(".popup-warning").removeClass("popup-warning--hidden");
83
77
 
84
78
  // Once form data are gathered make the request
85
- makeRequest(event, formData )
79
+ makeRequest(event, formData);
86
80
  }
87
81
 
82
+ function gatherData($parent_repeater, formData) {
83
+ $parent_repeater
84
+ .children(".form-group")
85
+ .find("input")
86
+ .each(function() {
87
+ formData.append(this.getAttribute("name"), this.getAttribute("value"));
88
+ });
89
+ }
88
90
 
89
- function makeRequest(event, formData )
90
- {
91
- let id = event.target.getAttribute('data-id')
92
- let $parent = $('#fileupload-'+id)
91
+ function makeRequest(event, formData) {
92
+ let id = event.target.getAttribute("data-id");
93
+ let $parent = $("#fileupload-" + id);
93
94
  // Make request
94
- $.ajax(
95
- {
96
- url: event.target.getAttribute('data-url'),
97
- type: 'PATCH',
98
- processData: false, // needed to pass formData with the current format
99
- contentType: false, // needed to pass formData with the current format
95
+ $.ajax({
96
+ url: event.target.getAttribute("data-url"),
97
+ type: "PATCH",
98
+ processData: false, // needed to pass formData with the current format
99
+ contentType: false, // needed to pass formData with the current format
100
100
  data: formData
101
- }).done( function(data)
102
- {
103
- if ( data.type == 'image' ) { setup_image_preview(data, id) }
104
- else if ( data.type == 'video' ) { setup_video_preview(data, id) }
105
- else { alert('Something went wrong. No preview has been received.') }
106
-
107
- // Hide loaded
108
- $('.popup-warning').addClass('popup-warning--hidden')
109
-
110
- // Display details and buttons
111
- $parent.find('.fileupload--details').removeClass('fileupload--details--hidden')
112
- $parent.find('.fileupload--remove-image-btn').removeClass('fileupload--remove-image-btn--hidden')
113
- }).fail( function(dataFail)
114
- {
115
- console.error("Error:", dataFail.responseJSON)
116
- // Hide loaded
117
- $('.popup-warning').addClass('popup-warning--hidden')
118
- alert($parent.data('error'))
119
101
  })
102
+ .done(function(data) {
103
+ updateFileuploadField(data, id);
104
+ })
105
+ .fail(function(dataFail) {
106
+ // Hide loaded
107
+ $(".popup-warning").addClass("popup-warning--hidden");
108
+ alert($parent.data("error"));
109
+ });
120
110
  }
121
111
 
122
- function reset_file(input)
123
- {
124
- input.value = ''
112
+ function updateFileuploadField(data, id) {
113
+ let $parent = $("#fileupload-" + id);
125
114
 
126
- if(!/safari/i.test(navigator.userAgent)){
127
- input.type = ''
128
- input.type = 'file'
115
+ if (data.type == "image") {
116
+ setup_image_preview(data, id);
117
+ } else if (data.type == "video") {
118
+ setup_video_preview(data, id);
119
+ } else {
120
+ alert("Something went wrong. No preview has been received.");
121
+ }
122
+
123
+ // Hide loaded
124
+ $(".popup-warning").addClass("popup-warning--hidden");
125
+
126
+ // Display details and buttons
127
+ $parent
128
+ .find(".fileupload--details")
129
+ .removeClass("fileupload--details--hidden");
130
+ $parent
131
+ .find(".fileupload--remove-image-btn")
132
+ .removeClass("fileupload--remove-image-btn--hidden");
133
+ }
134
+
135
+ function reset_file(input) {
136
+ input.value = "";
137
+
138
+ if (!/safari/i.test(navigator.userAgent)) {
139
+ input.type = "";
140
+ input.type = "file";
129
141
  }
130
142
  }
131
143
 
132
- function remove_preview(event)
133
- {
134
- let id = event.target.getAttribute('data-id')
135
- let $parent = $('#fileupload-'+id)
144
+ function remove_preview(event) {
145
+ let id = event.target.getAttribute("data-id");
146
+ let $parent = $("#fileupload-" + id);
136
147
 
137
148
  // Reset previews (either image or video)
138
- $parent.find('.fileupload--preview').css('background-image','').removeClass('fileupload--preview--uploaded')
139
- $parent.find('video source').removeAttr('src')
140
-
141
- // Clear input field
142
- reset_file( $parent.find('input[type=file]').get(0) )
149
+ $parent
150
+ .find(".fileupload--preview")
151
+ .css("background-image", "")
152
+ .removeClass("fileupload--preview--uploaded");
153
+ $parent.find("video source").removeAttr("src");
154
+
155
+ // Clear input field
156
+ reset_file($parent.find("input[type=file]").get(0));
143
157
 
144
158
  // Reset buttons to initial state
145
- $parent.find('.fileupload--remove-image-btn').addClass('fileupload--remove-image-btn--hidden')
146
- $parent.find('.fileupload--details').addClass('fileupload--details--hidden')
159
+ $parent
160
+ .find(".fileupload--remove-image-btn")
161
+ .addClass("fileupload--remove-image-btn--hidden");
162
+ $parent.find(".fileupload--details").addClass("fileupload--details--hidden");
147
163
  }
148
164
 
149
- function setup_image_preview(data, id)
150
- {
151
- let $parent = $('#fileupload-'+id)
152
- let $preview = $('#fileupload-'+id+' .fileupload--preview')
165
+ function setup_image_preview(data, id) {
166
+ let $parent = $("#fileupload-" + id);
167
+ let $preview = $("#fileupload-" + id + " .fileupload--preview");
153
168
 
154
169
  // Update thumbnail
155
- $preview.css('background-image', `url(${data.thumbnailUrl})`)
170
+ $preview.css("background-image", `url(${data.thumbnailUrl})`);
156
171
 
157
172
  // Remove and add class to trigger css animation
158
- let uploadedClass = 'fileupload--preview--uploaded'
159
- $preview.removeClass(uploadedClass).addClass(uploadedClass)
173
+ let uploadedClass = "fileupload--preview--uploaded";
174
+ $preview.removeClass(uploadedClass).addClass(uploadedClass);
160
175
 
161
176
  // Update details
162
- $parent.find('.fileupload--width').text(data.width)
163
- $parent.find('.fileupload--height').text(data.height)
164
- $parent.find('.fileupload--filesize').text(data.size)
165
- $parent.find('.fileupload--filename').text(data.name)
177
+ $parent.find(".fileupload--width").text(data.width);
178
+ $parent.find(".fileupload--height").text(data.height);
179
+ $parent.find(".fileupload--filesize").text(data.size);
180
+ $parent.find(".fileupload--filename").text(data.name);
166
181
  }
167
182
 
168
- function setup_video_preview(data, id)
169
- {
170
- let $parent = $('#fileupload-'+id)
171
- let $preview = $('#fileupload-'+id+' .fileupload--preview')
172
-
173
- $preview.removeClass('fileupload--preview--uploaded')
174
- .find('video')
175
- .attr('id', 'video-' + id)
176
- .find('source')
177
- .attr('src', data.url)
178
- .attr('type', 'video/' + data.ext)
179
-
180
- // If video source isn't blank load it (consider that a video tag is always present)
181
- if ( typeof $preview.find('video source').attr('src') != undefined )
182
- {
183
- $preview.find('video').get(0).load()
183
+ function setup_video_preview(data, id) {
184
+ let $parent = $("#fileupload-" + id);
185
+ let $preview = $("#fileupload-" + id + " .fileupload--preview");
186
+
187
+ $preview
188
+ .removeClass("fileupload--preview--uploaded")
189
+ .find("video")
190
+ .attr("id", "video-" + id)
191
+ .find("source")
192
+ .attr("src", data.url)
193
+ .attr("type", "video/" + data.ext);
194
+
195
+ // If video source isn't blank load it (consider that a video tag is always present)
196
+ if (typeof $preview.find("video source").attr("src") != undefined) {
197
+ $preview
198
+ .find("video")
199
+ .get(0)
200
+ .load();
184
201
  }
185
202
 
186
203
  // Remove and add class to trigger css animation
187
- let uploadedClass = 'fileupload--preview--uploaded'
188
- $preview.removeClass(uploadedClass).addClass(uploadedClass)
204
+ let uploadedClass = "fileupload--preview--uploaded";
205
+ $preview.removeClass(uploadedClass).addClass(uploadedClass);
189
206
 
190
207
  // Update details
191
- $parent.find('.fileupload--filesize').text(data.size)
192
- $parent.find('.fileupload--filename').text(data.name)
193
- $parent.find('.fileupload--videolink a').attr('href', data.url)
194
- }
208
+ $parent.find(".fileupload--filesize").text(data.size);
209
+ $parent.find(".fileupload--filename").text(data.name);
210
+ $parent.find(".fileupload--videolink a").attr("href", data.url);
211
+ }