alchemy-form 0.1.12 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/assets/stylesheets/form/alchemy_form.scss +2 -16
  3. package/assets/stylesheets/form/elements/_button.scss +52 -0
  4. package/assets/stylesheets/form/{alchemy_code_input.scss → elements/_code_input.scss} +1 -1
  5. package/assets/stylesheets/form/{alchemy_feedback_input.scss → elements/_feedback_input.scss} +6 -8
  6. package/assets/stylesheets/form/{alchemy_field.scss → elements/_field.scss} +1 -1
  7. package/assets/stylesheets/form/{alchemy_field_array.scss → elements/_field_array.scss} +2 -2
  8. package/assets/stylesheets/form/{alchemy_field_translatable.scss → elements/_field_translatable.scss} +1 -1
  9. package/assets/stylesheets/form/elements/_form.scss +16 -0
  10. package/assets/stylesheets/form/{alchemy_pager.scss → elements/_pager.scss} +1 -1
  11. package/assets/stylesheets/form/{query_builder.scss → elements/_query_builder.scss} +7 -7
  12. package/assets/stylesheets/form/{alchemy_select.scss → elements/_select.scss} +2 -2
  13. package/assets/stylesheets/form/elements/_state.scss +8 -0
  14. package/assets/stylesheets/form/{alchemy_table.scss → elements/_table.scss} +2 -2
  15. package/assets/stylesheets/form/elements/_tabs.scss +47 -0
  16. package/assets/stylesheets/form/{alchemy_toggle.scss → elements/_toggle.scss} +1 -1
  17. package/assets/stylesheets/form/elements/index.scss +14 -0
  18. package/element/00_form_base.js +16 -8
  19. package/element/05_feedback_input.js +4 -13
  20. package/element/10_alchemy_field_custom.js +13 -15
  21. package/element/10_dataprovider.js +282 -0
  22. package/element/15_alchemy_field_entry.js +8 -10
  23. package/element/20_query_builder_base.js +4 -13
  24. package/element/25_query_builder_data.js +2 -2
  25. package/element/30_tab_base.js +29 -0
  26. package/element/40_stateful.js +125 -0
  27. package/element/al_button.js +109 -0
  28. package/element/{code_input.js → al_code_input.js} +1 -10
  29. package/element/{alchemy_field.js → al_field.js} +15 -24
  30. package/element/{alchemy_field_array.js → al_field_array.js} +7 -18
  31. package/element/{alchemy_field_array_entry.js → al_field_array_entry.js} +7 -9
  32. package/element/{alchemy_field_schema.js → al_field_schema.js} +3 -3
  33. package/element/{alchemy_field_translatable.js → al_field_translatable.js} +6 -17
  34. package/element/{alchemy_field_translatable_entry.js → al_field_translatable_entry.js} +2 -4
  35. package/element/{alchemy_form.js → al_form.js} +7 -16
  36. package/element/{alchemy_label.js → al_label.js} +1 -10
  37. package/element/{number_input.js → al_number_input.js} +2 -2
  38. package/element/{alchemy_pager.js → al_pager.js} +49 -41
  39. package/element/{alchemy_password_input.js → al_password_input.js} +0 -0
  40. package/element/{query_builder.js → al_query_builder.js} +3 -12
  41. package/element/{query_builder_entry.js → al_query_builder_entry.js} +2 -2
  42. package/element/{query_builder_group.js → al_query_builder_group.js} +7 -7
  43. package/element/{query_builder_value.js → al_query_builder_value.js} +2 -2
  44. package/element/{query_builder_variable.js → al_query_builder_variable.js} +1 -1
  45. package/element/{alchemy_select.js → al_select.js} +35 -108
  46. package/element/{alchemy_select_item.js → al_select_item.js} +15 -9
  47. package/element/al_state.js +26 -0
  48. package/element/{string_input.js → al_string_input.js} +2 -2
  49. package/element/al_tab_button.js +138 -0
  50. package/element/al_tab_context.js +102 -0
  51. package/element/al_tab_list.js +66 -0
  52. package/element/al_tab_panel.js +44 -0
  53. package/element/{alchemy_table.js → al_table.js} +187 -174
  54. package/element/{alchemy_toggle.js → al_toggle.js} +1 -10
  55. package/helper/form_actions/00_form_action.js +15 -4
  56. package/helper/form_actions/url_action.js +3 -2
  57. package/helper/query_builder_variable_definition/boolean_variable_definition.js +1 -1
  58. package/helper_field/query_builder_field.js +2 -2
  59. package/package.json +2 -2
  60. package/view/form/elements/alchemy_button.hwk +1 -0
  61. package/view/form/elements/alchemy_field.hwk +4 -4
  62. package/view/form/elements/alchemy_field_array.hwk +2 -2
  63. package/view/form/elements/alchemy_field_schema.hwk +2 -2
  64. package/view/form/elements/alchemy_field_translatable.hwk +2 -2
  65. package/view/form/elements/alchemy_field_translatable_entry.hwk +2 -2
  66. package/view/form/elements/query_builder.hwk +1 -1
  67. package/view/form/elements/query_builder_entry.hwk +6 -6
  68. package/view/form/elements/query_builder_value.hwk +2 -2
  69. package/view/form/elements/query_builder_variable.hwk +2 -2
  70. package/view/form/inputs/edit/belongs_to.hwk +2 -2
  71. package/view/form/inputs/edit/boolean.hwk +2 -2
  72. package/view/form/inputs/edit/enum.hwk +2 -2
  73. package/view/form/inputs/edit/has_and_belongs_to_many.hwk +2 -2
  74. package/view/form/inputs/edit/html.hwk +2 -2
  75. package/view/form/inputs/edit/query_builder.hwk +2 -2
  76. package/view/form/inputs/edit/query_builder_assignment.hwk +2 -2
  77. package/view/form/inputs/edit/query_builder_value.hwk +2 -2
  78. package/view/form/inputs/edit/query_builder_variable.hwk +2 -2
  79. package/view/form/inputs/edit/schema.hwk +2 -2
  80. package/view/form/inputs/edit/sourcecode.hwk +2 -2
  81. package/view/form/inputs/edit_inline/boolean.hwk +2 -2
  82. package/view/form/inputs/view/string.hwk +6 -1
  83. package/view/form/inputs/view_inline/datetime.hwk +8 -4
  84. package/view/form/inputs/view_inline/string.hwk +6 -1
  85. package/view/form/wrappers/default/default.hwk +2 -2
  86. package/helper/widgets/alchemy_field_widget.js +0 -112
  87. package/helper/widgets/alchemy_form_widget.js +0 -183
  88. package/helper/widgets/alchemy_table_widget.js +0 -67
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The alchemy-toggle custom element
2
+ * The al-query-builder-group custom element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@elevenways.be>
5
5
  * @since 0.1.6
