saasufy-components 3.2.0 → 3.4.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.
- package/README.md +5 -4
- package/model-input.js +33 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -404,9 +404,9 @@ Used for displaying and editing a single field of a model instance in real time.
|
|
|
404
404
|
- `debounce-delay`: The delay in milliseconds to wait before sending an update to the server. This is useful to batch multiple updates together (as is common when user is typing). Default is 300ms.
|
|
405
405
|
- `input-id`: Can be used to set an `id` attribute on the inner `input` element.
|
|
406
406
|
- `list`: If specified, this sets the list attribute of the inner `input` element to provide input suggestions (only works with standard input elements).
|
|
407
|
-
- `type`: The type of the input component; can be `text`, `number`, `select`, `textarea` or `
|
|
407
|
+
- `type`: The type of the input component; can be `text`, `number`, `select`, `textarea`, `checkbox` or `file`.
|
|
408
408
|
- `placeholder`: Can be used to set the placeholder text on the inner input element.
|
|
409
|
-
- `consumers`: This allows you to connect this `model-input` to other elements on your page
|
|
409
|
+
- `consumers`: This allows you to connect this `model-input` to other elements on your page. It takes a list of selectors with optional attributes to target. For example `.my-input:value` will find all elements with a `my-input` class and update their `value` attributes with the value of the `model-input` component in real-time. You can specify multiple selectors separated by commas such as `.my-input,my-div` - In this case, because attribute names are not specified, values will be injected into the `value` attribute (for input elements) or into the `innerHTML` property (for other kinds of elements). The default attribute/property depends on the element type.
|
|
410
410
|
- `provider-template`: A template string within which the `{{value}}` can be injected before passing to consumers.
|
|
411
411
|
- `show-error-message`: If this attribute is present, an error message will be displayed above the input if it fails to update the value.
|
|
412
412
|
- `options`: A comma-separated list of options to provide - This only works if the input type is `select`.
|
|
@@ -417,6 +417,7 @@ Used for displaying and editing a single field of a model instance in real time.
|
|
|
417
417
|
- `autocapitalize`: Can be `on` or `off` - It will set the auto-capitalize attribute on the inner input element. This is useful for mobile devices to enable or disable auto-capitalization of the first character which is typed into the input element.
|
|
418
418
|
- `autocorrect`: Can be `on` or `off` - It will set the auto-correct attribute on the inner input element. This is useful for mobile devices to enable or disable auto-correct.
|
|
419
419
|
- `enable-rebound`: By default, for efficiency reasons, real-time updates performed via `model-input` components are not sent back to the publishing client; it is usually unnecessary because state changes are shared locally between all components which are bound to the same `socket-provider`. You can add the `enable-rebound` attribute to the `model-input` component to force real-time updates to rebound back to the publisher to support more advanced scenarios. Note that enabling rebound comes with additional performance overheads.
|
|
420
|
+
- `accept`: This attribute should only be used if the `type` is set to `file`; it serves to constrain the types of files which can be selected by the user.
|
|
420
421
|
|
|
421
422
|
### model-text
|
|
422
423
|
|
|
@@ -513,7 +514,7 @@ This component can be configured to provide its data to multiple components (con
|
|
|
513
514
|
- `list`: If specified, this sets the list attribute of the inner `input` element to provide input suggestions (only works with standard input elements).
|
|
514
515
|
- `type`: The type of the input component; can be `text`, `number`, `select`, `textarea` or `checkbox`.
|
|
515
516
|
- `placeholder`: Can be used to set the placeholder text on the inner input element.
|
|
516
|
-
- `consumers`: This allows you to connect this `input-provider` to other elements on your page
|
|
517
|
+
- `consumers`: This allows you to connect this `input-provider` to other elements on your page. It takes a list of selectors with optional attributes to target. For example `.my-input:value` will find all elements with a `my-input` class and update their `value` attributes with the value of the `input-provider` component in real-time. You can specify multiple selectors separated by commas such as `.my-input,my-div` - In this case, because attribute names are not specified, values will be injected into the `value` attribute (for input elements) or into the `innerHTML` property (for other kinds of elements). The default attribute/property depends on the element type.
|
|
517
518
|
- `provider-template`: A template string within which the `{{value}}` can be injected before passing to consumers.
|
|
518
519
|
- `debounce-delay`: The delay in milliseconds to wait before triggering a change event. This is useful to batch multiple updates together (as is common when user is typing). Default is 800ms.
|
|
519
520
|
- `options`: A comma-separated list of options to provide - This only works if the input type is `select`.
|
|
@@ -738,7 +739,7 @@ A component which can be used to group together multiple `collection-adder` comp
|
|
|
738
739
|
|
|
739
740
|
```html
|
|
740
741
|
<!--
|
|
741
|
-
This collection-adder-group adds
|
|
742
|
+
This collection-adder-group adds multiple pre-defined records into a Product
|
|
742
743
|
collection using a single button click. This example assumes that the name
|
|
743
744
|
field is the only required field in the Product model.
|
|
744
745
|
-->
|
package/model-input.js
CHANGED
|
@@ -26,6 +26,7 @@ class ModelInput extends SocketConsumer {
|
|
|
26
26
|
'socket-instance-property',
|
|
27
27
|
'type',
|
|
28
28
|
'placeholder',
|
|
29
|
+
'accept',
|
|
29
30
|
'consumers',
|
|
30
31
|
'show-error-message',
|
|
31
32
|
'model-type',
|
|
@@ -95,6 +96,7 @@ class ModelInput extends SocketConsumer {
|
|
|
95
96
|
let inputList = this.getAttribute('list');
|
|
96
97
|
let type = this.getAttribute('type') || 'text';
|
|
97
98
|
let placeholder = this.getAttribute('placeholder');
|
|
99
|
+
let accept = this.getAttribute('accept');
|
|
98
100
|
let modelType = this.getAttribute('model-type');
|
|
99
101
|
let modelId = this.getAttribute('model-id');
|
|
100
102
|
let modelField = this.getAttribute('model-field');
|
|
@@ -102,6 +104,7 @@ class ModelInput extends SocketConsumer {
|
|
|
102
104
|
let height = this.getAttribute('height');
|
|
103
105
|
let hideErrorLogs = this.hasAttribute('hide-error-logs');
|
|
104
106
|
let enableRebound = this.hasAttribute('enable-rebound');
|
|
107
|
+
let hasConsumers = this.hasAttribute('consumers');
|
|
105
108
|
|
|
106
109
|
let socket;
|
|
107
110
|
if (socketInstanceProperty) {
|
|
@@ -124,11 +127,14 @@ class ModelInput extends SocketConsumer {
|
|
|
124
127
|
socket = this.getSocket();
|
|
125
128
|
}
|
|
126
129
|
this.socket = socket;
|
|
130
|
+
|
|
131
|
+
let modelFieldList = hasConsumers ? [ modelField ] : [];
|
|
132
|
+
|
|
127
133
|
let model = new AGModel({
|
|
128
134
|
socket: this.socket,
|
|
129
135
|
type: modelType,
|
|
130
136
|
id: modelId,
|
|
131
|
-
fields:
|
|
137
|
+
fields: modelFieldList,
|
|
132
138
|
enableRebound
|
|
133
139
|
});
|
|
134
140
|
if (!hideErrorLogs) {
|
|
@@ -191,6 +197,9 @@ class ModelInput extends SocketConsumer {
|
|
|
191
197
|
if (placeholder) {
|
|
192
198
|
this.inputElement.setAttribute('placeholder', placeholder);
|
|
193
199
|
}
|
|
200
|
+
if (accept) {
|
|
201
|
+
this.inputElement.setAttribute('accept', accept);
|
|
202
|
+
}
|
|
194
203
|
let errorMessageContainer = null;
|
|
195
204
|
if (showErrorMessage) {
|
|
196
205
|
errorMessageContainer = document.createElement('div');
|
|
@@ -215,8 +224,11 @@ class ModelInput extends SocketConsumer {
|
|
|
215
224
|
updateConsumerElements(consumers, checked, providerTemplate);
|
|
216
225
|
} else {
|
|
217
226
|
let defaultValue = this.getAttribute('default-value') || '';
|
|
218
|
-
|
|
219
|
-
|
|
227
|
+
let elementValue = fieldValue == null ? defaultValue : fieldValue;
|
|
228
|
+
if (inputElement.type !== 'file') {
|
|
229
|
+
inputElement.value = elementValue;
|
|
230
|
+
}
|
|
231
|
+
updateConsumerElements(consumers, elementValue, providerTemplate);
|
|
220
232
|
}
|
|
221
233
|
}
|
|
222
234
|
|
|
@@ -278,12 +290,28 @@ class ModelInput extends SocketConsumer {
|
|
|
278
290
|
hideErrorMessage(fieldName);
|
|
279
291
|
return;
|
|
280
292
|
}
|
|
281
|
-
|
|
293
|
+
let inputValue;
|
|
294
|
+
if (inputElement.type === 'file' && inputElement.files && inputElement.files.length) {
|
|
295
|
+
let reader = new FileReader();
|
|
296
|
+
let readerLoadPromise = new Promise((resolve, reject) => {
|
|
297
|
+
reader.addEventListener('load', () => {
|
|
298
|
+
resolve(reader.result);
|
|
299
|
+
});
|
|
300
|
+
reader.addEventListener('error', () => {
|
|
301
|
+
reject(new Error('Failed to read file'));
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
reader.readAsDataURL(inputElement.files[0]);
|
|
305
|
+
inputValue = await readerLoadPromise;
|
|
306
|
+
} else {
|
|
307
|
+
inputValue = event.target.value;
|
|
308
|
+
}
|
|
309
|
+
if (inputValue === '') {
|
|
282
310
|
updateConsumerElements(consumers, '', providerTemplate);
|
|
283
311
|
await model.delete(fieldName);
|
|
284
312
|
} else {
|
|
285
313
|
let targetValue = inputElement.type === 'number' ?
|
|
286
|
-
Number(
|
|
314
|
+
Number(inputValue) : inputValue;
|
|
287
315
|
updateConsumerElements(consumers, targetValue, providerTemplate);
|
|
288
316
|
await model.update(fieldName, targetValue);
|
|
289
317
|
}
|