saasufy-components 3.2.0 → 3.3.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 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 `checkbox`.
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 which share the same parent element. 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.
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 which share the same parent element. 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
+ - `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 two pre-defined records into a Product
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');
@@ -191,6 +193,9 @@ class ModelInput extends SocketConsumer {
191
193
  if (placeholder) {
192
194
  this.inputElement.setAttribute('placeholder', placeholder);
193
195
  }
196
+ if (accept) {
197
+ this.inputElement.setAttribute('accept', accept);
198
+ }
194
199
  let errorMessageContainer = null;
195
200
  if (showErrorMessage) {
196
201
  errorMessageContainer = document.createElement('div');
@@ -215,8 +220,11 @@ class ModelInput extends SocketConsumer {
215
220
  updateConsumerElements(consumers, checked, providerTemplate);
216
221
  } else {
217
222
  let defaultValue = this.getAttribute('default-value') || '';
218
- inputElement.value = fieldValue == null ? defaultValue : fieldValue;
219
- updateConsumerElements(consumers, inputElement.value, providerTemplate);
223
+ let elementValue = fieldValue == null ? defaultValue : fieldValue;
224
+ if (inputElement.type !== 'file') {
225
+ inputElement.value = elementValue;
226
+ }
227
+ updateConsumerElements(consumers, elementValue, providerTemplate);
220
228
  }
221
229
  }
222
230
 
@@ -278,12 +286,28 @@ class ModelInput extends SocketConsumer {
278
286
  hideErrorMessage(fieldName);
279
287
  return;
280
288
  }
281
- if (event.target.value === '') {
289
+ let inputValue;
290
+ if (inputElement.type === 'file' && inputElement.files && inputElement.files.length) {
291
+ let reader = new FileReader();
292
+ let readerLoadPromise = new Promise((resolve, reject) => {
293
+ reader.addEventListener('load', () => {
294
+ resolve(reader.result);
295
+ });
296
+ reader.addEventListener('error', () => {
297
+ reject(new Error('Failed to read file'));
298
+ });
299
+ });
300
+ reader.readAsDataURL(inputElement.files[0]);
301
+ inputValue = await readerLoadPromise;
302
+ } else {
303
+ inputValue = event.target.value;
304
+ }
305
+ if (inputValue === '') {
282
306
  updateConsumerElements(consumers, '', providerTemplate);
283
307
  await model.delete(fieldName);
284
308
  } else {
285
309
  let targetValue = inputElement.type === 'number' ?
286
- Number(event.target.value) : event.target.value;
310
+ Number(inputValue) : inputValue;
287
311
  updateConsumerElements(consumers, targetValue, providerTemplate);
288
312
  await model.update(fieldName, targetValue);
289
313
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasufy-components",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Components for Saasufy.",
5
5
  "main": "index.js",
6
6
  "scripts": {