not-bulma 1.0.53 → 1.0.55

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-bulma",
3
- "version": "1.0.53",
3
+ "version": "1.0.55",
4
4
  "description": "not-* family UI components on Bulma CSS Framework",
5
5
  "main": "src/index.js",
6
6
  "svelte": "src/index.js",
@@ -8,6 +8,7 @@ import notBase from "../../base";
8
8
  import UICommon from "../../../elements/common.js";
9
9
  import FormHelpers from "./form.helpers.js";
10
10
  import UIFormComponent from "./form.svelte";
11
+ import notFormRules from "./form.rules.js";
11
12
 
12
13
  import { DEFAULT_STATUS_SUCCESS, DEFAULT_STATUS_ERROR } from "../../const";
13
14
 
@@ -141,6 +142,34 @@ class notForm extends notBase {
141
142
  this.#form.$on("submit", (ev) => this.submit(ev.detail));
142
143
  this.#form.$on("reject", () => this.reject());
143
144
  this.#form.$on("error", ({ detail }) => this.emit("error", detail));
145
+ this.#bindMasterSlaveEvents();
146
+ }
147
+
148
+ #bindMasterSlaveEvents() {
149
+ const masters = this.getOptions("masters", false);
150
+ if (!masters) {
151
+ return;
152
+ }
153
+ for (let master in masters) {
154
+ const rules = masters[master];
155
+ for (let ruleName in rules) {
156
+ const ruleSlaves = rules[ruleName];
157
+ this.#addMasterSlaveEvents(ruleName, master, ruleSlaves);
158
+ }
159
+ }
160
+ }
161
+
162
+ #addMasterSlaveEvents(rule, master, slaves = []) {
163
+ this.on(`change.${master}`, (value) => {
164
+ this.#execSlaveRule(rule, slaves, value);
165
+ });
166
+ }
167
+
168
+ #execSlaveRule(rule, slaves, value) {
169
+ const cmd = notFormRules.exec(rule, value);
170
+ slaves.forEach((slaveField) => {
171
+ this.updateField(slaveField, cmd);
172
+ });
144
173
  }
145
174
 
