binda 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|