@@ -171,7 +171,7 @@ QueryBuilderGroup.setProperty(function value() {
171
171
  *
172
172
  * @author Jelle De Loecker <jelle@elevenways.be>
173
173
  * @since 0.1.6
174
- * @version 0.1.7
174
+ * @version 0.2.0
175
175
  */
176
176
  QueryBuilderGroup.setMethod(function applyValue(value) {
177
177
 
@@ -198,9 +198,9 @@ QueryBuilderGroup.setMethod(function applyValue(value) {
198
198
 
199
199
  for (rule of value.rules) {
200
200
  if (rule.type == 'qb_entry') {
201
- element = this.createElement('alchemy-query-builder-entry');
201
+ element = this.createElement('al-query-builder-entry');
202
202
  } else {
203
- element = this.createElement('alchemy-query-builder-group');
203
+ element = this.createElement('al-query-builder-group');
204
204
  }
205
205
 
206
206
  element.assigned_data.value = rule;
@@ -214,7 +214,7 @@ QueryBuilderGroup.setMethod(function applyValue(value) {
214
214
  *
215
215
  * @author Jelle De Loecker <jelle@elevenways.be>
216
216
  * @since 0.1.6
217
- * @version 0.1.7
217
+ * @version 0.2.0
218
218
  */
219
219
  QueryBuilderGroup.setMethod(function introduced() {
220
220
 
@@ -225,14 +225,14 @@ QueryBuilderGroup.setMethod(function introduced() {
225
225
  add_rule.addEventListener('click', e => {
226
226
  e.preventDefault();
227
227
 
228
- let new_rule = this.createElement('alchemy-query-builder-entry');
228
+ let new_rule = this.createElement('al-query-builder-entry');
229
229
  this.rules_list.append(new_rule);
230
230
  });
231
231
 
232
232
  add_group.addEventListener('click', e => {
233
233
  e.preventDefault();
234
234
 
235
- let new_group = this.createElement('alchemy-query-builder-group');
235
+ let new_group = this.createElement('al-query-builder-group');
236
236
  this.rules_list.append(new_group);
237
237
  });
238
238
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The alchemy-query-builder-value custom element
2
+ * The al-query-builder-value custom element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@elevenways.be>
5
5
  * @since 0.1.6
@@ -186,7 +186,7 @@ QueryBuilderValue.setMethod(async function applySourceTypeChanges() {
186
186
  let type = this.source_type_select.value;
187
187
 
188
188
  if (type == 'variable') {
189
- let select = this.createElement('alchemy-select');
189
+ let select = this.createElement('al-select');
190
190
  select.dataprovider = this;
191
191
  select.classList.add('qb-value-variable');
192
192
  this.value_input_wrapper.append(select);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The alchemy-query-builder-value custom element
2
+ * The al-query-builder-value custom element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@elevenways.be>
5
5
  * @since 0.1.7
@@ -1,20 +1,11 @@
1
1
  /**
2
- * The alchemy-select element
2
+ * The al-select element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@develry.be>
5
5
  * @since 0.1.0
6
6
  * @version 0.1.0
7
7
  */
8
- const AlchemySelect = Function.inherits('Alchemy.Element.Form.Base', 'Select');
9
-
10
- /**
11
- * The remote url attribute
12
- *
13
- * @author Jelle De Loecker <jelle@develry.be>
14
- * @since 0.1.0
15
- * @version 0.1.0
16
- */
17
- AlchemySelect.setAttribute('src');
8
+ const AlchemySelect = Function.inherits('Alchemy.Element.Form.WithDataprovider', 'Select');
18
9
 
19
10
  /**
20
11
  * The value clear count
@@ -63,15 +54,6 @@ AlchemySelect.setAttribute('option-item-template');
63
54
  */
64
55
  AlchemySelect.setTemplateFile('form/elements/alchemy_select');
65
56
 
66
- /**
67
- * The stylesheet to load for this element
68
- *
69
- * @author Jelle De Loecker <jelle@develry.be>
70
- * @since 0.1.0
71
- * @version 0.1.0
72
- */
73
- AlchemySelect.setStylesheetFile('form/alchemy_select');
74
-
75
57
  /**
76
58
  * Getter for the value-wrapper div
77
59
  *
@@ -135,16 +117,6 @@ AlchemySelect.addElementGetter('result_info', '.result-info');
135
117
  */
136
118
  AlchemySelect.setAssignedProperty('sortable');
137
119
 
138
- /**
139
- * The dataprovider is an instance of something that will load
140
- * the remote data for this element
141
- *
142
- * @author Jelle De Loecker <jelle@elevenways.be>
143
- * @since 0.1.0
144
- * @version 0.1.0
145
- */
146
- AlchemySelect.setAssignedProperty('dataprovider');
147
-
148
120
  /**
149
121
  * The value property
150
122
  *
@@ -495,7 +467,7 @@ AlchemySelect.setMethod(function introduced() {
495
467
 
496
468
  this.addEventListener('keydown', function onKeydown(e) {
497
469
 
498
- // Only listen for keydowns on the alchemy-select itself
470
+ // Only listen for keydowns on the al-select itself
499
471
  if (e.target != that) {
500
472
  return;
501
473
  }
@@ -779,7 +751,7 @@ AlchemySelect.setMethod(function getValueData(value) {
779
751
  *
780
752
  * @author Jelle De Loecker <jelle@develry.be>
781
753
  * @since 0.1.0
782
- * @version 0.1.0
754
+ * @version 0.2.0
783
755
  *
784
756
  * @param {Number} page
785
757
  *
@@ -802,7 +774,7 @@ AlchemySelect.setMethod(function _ensureValueData(value) {
802
774
 
803
775
  this.delayAssemble(pledge);
804
776
 
805
- this._loadRemote({value: value}).done(function gotValueData(err, result) {
777
+ this.fetchRemoteData({value: value}).done(function gotValueData(err, result) {
806
778
 
807
779
  if (err) {
808
780
  return pledge.reject(err);
@@ -928,93 +900,49 @@ AlchemySelect.setMethod(function _processResponseList(list, page) {
928
900
  });
929
901
 
930
902
  /**
931
- * Load remote content
932
- *
933
- * @author Jelle De Loecker <jelle@develry.be>
934
- * @since 0.1.0
935
- * @version 0.1.8
936
- *
937
- * @param {Number} page
903
+ * Construct the config object used to fetch data
938
904
  *
939
- * @return {Pledge}
905
+ * @author Jelle De Loecker <jelle@elevenways.be>
906
+ * @since 0.2.0
907
+ * @version 0.2.0
940
908
  */
941
- AlchemySelect.setMethod(function loadRemote(page) {
942
-
943
- let pledge = new Classes.Pledge();
909
+ AlchemySelect.setMethod(function getRemoteFetchConfig() {
944
910
 
945
911
  // Don't perform request when everything has already been loaded
946
912
  if (this.total_item_count >= this.loaded_item_count) {
947
- pledge.resolve(true);
948
913
  return;
949
914
  }
950
915
 
951
- if (!this.src && !this.dataprovider) {
952
- pledge.resolve(false);
953
- return pledge;
954
- }
955
-
956
- if (page == null) {
957
- page = 1;
958
- }
959
-
960
- const that = this;
961
-
962
- this.loading_dropdown = true;
963
-
964
- let data = {
916
+ let config = {
965
917
  search : this.search_value,
966
- page : page
967
- };
968
-
969
- this._loadRemote(data).done(gotResponse);
970
-
971
- function gotResponse(err, data) {
972
-
973
- if (err) {
974
- that.loading_dropdown = false;
975
- pledge.resolve(false);
976
- throw err;
977
- }
978
-
979
- if (page == null || page == 1) {
980
- Hawkejs.removeChildren(that.dropdown_content);
981
- }
982
-
983
- that._processResponseData(data, page);
984
-
985
- pledge.resolve(true);
918
+ page : this.page || 1,
986
919
  };
987
920
 
988
- return pledge;
921
+ return config;
989
922
  });
990
923
 
924
+
991
925
  /**
992
- * Load remote content
993
- *
994
- * @author Jelle De Loecker <jelle@develry.be>
995
- * @since 0.1.0
996
- * @version 0.1.0
926
+ * Apply the fetched data
997
927
  *
998
- * @param {Object) config
999
- *
1000
- * @return {Pledge}
928
+ * @author Jelle De Loecker <jelle@elevenways.be>
929
+ * @since 0.2.0
930
+ * @version 0.2.0
1001
931
  */
1002
- AlchemySelect.setMethod(function _loadRemote(config) {
932
+ AlchemySelect.setMethod(function applyFetchedData(err, result, config) {
1003
933
 
1004
- let pledge;
934
+ if (err) {
935
+ this.loading_dropdown = false;
936
+ return;
937
+ }
1005
938
 
1006
- if (this.dataprovider) {
1007
- pledge = Blast.Classes.Pledge.cast(this.dataprovider.loadData(config, this));
1008
- } else {
1009
- let url = this.src;
939
+ let page = config.page;
1010
940
 
1011
- pledge = this.hawkejs_helpers.Alchemy.getResource({
1012
- href : url,
1013
- get : config
1014
- });
941
+ if (page == null || page == 1) {
942
+ Hawkejs.removeChildren(this.dropdown_content);
1015
943
  }
1016
944
 
1017
- return pledge;
945
+ this._processResponseData(result, page);
1018
946
  });
1019
947
 
1020
948
  /**
@@ -1091,7 +1019,7 @@ AlchemySelect.setMethod(function setLastSuccessfulLoadedPage(page) {
1091
1019
  *
1092
1020
  * @author Jelle De Loecker <jelle@develry.be>
1093
1021
  * @since 0.1.0
1094
- * @version 0.1.8
1022
+ * @version 0.2.0
1095
1023
  *
1096
1024
  * @param {Number} page
1097
1025
  */
@@ -1131,9 +1059,8 @@ AlchemySelect.setMethod(function loadOptions(page) {
1131
1059
  return;
1132
1060
  }
1133
1061
 
1134
- // If an URL is provided, use that
1135
- if (this.src || this.dataprovider) {
1136
- return this.loadRemote(page);
1062
+ if (this.can_fetch_remote_data) {
1063
+ return this.loadRemoteData({page});
1137
1064
  }
1138
1065
 
1139
1066
  let field = this.model_field;
@@ -1291,7 +1218,7 @@ AlchemySelect.setMethod(function close(event) {
1291
1218
  *
1292
1219
  * @author Jelle De Loecker <jelle@develry.be>
1293
1220
  * @since 0.1.0
1294
- * @version 0.1.6
1221
+ * @version 0.2.0
1295
1222
  *
1296
1223
  * @param {String} type "value" or "option"
1297
1224
  * @param {Mixed} value The actual value of this item
@@ -1301,7 +1228,7 @@ AlchemySelect.setMethod(function close(event) {
1301
1228
  */
1302
1229
  AlchemySelect.setMethod(function _makeValueItem(type, value, data) {
1303
1230
 
1304
- let item = this.createElement('alchemy-select-item');
1231
+ let item = this.createElement('al-select-item');
1305
1232
 
1306
1233
  // Set the type ("value" or "option")
1307
1234
  item.type = type;
@@ -1350,7 +1277,7 @@ AlchemySelect.setMethod(function _makeValueItem(type, value, data) {
1350
1277
  item.prepareRenderVariables = async function() {
1351
1278
 
1352
1279
  try {
1353
- await that.loadRemote();
1280
+ await that.loadRemoteData();
1354
1281
  } catch (err) {
1355
1282
  return
1356
1283
  }
@@ -1796,11 +1723,11 @@ AlchemySelect.setMethod(function applyLocalFilter(query) {
1796
1723
  *
1797
1724
  * @author Jelle De Loecker <jelle@develry.be>
1798
1725
  * @since 0.1.0
1799
- * @version 0.1.8
1726
+ * @version 0.2.0
1800
1727
  */
1801
1728
  AlchemySelect.setMethod('refreshRemote', Fn.throttle(function refreshRemote() {
1802
1729
  this.loaded_page = 0;
1803
- this.loadRemote();
1730
+ this.loadRemoteData();
1804
1731
  }, {
1805
1732
  minimum_wait : 350,
1806
1733
  immediate : false,
@@ -1,14 +1,11 @@
1
1
  /**
2
- * The alchemy-select-item element
2
+ * The al-select-item element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@elevenways.be>
5
5
  * @since 0.1.0
6
- * @version 0.1.0
6
+ * @version 0.2.0
7
7
  */
8
- const Item = Function.inherits('Alchemy.Element.Form.Base', function SelectItem() {
9
- SelectItem.super.call(this);
10
- this.setAttribute('tabindex', '-1');
11
- });
8
+ const Item = Function.inherits('Alchemy.Element.Form.Base', 'SelectItem');
12
9
 
13
10
  /**
14
11
  * Set the default inner template
@@ -28,6 +25,15 @@ Item.setTemplateFile('form/elements/alchemy_select_item');
28
25
  */
29
26
  Item.setAttribute('type');
30
27
 
28
+ /**
29
+ * The type of this item: "value" or "option"
30
+ *
31
+ * @author Jelle De Loecker <jelle@elevenways.be>
32
+ * @since 0.2.0
33
+ * @version 0.2.0
34
+ */
35
+ Item.setAttribute('tabindex', {default: -1});
36
+
31
37
  /**
32
38
  * Is this item selected?
33
39
  *
@@ -65,16 +71,16 @@ Item.setAssignedProperty('value');
65
71
  Item.setAssignedProperty('data');
66
72
 
67
73
  /**
68
- * The parent alchemy-select item
74
+ * The parent al-select item
69
75
  *
70
76
  * @author Jelle De Loecker <jelle@elevenways.be>
71
77
  * @since 0.1.5
72
- * @version 0.1.5
78
+ * @version 0.2.0
73
79
  */
74
80
  Item.enforceProperty(function alchemy_select(new_value) {
75
81
 
76
82
  if (new_value == null) {
77
- new_value = this.closest('alchemy-select');
83
+ new_value = this.closest('al-select');
78
84
  }
79
85
 
80
86
  return new_value;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The al-state element
3
+ *
4
+ * @author Jelle De Loecker <jelle@elevenways.be>
5
+ * @since 0.2.0
6
+ * @version 0.2.0
7
+ */
8
+ const State = Function.inherits('Alchemy.Element.Form.Stateful', 'State');
9
+
10
+ /**
11
+ * The name of the state this element represents
12
+ *
13
+ * @author Jelle De Loecker <jelle@elevenways.be>
14
+ * @since 0.2.0
15
+ * @version 0.2.0
16
+ */
17
+ State.setAttribute('state-name');
18
+
19
+ /**
20
+ * Is this state active?
21
+ *
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
+ * @since 0.2.0
24
+ * @version 0.2.0
25
+ */
26
+ State.setAttribute('active', {boolean: true});
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The alchemy-string-input custom element
2
+ * The al-string-input custom element
3
3
  *
4
4
  * @author Jelle De Loecker <jelle@elevenways.be>
5
5
  * @since 0.1.0
@@ -306,7 +306,7 @@ StringInput.setMethod(async function revalidate(trigger, force) {
306
306
  * @since 0.1.3
307
307
  * @version 0.1.3
308
308
  */
309
- StringInput.setMethod(function introduced() {
309
+ StringInput.setMethod(function introduced() {
310
310
 
311
311
  const that = this,
312
312
  input = this.input_el;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * The al-tab-button element
3
+ *
4
+ * @author Jelle De Loecker <jelle@elevenways.be>
5
+ * @since 0.2.0
6
+ * @version 0.2.0
7
+ */
8
+ const TabButton = Function.inherits('Alchemy.Element.Form.TabBase', 'TabButton');
9
+
10
+ /**
11
+ * Set the ARIA role of the element
12
+ *
13
+ * @author Jelle De Loecker <jelle@elevenways.be>
14
+ * @since 0.2.0
15
+ * @version 0.2.0
16
+ */
17
+ TabButton.setRole('tab');
18
+
19
+ /**
20
+ * Only the active tab should be tabable
21
+ *
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
+ * @since 0.2.0
24
+ * @version 0.2.0
25
+ */
26
+ TabButton.setAttribute('tabindex', {default: -1});
27
+
28
+ /**
29
+ * The name of the tab
30
+ *
31
+ * @author Jelle De Loecker <jelle@elevenways.be>
32
+ * @since 0.2.0
33
+ * @version 0.2.0
34
+ */
35
+ TabButton.setAttribute('tab-name');
36
+
37
+ /**
38
+ * Is this tab active?
39
+ *
40
+ * @author Jelle De Loecker <jelle@elevenways.be>
41
+ * @since 0.2.0
42
+ * @version 0.2.0
43
+ */
44
+ TabButton.setAttribute('active', null, function setActive(value) {
45
+
46
+ if (value != null) {
47
+ this.activate(value);
48
+ }
49
+
50
+ return value;
51
+ }, {boolean: true});
52
+
53
+ /**
54
+ * Get the corresponding tab content element
55
+ *
56
+ * @author Jelle De Loecker <jelle@elevenways.be>
57
+ * @since 0.2.0
58
+ * @version 0.2.0
59
+ */
60
+ TabButton.setMethod(function getContentElement() {
61
+
62
+ const tab_name = this.dataset.tabName;
63
+
64
+ if (!tab_name) {
65
+ return;
66
+ }
67
+
68
+ let context = this.tab_context;
69
+
70
+ if (!context) {
71
+ return;
72
+ }
73
+
74
+ return context.querySelector('al-tab-content[tab-name="' + tab_name + '"]');
75
+ });
76
+
77
+ /**
78
+ * Activate this tab
79
+ *
80
+ * @author Jelle De Loecker <jelle@elevenways.be>
81
+ * @since 0.2.0
82
+ * @version 0.2.0
83
+ */
84
+ TabButton.setMethod(function activate(value) {
85
+
86
+ let context = this.tab_context;
87
+
88
+ if (!context) {
89
+ return;
90
+ }
91
+
92
+ if (value == null) {
93
+ value = true;
94
+ }
95
+
96
+ let all_buttons = context.getAllTabButtons(),
97
+ all_contents = context.getAllTabContents();
98
+
99
+ this.setAttributeSilent('active', value);
100
+
101
+ // If this tab is activated, others have to be deactivated
102
+ if (value) {
103
+ for (let button of all_buttons) {
104
+ if (button != this && button.active) {
105
+ button.active = false;
106
+ }
107
+ }
108
+
109
+ this.setAttribute('aria-selected', true);
110
+ this.setAttribute('tabindex', 0);
111
+ } else {
112
+ this.removeAttribute('aria-selected');
113
+ this.setAttribute('tabindex', -1);
114
+ }
115
+
116
+ for (let content of all_contents) {
117
+ if (content.tab_name == this.tab_name) {
118
+ content.active = value;
119
+ } else if (value) {
120
+ content.active = false;
121
+ }
122
+ }
123
+
124
+ });
125
+
126
+ /**
127
+ * Added to the DOM for the first time
128
+ *
129
+ * @author Jelle De Loecker <jelle@elevenways.be>
130
+ * @since 0.2.0
131
+ * @version 0.2.0
132
+ */
133
+ TabButton.setMethod(function introduced() {
134
+
135
+ this.addEventListener('click', e => {
136
+ this.activate();
137
+ });
138
+ });
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The al-tab-context element
3
+ *
4
+ * @author Jelle De Loecker <jelle@elevenways.be>
5
+ * @since 0.2.0
6
+ * @version 0.2.0
7
+ */
8
+ const TabContext = Function.inherits('Alchemy.Element.Form.TabBase', 'TabContext');
9
+
10
+ /**
11
+ * The "value", or active tab
12
+ *
13
+ * @author Jelle De Loecker <jelle@elevenways.be>
14
+ * @since 0.2.0
15
+ * @version 0.2.0
16
+ *
17
+ * @return {AlchemyTabButton[]}
18
+ */
19
+ TabContext.setAttribute('value', function getValue(value) {
20
+
21
+ let all_buttons = this.getAllTabButtons();
22
+
23
+ if (all_buttons.length) {
24
+ value = '';
25
+
26
+ for (let entry of all_buttons) {
27
+ if (entry.active) {
28
+ value = entry.tab_name;
29
+ break;
30
+ }
31
+ }
32
+ }
33
+
34
+ return value;
35
+
36
+ }, function setValue(value) {
37
+
38
+ let all_buttons = this.getAllTabButtons(),
39
+ activated = false;
40
+
41
+ if (all_buttons.length) {
42
+ for (let entry of all_buttons) {
43
+ if (entry.tab_name == value) {
44
+ entry.active = true;
45
+ activated = true;
46
+ } else {
47
+ entry.active = false;
48
+ }
49
+ }
50
+
51
+ // If nothing was activated, activate the first one
52
+ if (!activated) {
53
+ all_buttons[0].active = true;
54
+ value = all_buttons[0].tab_name;
55
+ }
56
+ }
57
+
58
+ return value;
59
+ });
60
+
61
+ /**
62
+ * Do something when this element is retained
63
+ *
64
+ * @author Jelle De Loecker <jelle@elevenways.be>
65
+ * @since 0.2.0
66
+ * @version 0.2.0
67
+ */
68
+ TabContext.setMethod(function retained() {
69
+
70
+ let value = this.value;
71
+
72
+ if (!value) {
73
+ // Trigger setValue, which will select the first tab
74
+ this.value = '';
75
+ }
76
+ });
77
+
78
+ /**
79
+ * Get all the tab buttons
80
+ *
81
+ * @author Jelle De Loecker <jelle@elevenways.be>
82
+ * @since 0.2.0
83
+ * @version 0.2.0
84
+ *
85
+ * @return {AlchemyTabButton[]}
86
+ */
87
+ TabContext.setMethod(function getAllTabButtons() {
88
+ return this.queryAllNotNested('al-tab-button');
89
+ });
90
+
91
+ /**
92
+ * Get all the tab contents
93
+ *
94
+ * @author Jelle De Loecker <jelle@elevenways.be>
95
+ * @since 0.2.0
96
+ * @version 0.2.0
97
+ *
98
+ * @return {AlchemyTabButton[]}
99
+ */
100
+ TabContext.setMethod(function getAllTabContents() {
101
+ return this.queryAllNotNested('al-tab-panel');
102
+ });