146
175
  async validateForm() {
@@ -0,0 +1,45 @@
1
+ const DEFAULT_RULES = {
2
+ notReadonly(v) {
3
+ return {
4
+ readonly: !v,
5
+ };
6
+ },
7
+ readonly(v) {
8
+ return {
9
+ readonly: v,
10
+ };
11
+ },
12
+ enable(v) {
13
+ return {
14
+ disabled: !v,
15
+ };
16
+ },
17
+ disable(v) {
18
+ return {
19
+ disabled: v,
20
+ };
21
+ },
22
+ };
23
+
24
+ export default class notFormRules {
25
+ static #RULES = { ...DEFAULT_RULES };
26
+
27
+ static add(name, func) {
28
+ if (!Object.hasOwn(this.#RULES, name)) {
29
+ this.#RULES[name] = func;
30
+ }
31
+ }
32
+
33
+ static remove(name) {
34
+ if (
35
+ Object.hasOwn(this.#RULES, name) &&
36
+ !Object.keys(DEFAULT_RULES).includes(name)
37
+ ) {
38
+ delete this.#RULES[name];
39
+ }
40
+ }
41
+
42
+ static exec(name, value) {
43
+ return this.#RULES[name](value);
44
+ }
45
+ }
@@ -1,272 +1,318 @@
1
1
  <script>
2
- import 'bulma-pageloader';
3
- import {
4
- createEventDispatcher
5
- } from 'svelte';
6
- let dispatch = createEventDispatcher();
7
-
8
- import Lib from '../../lib.js';
9
-
10
- import {
11
- LOCALE
12
- } from '../../../locale';
13
-
14
- import UIField from './field.svelte';
15
- import FormHelpers from './form.helpers.js';
16
-
17
- //validation status
18
- let formErrors = [];
19
- let formHasErrors = false;
20
- let fieldsHasErrors = false;
21
- let success = false;
22
-
23
- //input data
24
- //form structure object
25
- /**
26
- * {
27
- * [fieldName: string] => description: object
28
- * }
29
- **/
30
- export let form = {};
31
- //state if form loading
32
- export let loading = false;
33
- //hidden - no loader
34
- //container - parent container of form
35
- //page - whole page
36
- export let loader = 'container';
37
- //fields list structure
38
- /**
39
- * each item is a row
40
- * if item is array, then there few fields in a row
41
- * [
42
- * [name, age],
43
- * [email, telephone]
44
- * bio,
45
- * agreed
46
- * ]
47
- **/
48
- export let fields = [];
49
- //form result labels
50
- export let SUCCESS_TEXT = 'Операция завершена';
51
- export let WAITING_TEXT = 'Отправка данных на сервер';
52
-
53
- //form labels
54
- export let title = 'Форма';
55
- export let description = 'Заполните пожалуйста форму';
56
- //if you want button on top
57
- export let buttonsFirst = false;
58
- //if form fields should have horizontal layout
59
- export let horizontal = false;
60
- //buttons labels and availability
61
- export let submit = {
62
- caption: 'Отправить',
63
- enabled: true
64
- };
65
-
66
- export let cancel = {
67
- caption: 'Назад',
68
- enabled: true
69
- };
70
-
71
- $: formInvalid = formHasErrors || fieldsHasErrors;
72
-
73
- export function collectData() {
74
- return FormHelpers.collectData(fields, form);
75
- }
76
-
77
- export function setFieldInvalid(fieldName, value, errors) {
78
- form = FormHelpers.setFieldInvalid(form, fieldName, value, errors);
79
- fieldsHasErrors = true;
80
- }
81
-
82
- export function setFieldValid(fieldName, value) {
83
- form = FormHelpers.setFieldValid(form, fieldName, value);
84
- if (fieldsHasErrors !== some) {
85
- fieldsHasErrors = some;
86
- }
87
- }
88
-
89
- export function isFieldValid(fieldName) {
90
- return FormHelpers.isFieldValid(form, fieldName);
91
- }
92
-
93
- export function setFormFieldInvalid(fieldName, errors) {
94
- form = FormHelpers.setFormFieldInvalid(form, fieldName, errors);
95
- dispatch(`field.invalid`, {
96
- fieldName
97
- });
98
- }
99
-
100
- export function setFormFieldValid(fieldName) {
101
- form = FormHelpers.setFormFieldValid(form, fieldName);
102
- dispatch(`field.valid`, {
103
- fieldName
104
- });
105
- }
106
-
107
- export function updateFormValidationStatus(
108
- validationStatus /* FormValidationSession.getCompleteResult() */
109
- ) {
110
- formHasErrors = false;
111
- fieldsHasErrors = false;
112
- if (Array.isArray(validationStatus.form) && validationStatus.form.length) {
113
- formErrors.splice(0, formErrors.length, ...validationStatus.form);
114
- formHasErrors = true;
115
- } else {
116
- formErrors.splice(0, formErrors.length);
117
- }
118
- formErrors = formErrors;
119
- if (validationStatus.fields) {
120
- for (let fieldName of Object.keys(form)) {
121
- if (Array.isArray(validationStatus.fields[fieldName]) && validationStatus.fields[fieldName].length) {
122
- FormHelpers.setFormFieldInvalid(form, fieldName, validationStatus.fields[fieldName]);
123
- fieldsHasErrors = true;
124
- } else {
125
- FormHelpers.setFormFieldValid(form, fieldName);
126
- }
127
- }
128
- }
129
- }
130
-
131
- export function showSuccess() {
132
- success = true;
133
- }
134
-
135
- export function setLoading() {
136
- loading = true;
137
- }
138
-
139
- export function resetLoading() {
140
- loading = false;
141
- }
142
-
143
- export function setFieldsVisibility(fieldsList, val) {
144
- if (FormHelpers.setFieldsVisibility(form, fieldsList, val)){
145
- form = form;
146
- }
147
- }
148
-
149
- export function setVisibleFields(fieldsList) {
150
- setFieldsVisibility(fieldsList, true);
151
- }
152
-
153
- export function setInvisibleFields(fieldsList) {
154
- setFieldsVisibility(fieldsList, false);
155
- }
156
-
157
- export function setFieldValue(fieldName, value) {
158
- if (FormHelpers.setFieldValue(form, fieldName, value)){
159
- onFieldChange({
160
- detail: {
161
- field: fieldName,
162
- value
163
- }
164
- });
165
- }
166
- }
167
-
168
- export function updateField(fieldName, props){
169
- form[fieldName] = {
170
- ...form[fieldName],
171
- ...props
172
- };
173
- form = form;
174
- }
175
-
176
- function onFieldChange(ev) {
177
- let data = ev.detail;
178
- form[data.field].value = data.value;
179
- form = form;
180
- dispatch('change', data);
181
- }
182
-
183
- function submitForm(e){
184
- e && e.preventDefault();
185
- dispatch('submit', collectData());
186
- return false;
187
- };
188
-
189
- function rejectForm(){
190
- dispatch('reject');
191
- }
2
+ import "bulma-pageloader";
3
+ import { createEventDispatcher } from "svelte";
4
+ let dispatch = createEventDispatcher();
5
+
6
+ import Lib from "../../lib.js";
7
+
8
+ import { LOCALE } from "../../../locale";
9
+
10
+ import UIField from "./field.svelte";
11
+ import FormHelpers from "./form.helpers.js";
12
+
13
+ //validation status
14
+ let formErrors = [];
15
+ let formHasErrors = false;
16
+ let fieldsHasErrors = false;
17
+ let success = false;
18
+
19
+ //input data
20
+ //form structure object
21
+ /**
22
+ * {
23
+ * [fieldName: string] => description: object
24
+ * }
25
+ **/
26
+ export let form = {};
27
+ //state if form loading
28
+ export let loading = false;
29
+ //hidden - no loader
30
+ //container - parent container of form
31
+ //page - whole page
32
+ export let loader = "container";
33
+ //fields list structure
34
+ /**
35
+ * each item is a row
36
+ * if item is array, then there few fields in a row
37
+ * [
38
+ * [name, age],
39
+ * [email, telephone]
40
+ * bio,
41
+ * agreed
42
+ * ]
43
+ **/
44
+ export let fields = [];
45
+ //form result labels
46
+ export let SUCCESS_TEXT = "Операция завершена";
47
+ export let WAITING_TEXT = "Отправка данных на сервер";
48
+
49
+ //form labels
50
+ export let title = "Форма";
51
+ export let description = "";
52
+ //if you want button on top
53
+ export let buttonsFirst = false;
54
+ //if form fields should have horizontal layout
55
+ export let horizontal = false;
56
+ //buttons labels and availability
57
+ export let submit = {
58
+ caption: "Отправить",
59
+ enabled: true,
60
+ };
61
+
62
+ export let cancel = {
63
+ caption: "Назад",
64
+ enabled: true,
65
+ };
66
+
67
+ $: formInvalid = formHasErrors || fieldsHasErrors;
68
+
69
+ export function collectData() {
70
+ return FormHelpers.collectData(fields, form);
71
+ }
72
+
73
+ export function setFieldInvalid(fieldName, value, errors) {
74
+ form = FormHelpers.setFieldInvalid(form, fieldName, value, errors);
75
+ fieldsHasErrors = true;
76
+ }
77
+
78
+ export function setFieldValid(fieldName, value) {
79
+ form = FormHelpers.setFieldValid(form, fieldName, value);
80
+ if (fieldsHasErrors !== some) {
81
+ fieldsHasErrors = some;
82
+ }
83
+ }
84
+
85
+ export function isFieldValid(fieldName) {
86
+ return FormHelpers.isFieldValid(form, fieldName);
87
+ }
88
+
89
+ export function setFormFieldInvalid(fieldName, errors) {
90
+ form = FormHelpers.setFormFieldInvalid(form, fieldName, errors);
91
+ dispatch(`field.invalid`, {
92
+ fieldName,
93
+ });
94
+ }
95
+
96
+ export function setFormFieldValid(fieldName) {
97
+ form = FormHelpers.setFormFieldValid(form, fieldName);
98
+ dispatch(`field.valid`, {
99
+ fieldName,
100
+ });
101
+ }
102
+
103
+ export function updateFormValidationStatus(
104
+ validationStatus /* FormValidationSession.getCompleteResult() */
105
+ ) {
106
+ formHasErrors = false;
107
+ fieldsHasErrors = false;
108
+ if (
109
+ Array.isArray(validationStatus.form) &&
110
+ validationStatus.form.length
111
+ ) {
112
+ formErrors.splice(0, formErrors.length, ...validationStatus.form);
113
+ formHasErrors = true;
114
+ } else {
115
+ formErrors.splice(0, formErrors.length);
116
+ }
117
+ formErrors = formErrors;
118
+ if (validationStatus.fields) {
119
+ for (let fieldName of Object.keys(form)) {
120
+ if (
121
+ Array.isArray(validationStatus.fields[fieldName]) &&
122
+ validationStatus.fields[fieldName].length
123
+ ) {
124
+ FormHelpers.setFormFieldInvalid(
125
+ form,
126
+ fieldName,
127
+ validationStatus.fields[fieldName]
128
+ );
129
+ fieldsHasErrors = true;
130
+ } else {
131
+ FormHelpers.setFormFieldValid(form, fieldName);
132
+ }
133
+ }
134
+ }
135
+ }
136
+
137
+ export function showSuccess() {
138
+ success = true;
139
+ }
140
+
141
+ export function setLoading() {
142
+ loading = true;
143
+ }
144
+
145
+ export function resetLoading() {
146
+ loading = false;
147
+ }
148
+
149
+ export function setFieldsVisibility(fieldsList, val) {
150
+ if (FormHelpers.setFieldsVisibility(form, fieldsList, val)) {
151
+ form = form;
152
+ }
153
+ }
154
+
155
+ export function setVisibleFields(fieldsList) {
156
+ setFieldsVisibility(fieldsList, true);
157
+ }
158
+
159
+ export function setInvisibleFields(fieldsList) {
160
+ setFieldsVisibility(fieldsList, false);
161
+ }
162
+
163
+ export function setFieldValue(fieldName, value) {
164
+ if (FormHelpers.setFieldValue(form, fieldName, value)) {
165
+ onFieldChange({
166
+ detail: {
167
+ field: fieldName,
168
+ value,
169
+ },
170
+ });
171
+ }
172
+ }
173
+
174
+ export function updateField(fieldName, props) {
175
+ form[fieldName] = {
176
+ ...form[fieldName],
177
+ ...props,
178
+ };
179
+ form = form;
180
+ }
181
+
182
+ function onFieldChange(ev) {
183
+ let data = ev.detail;
184
+ form[data.field].value = data.value;
185
+ form = form;
186
+ dispatch("change", data);
187
+ }
188
+
189
+ function submitForm(e) {
190
+ e && e.preventDefault();
191
+ dispatch("submit", collectData());
192
+ return false;
193
+ }
194
+
195
+ function rejectForm() {
196
+ dispatch("reject");
197
+ }
192
198
  </script>
193
199
 
194
200
  <div class="form-container">
195
-
196
- {#if loader!=='hidden' }
197
- <div class="{loader==='page'?'pageloader':'containerloader'} {loading?'is-active':''}" ><span class="title">{$LOCALE[WAITING_TEXT]}</span></div>
198
- {/if}
199
-
200
- {#if success}
201
- <div class="notification is-success">
202
- <h3 class="form-success-message">{$LOCALE[SUCCESS_TEXT]}</h3>
203
- </div>
204
- {:else}
205
- {#if title }
206
- <h5 class="title is-5">{$LOCALE[title]}</h5>
207
- {/if}
208
- {#if description }
209
- <h6 class="subtitle is-6">{$LOCALE[description]}</h6>
210
- {/if}
211
-
212
- {#if buttonsFirst }
213
- <div class="buttons is-grouped is-centered">
214
- {#if cancel.enabled}
215
- <button class="button is-outlined {cancel.classes}" on:click={rejectForm}>{$LOCALE[cancel.caption]}</button>
216
- {/if}
217
- {#if submit.enabled}
218
- <button on:click={submitForm} disabled={formInvalid} class="button is-primary is-hovered {submit.classes}">{$LOCALE[submit.caption]}</button>
219
- {/if}
220
- </div>
221
-
222
- {#if formErrors.length > 0 }
223
- <div class="edit-form-error notification is-danger">{formErrors.join(', ')}</div>
224
- {/if}
225
-
226
- {/if}
227
-
228
- {#each fields as field}
229
- {#if Array.isArray(field) }
230
- <div class="columns">
231
- {#each field as subfield }
232
- {#if form[subfield] && form[subfield].component }
233
- {#if form[subfield].visible }
234
- <div class="column {form[subfield].fieldSize?('is-'+form[subfield].fieldSize):''} ">
235
- <UIField controls={[form[subfield]]} on:change={onFieldChange} name={subfield} horizontal={horizontal} label={form[subfield].label} />
236
- </div>
237
- {/if}
238
- {:else}
239
- <div class="column notification is-danger">Subfield '{subfield}' is not registered</div>
240
- {/if}
241
- {/each}
242
- </div>
243
- {:else }
244
- {#if form[field] && form[field].component }
245
- {#if form[field].visible}
246
- <UIField controls={[form[field]]} on:change={onFieldChange} name={field} horizontal={horizontal} label={form[field].label} />
247
- {/if}
248
- {:else}
249
- <div class="notification is-danger">Field '{field}' is not registered</div>
250
- {/if}
251
- {/if}
252
- {/each}
253
-
254
- {#if !buttonsFirst }
255
- {#if formErrors.length > 0 }
256
- <div class="edit-form-error notification is-danger">
257
- {#each formErrors as formError}
258
- <span>{$LOCALE[formError]}</span>
259
- {/each}
260
- </div>
261
- {/if}
262
- <div class="buttons is-grouped is-centered">
263
- {#if cancel.enabled}
264
- <button class="button is-outlined {cancel.classes}" on:click={rejectForm}>{$LOCALE[cancel.caption]}</button>
265
- {/if}
266
- {#if submit.enabled}
267
- <button on:click={submitForm} disabled={formInvalid} class="button is-primary is-hovered {submit.classes}">{$LOCALE[submit.caption]}</button>
268
- {/if}
269
- </div>
270
- {/if}
271
- {/if}
201
+ {#if loader !== "hidden"}
202
+ <div
203
+ class="{loader === 'page'
204
+ ? 'pageloader'
205
+ : 'containerloader'} {loading ? 'is-active' : ''}"
206
+ >
207
+ <span class="title">{$LOCALE[WAITING_TEXT]}</span>
208
+ </div>
209
+ {/if}
210
+
211
+ {#if success}
212
+ <div class="notification is-success">
213
+ <h3 class="form-success-message">{$LOCALE[SUCCESS_TEXT]}</h3>
214
+ </div>
215
+ {:else}
216
+ {#if title}
217
+ <h5 class="title is-5">{$LOCALE[title]}</h5>
218
+ {/if}
219
+ {#if description}
220
+ <h6 class="subtitle is-6">{$LOCALE[description]}</h6>
221
+ {/if}
222
+
223
+ {#if buttonsFirst}
224
+ <div class="buttons is-grouped is-centered">
225
+ {#if cancel.enabled}
226
+ <button
227
+ class="button is-outlined {cancel.classes}"
228
+ on:click={rejectForm}>{$LOCALE[cancel.caption]}</button
229
+ >
230
+ {/if}
231
+ {#if submit.enabled}
232
+ <button
233
+ on:click={submitForm}
234
+ disabled={formInvalid}
235
+ class="button is-primary is-hovered {submit.classes}"
236
+ >{$LOCALE[submit.caption]}</button
237
+ >
238
+ {/if}
239
+ </div>
240
+
241
+ {#if formErrors.length > 0}
242
+ <div class="edit-form-error notification is-danger">
243
+ {formErrors.join(", ")}
244
+ </div>
245
+ {/if}
246
+ {/if}
247
+
248
+ {#each fields as field}
249
+ {#if Array.isArray(field)}
250
+ <div class="columns">
251
+ {#each field as subfield}
252
+ {#if form[subfield] && form[subfield].component}
253
+ {#if form[subfield].visible}
254
+ <div
255
+ class="column {form[subfield].fieldSize
256
+ ? 'is-' + form[subfield].fieldSize
257
+ : ''} "
258
+ >
259
+ <UIField
260
+ controls={[form[subfield]]}
261
+ on:change={onFieldChange}
262
+ name={subfield}
263
+ {horizontal}
264
+ label={form[subfield].label}
265
+ />
266
+ </div>
267
+ {/if}
268
+ {:else}
269
+ <div class="column notification is-danger">
270
+ Subfield '{subfield}' is not registered
271
+ </div>
272
+ {/if}
273
+ {/each}
274
+ </div>
275
+ {:else if form[field] && form[field].component}
276
+ {#if form[field].visible}
277
+ <UIField
278
+ controls={[form[field]]}
279
+ on:change={onFieldChange}
280
+ name={field}
281
+ {horizontal}
282
+ label={form[field].label}
283
+ />
284
+ {/if}
285
+ {:else}
286
+ <div class="notification is-danger">
287
+ Field '{field}' is not registered
288
+ </div>
289
+ {/if}
290
+ {/each}
291
+
292
+ {#if !buttonsFirst}
293
+ {#if formErrors.length > 0}
294
+ <div class="edit-form-error notification is-danger">
295
+ {#each formErrors as formError}
296
+ <span>{$LOCALE[formError]}</span>
297
+ {/each}
298
+ </div>
299
+ {/if}
300
+ <div class="buttons is-grouped is-centered">
301
+ {#if cancel.enabled}
302
+ <button
303
+ class="button is-outlined {cancel.classes}"
304
+ on:click={rejectForm}>{$LOCALE[cancel.caption]}</button
305
+ >
306
+ {/if}
307
+ {#if submit.enabled}
308
+ <button
309
+ on:click={submitForm}
310
+ disabled={formInvalid}
311
+ class="button is-primary is-hovered {submit.classes}"
312
+ >{$LOCALE[submit.caption]}</button
313
+ >
314
+ {/if}
315
+ </div>
316
+ {/if}
317
+ {/if}
272
318
  </div>
@@ -1,7 +1,15 @@
1
1
  import notFormUtils from "./utils";
2
2
  import notFormHelpers from "./form.helpers";
3
3
  import notForm from "./form";
4
+ import notFormRules from "./form.rules";
4
5
  import notFormSet from "./form.set";
5
6
  import UIForm from "./form.svelte";
6
7
 
7
- export { UIForm, notForm, notFormSet, notFormUtils, notFormHelpers };
8
+ export {
9
+ UIForm,
10
+ notForm,
11
+ notFormRules,
12
+ notFormSet,
13
+ notFormUtils,
14
+ notFormHelpers,
15
+ };
@@ -4,6 +4,7 @@ import notActionUI from "./action/action.ui.js";
4
4
 
5
5
  import {
6
6
  notForm,
7
+ notFormRules,
7
8
  notFormSet,
8
9
  notFormUtils,
9
10
  notFormHelpers,
@@ -19,6 +20,7 @@ export {
19
20
  notTable,
20
21
  UIForm,
21
22
  notForm,
23
+ notFormRules,
22
24
  notFormSet,
23
25
  notFormUtils,
24
26
  notFormHelpers,