binda 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +83 -25
- data/app/assets/javascripts/binda/application.js +3 -3
- data/app/assets/javascripts/binda/components/bootstrap.js +3 -4
- data/app/assets/javascripts/binda/components/field_group_editor.js +10 -10
- data/app/assets/javascripts/binda/components/field_setting_choices.js +61 -49
- data/app/assets/javascripts/binda/components/fileupload.js +135 -118
- data/app/assets/javascripts/binda/components/form_item.js +65 -65
- data/app/assets/javascripts/binda/components/form_item_editor.js +19 -19
- data/app/assets/javascripts/binda/components/form_item_image.js +11 -13
- data/app/assets/javascripts/binda/components/form_item_repeater.js +77 -71
- data/app/assets/javascripts/binda/components/login-shader.js +171 -164
- data/app/assets/javascripts/binda/components/login_form.js +65 -73
- data/app/assets/javascripts/binda/components/radio-toggle.js +8 -12
- data/app/assets/javascripts/binda/components/select2.js +19 -14
- data/app/assets/javascripts/binda/components/sortable.js +76 -71
- data/app/assets/javascripts/binda/dist/binda.bundle.js +735 -727
- data/app/assets/javascripts/binda/index.js +49 -35
- data/app/assets/stylesheets/binda/components/assets_manager.scss +13 -22
- data/app/assets/stylesheets/binda/components/b-alert.scss +18 -14
- data/app/assets/stylesheets/binda/components/b-btn.scss +24 -43
- data/app/assets/stylesheets/binda/components/field_setting_choices.scss +16 -31
- data/app/assets/stylesheets/binda/components/fileupload.scss +25 -42
- data/app/assets/stylesheets/binda/components/form_item.scss +51 -93
- data/app/assets/stylesheets/binda/components/form_item_choices.scss +7 -10
- data/app/assets/stylesheets/binda/components/login.scss +2 -2
- data/app/assets/stylesheets/binda/components/main_header.scss +5 -10
- data/app/assets/stylesheets/binda/components/main_sidebar.scss +42 -46
- data/app/assets/stylesheets/binda/components/main_sortable_table.scss +12 -21
- data/app/assets/stylesheets/binda/components/main_table.scss +18 -35
- data/app/assets/stylesheets/binda/components/popup_warning.scss +14 -27
- data/app/assets/stylesheets/binda/components/select2.scss +46 -48
- data/app/assets/stylesheets/binda/components/sortable.scss +25 -45
- data/app/assets/stylesheets/binda/components/standard-form.scss +43 -73
- data/app/assets/stylesheets/binda/controllers/users_sessions_new.scss +52 -89
- data/app/assets/stylesheets/binda/index.scss +0 -1
- data/app/assets/stylesheets/binda/settings/buttons.scss +9 -10
- data/app/assets/stylesheets/binda/settings/common.scss +17 -22
- data/app/assets/stylesheets/binda/settings/fonts.scss +112 -67
- data/app/assets/stylesheets/binda/settings/tiny_mce_overrides.scss +20 -36
- data/app/assets/stylesheets/binda/settings/variables.scss +38 -43
- data/app/controllers/binda/choices_controller.rb +14 -11
- data/app/controllers/binda/components_controller.rb +6 -4
- data/app/controllers/binda/structures_controller.rb +7 -3
- data/app/helpers/binda/components_helper.rb +69 -3
- data/app/helpers/binda/field_groups_helper.rb +16 -6
- data/app/helpers/binda/structures_helper.rb +1 -4
- data/app/models/binda/application_record.rb +4 -1
- data/app/models/binda/asset.rb +3 -1
- data/app/models/binda/b.rb +1 -0
- data/app/models/binda/category.rb +1 -0
- data/app/models/binda/checkbox.rb +2 -0
- data/app/models/binda/choice.rb +74 -41
- data/app/models/binda/component.rb +1 -1
- data/app/models/binda/date.rb +4 -0
- data/app/models/binda/deprecation.rb +7 -0
- data/app/models/binda/field_group.rb +16 -3
- data/app/models/binda/field_setting.rb +168 -41
- data/app/models/binda/image.rb +1 -0
- data/app/models/binda/radio.rb +2 -0
- data/app/models/binda/relation.rb +3 -0
- data/app/models/binda/repeater.rb +3 -0
- data/app/models/binda/selection.rb +237 -0
- data/app/models/binda/string.rb +4 -0
- data/app/models/binda/structure.rb +25 -14
- data/app/models/binda/text.rb +9 -0
- data/app/models/binda/video.rb +1 -0
- data/app/models/concerns/binda/default_helpers.rb +40 -31
- data/app/models/concerns/binda/deprecations.rb +6 -0
- data/app/models/concerns/binda/fieldable_association_helpers.rb +366 -0
- data/app/models/concerns/binda/fieldable_associations.rb +32 -369
- data/app/views/binda/boards/edit.html.erb +15 -2
- data/app/views/binda/categories/_form.html.erb +24 -51
- data/app/views/binda/categories/edit.html.erb +23 -3
- data/app/views/binda/categories/index.html.erb +49 -25
- data/app/views/binda/categories/new.html.erb +21 -2
- data/app/views/binda/components/edit.html.erb +27 -4
- data/app/views/binda/components/index.html.erb +47 -50
- data/app/views/binda/components/new.html.erb +12 -2
- data/app/views/binda/components/sort_index.html.erb +28 -13
- data/app/views/binda/field_groups/_form_body.html.erb +43 -82
- data/app/views/binda/field_groups/_form_item.html.erb +3 -120
- data/app/views/binda/field_groups/_form_section.html.erb +11 -16
- data/app/views/binda/field_groups/_form_section_repeater.html.erb +7 -15
- data/app/views/binda/field_groups/edit.html.erb +14 -2
- data/app/views/binda/field_groups/form_item/_form_item_choice_editor.html.erb +11 -0
- data/app/views/binda/field_groups/form_item/_form_item_editor.html.erb +14 -0
- data/app/views/binda/field_groups/form_item/_form_item_header.html.erb +25 -0
- data/app/views/binda/field_groups/form_item/_form_item_new_editor.html.erb +8 -0
- data/app/views/binda/field_groups/form_item/_form_item_persisted_editor.html.erb +27 -0
- data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_allow_null_choice.html.erb +11 -0
- data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_choice_header.html.erb +11 -0
- data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_default_choice.html.erb +11 -0
- data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_new_choice.html.erb +16 -0
- data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_persisted_choices.html.erb +16 -0
- data/app/views/binda/field_groups/new.html.erb +14 -2
- data/app/views/binda/field_settings/_form_body.html.erb +1 -3
- data/app/views/binda/field_settings/edit.html.erb +1 -1
- data/app/views/binda/field_settings/new.html.erb +1 -1
- data/app/views/binda/fieldable/_form_body.html.erb +24 -72
- data/app/views/binda/fieldable/_form_item_date.html.erb +1 -4
- data/app/views/binda/fieldable/_form_item_image.html.erb +3 -7
- data/app/views/binda/fieldable/_form_item_new_repeater.html.erb +0 -13
- data/app/views/binda/fieldable/_form_item_selections.html.erb +20 -112
- data/app/views/binda/fieldable/form_item_selections/_form_item_checkbox.html.erb +34 -0
- data/app/views/binda/fieldable/form_item_selections/_form_item_radio.html.erb +28 -0
- data/app/views/binda/fieldable/form_item_selections/_form_item_selection.html.erb +30 -0
- data/app/views/binda/manage/users/_form_body.html.erb +1 -31
- data/app/views/binda/manage/users/edit.html.erb +12 -2
- data/app/views/binda/manage/users/index.html.erb +36 -19
- data/app/views/binda/manage/users/new.html.erb +14 -3
- data/app/views/binda/structures/_form_body.html.erb +2 -25
- data/app/views/binda/structures/_form_section.html.erb +43 -65
- data/app/views/binda/structures/_form_sidebar.html.erb +19 -12
- data/app/views/binda/structures/edit.html.erb +20 -3
- data/app/views/binda/structures/index.html.erb +46 -26
- data/app/views/binda/structures/new.html.erb +13 -2
- data/app/views/binda/structures/sort_index.html.erb +37 -17
- data/app/views/binda/users/sessions/new.html.erb +25 -20
- data/app/views/layouts/binda/_form_errors.html.erb +10 -0
- data/app/views/layouts/binda/_sidebar.html.erb +6 -6
- data/app/views/layouts/binda/application.html.erb +1 -1
- data/config/initializers/carrierwave.rb +3 -2
- data/config/locales/en.yml +56 -12
- data/config/tinymce.yml +2 -2
- data/db/migrate/1_create_binda_tables.rb +1 -1
- data/lib/binda/version.rb +1 -1
- data/lib/generators/binda/setup/setup_generator.rb +2 -2
- data/lib/tasks/add_default_choice_to_all_selections_with_no_choices_task.rake +6 -0
- metadata +58 -8
- data/app/assets/stylesheets/binda/components/form_item_image.scss +0 -0
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0595e8ebcd16b13684f90a7329163fee69a897f7
|
4
|
+
data.tar.gz: df0c48d8da9db4f7fb62a08ac1e45c29419b09f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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*
|
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
|
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
|
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
|
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
|
337
|
-
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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)
|
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
|
-
|
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
|
-
|
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
|
-
|
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 (
|
15
|
-
alert(
|
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
|
6
|
-
|
5
|
+
import { _FormItemEditor } from "./form_item_editor";
|
7
6
|
|
8
7
|
class FieldSettingChoices {
|
9
|
-
|
10
|
-
|
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
|
-
|
18
|
-
else {
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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 = $(
|
48
|
-
var choices = $(`#${choices_id}`)
|
49
|
-
var newchoice = choices.find(
|
50
|
-
var clone = newchoice
|
51
|
-
|
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(
|
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
|
-
|
60
|
-
|
61
|
-
|
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:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
11
|
-
this.target = '.fileupload'
|
9
|
+
constructor() {
|
10
|
+
this.target = ".fileupload";
|
12
11
|
}
|
13
12
|
|
14
|
-
isSet()
|
15
|
-
|
16
|
-
|
17
|
-
else {
|
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(
|
24
|
+
$(document).on("click", ".fileupload--remove-image-btn", remove_preview);
|
25
25
|
|
26
|
-
$(document).on(
|
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
|
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 (
|
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(
|
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(
|
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(
|
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(
|
68
|
-
if (
|
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
|
-
$(
|
82
|
-
$(
|
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
|
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
|
-
|
97
|
-
|
98
|
-
|
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
|
123
|
-
|
124
|
-
input.value = ''
|
112
|
+
function updateFileuploadField(data, id) {
|
113
|
+
let $parent = $("#fileupload-" + id);
|
125
114
|
|
126
|
-
if(
|
127
|
-
|
128
|
-
|
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
|
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
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
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
|
146
|
-
|
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 $
|
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(
|
170
|
+
$preview.css("background-image", `url(${data.thumbnailUrl})`);
|
156
171
|
|
157
172
|
// Remove and add class to trigger css animation
|
158
|
-
let uploadedClass =
|
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(
|
163
|
-
$parent.find(
|
164
|
-
$parent.find(
|
165
|
-
$parent.find(
|
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 $
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
if (
|
182
|
-
|
183
|
-
|
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 =
|
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(
|
192
|
-
$parent.find(
|
193
|
-
$parent.find(
|
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
|
+
}
|