Skip to content

Commit ee02208

Browse files
committed
Merge branch 'master' of https://github.com/formio/formio.js into added-upload-only
2 parents 87ac9eb + 2e2bfee commit ee02208

File tree

20 files changed

+220
-79
lines changed

20 files changed

+220
-79
lines changed

Changelog.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
4545
- "row" always points to the "data" context object for that instance (typically row in DataGrid)
4646
- "data" always refers to the global data of the submission.
4747

48+
## [UNRELEASED]
49+
### Added
50+
- Possibility to override i18n settings.
51+
- `focus` and `blur` events.
52+
53+
### Fixed
54+
- Nested forms validation.
55+
4856
## 3.0.0-rc.14
4957
### Fixed
5058
- Bad build from previous release.
@@ -62,13 +70,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6270
- Problem with the PDF Builder where you would not see the builder elemements.
6371
- Fix default value on checkboxes.
6472
- Fix multiple required file fields not requiring uploading a file.
65-
73+
6674
### Added
6775
- Make rowIndex available on editgrids and datagrids.
6876
- Add custom class name to table component.
6977
- Add the ability for events to trigger field logic.
7078
- Add option to trigger validations when button is pressed.
71-
79+
7280
### Changed
7381
- Upgrade i18next@11.3.3
7482

src/Formio.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'whatwg-fetch';
88
import { EventEmitter2 as EventEmitter } from 'eventemitter2';
99
import cookies from 'browser-cookies';
1010
import copy from 'shallow-copy';
11-
import providers from './providers';
11+
import * as providers from './providers';
1212
import _get from 'lodash/get';
1313

1414
const isBoolean = (val) => typeof val === typeof true;
@@ -462,9 +462,9 @@ export default class Formio {
462462
const requestArgs = {
463463
provider: storage,
464464
method: 'upload',
465-
file: file,
466-
fileName: fileName,
467-
dir: dir
465+
file,
466+
fileName,
467+
dir
468468
};
469469
const request = Formio.pluginWait('preRequest', requestArgs)
470470
.then(() => {

src/Webform.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Formio.registerComponent = Components.setComponent;
2020
function getOptions(options) {
2121
options = _.defaults(options, {
2222
submitOnEnter: false,
23-
i18next: i18next
23+
i18next,
2424
});
2525
if (!options.events) {
2626
options.events = new EventEmitter({
@@ -68,7 +68,10 @@ export default class Webform extends NestedComponent {
6868
}
6969
else {
7070
_.each(options.i18n, (lang, code) => {
71-
if (!i18n.resources[code]) {
71+
if (code === 'options') {
72+
_.merge(i18n, lang);
73+
}
74+
else if (!i18n.resources[code]) {
7275
i18n.resources[code] = { translation: lang };
7376
}
7477
else {
@@ -779,6 +782,9 @@ export default class Webform extends NestedComponent {
779782
* @param {string} message - The message to show in the alert.
780783
*/
781784
setAlert(type, message) {
785+
if (!type && this.submitted) {
786+
return;
787+
}
782788
if (this.options.noAlerts) {
783789
if (!message) {
784790
this.emit('error', false);

src/components/Components.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import UnknownComponent from './unknown/Unknown';
22
import _ from 'lodash';
3+
34
export default class Components {
45
static get components() {
56
if (!Components._components) {

src/components/base/Base.js

+26
Original file line numberDiff line numberDiff line change
@@ -1886,11 +1886,37 @@ export default class BaseComponent {
18861886
}
18871887
this.inputs.push(input);
18881888
this.hook('input', input, container);
1889+
this.addFocusBlurEvents(input);
18891890
this.addInputEventListener(input);
18901891
this.addInputSubmitListener(input);
18911892
return input;
18921893
}
18931894

1895+
addFocusBlurEvents(element) {
1896+
this.addEventListener(element, 'focus', () => {
1897+
if (this.root.focusedComponent !== this) {
1898+
if (this.root.pendingBlur) {
1899+
this.root.pendingBlur();
1900+
}
1901+
1902+
this.root.focusedComponent = this;
1903+
1904+
this.emit('focus', this);
1905+
}
1906+
else if (this.root.focusedComponent === this && this.root.pendingBlur) {
1907+
this.root.pendingBlur.cancel();
1908+
this.root.pendingBlur = null;
1909+
}
1910+
});
1911+
this.addEventListener(element, 'blur', () => {
1912+
this.root.pendingBlur = FormioUtils.delay(() => {
1913+
this.emit('blur', this);
1914+
this.root.focusedComponent = null;
1915+
this.root.pendingBlur = null;
1916+
});
1917+
});
1918+
}
1919+
18941920
get wysiwygDefault() {
18951921
return {
18961922
theme: 'snow',

src/components/builder.js

+43-42
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,75 @@
11
import Components from '.';
2+
23
import AddressForm from './address/Address.form';
3-
import ContentForm from './content/Content.form';
4+
import ButtonForm from './button/Button.form';
5+
import CheckboxForm from './checkbox/Checkbox.form';
6+
import ColumnsForm from './columns/Columns.form';
47
import ContainerForm from './container/Container.form';
8+
import ContentForm from './content/Content.form';
9+
import CurrencyForm from './currency/Currency.form';
510
import DataGridForm from './datagrid/DataGrid.form';
611
import DateTimeForm from './datetime/DateTime.form';
712
import DayForm from './day/Day.form';
8-
import HtmlElementForm from './html/HTML.form';
9-
import HiddenForm from './hidden/Hidden.form';
1013
import EditGridForm from './editgrid/EditGrid.form';
11-
import FormForm from './form/Form.form';
12-
import TextfieldForm from './textfield/TextField.form';
13-
import PhoneNumberForm from './phonenumber/PhoneNumber.form';
14-
import LocationForm from './location/Location.form';
1514
import EmailForm from './email/Email.form';
16-
import TimeForm from './time/Time.form';
17-
import CheckboxForm from './checkbox/Checkbox.form';
18-
import CurrencyForm from './currency/Currency.form';
1915
import FieldsetForm from './fieldset/Fieldset.form';
20-
import SignatureForm from './signature/Signature.form';
21-
import SelectForm from './select/Select.form';
22-
import ResourceForm from './resource/Resource.form';
23-
import TextAreaForm from './textarea/TextArea.form';
24-
import TagsForm from './tags/Tags.form';
25-
import ButtonForm from './button/Button.form';
16+
import FileForm from './file/File.form';
17+
import FormForm from './form/Form.form';
18+
import HiddenForm from './hidden/Hidden.form';
19+
import HtmlElementForm from './html/HTML.form';
20+
import LocationForm from './location/Location.form';
2621
import NumberForm from './number/Number.form';
27-
import PasswordForm from './password/Password.form';
2822
import PanelForm from './panel/Panel.form';
29-
import TabsForm from './tabs/Tabs.form';
30-
import ColumnsForm from './columns/Columns.form';
31-
import TableForm from './table/Table.form';
23+
import PasswordForm from './password/Password.form';
24+
import PhoneNumberForm from './phonenumber/PhoneNumber.form';
3225
import RadioForm from './radio/Radio.form';
26+
import ResourceForm from './resource/Resource.form';
27+
import SelectForm from './select/Select.form';
3328
import SelectboxesForm from './selectboxes/SelectBoxes.form';
29+
import SignatureForm from './signature/Signature.form';
3430
import SurveyForm from './survey/Survey.form';
31+
import TableForm from './table/Table.form';
32+
import TabsForm from './tabs/Tabs.form';
33+
import TagsForm from './tags/Tags.form';
34+
import TextAreaForm from './textarea/TextArea.form';
35+
import TextFieldForm from './textfield/TextField.form';
36+
import TimeForm from './time/Time.form';
3537
import WellForm from './well/Well.form';
36-
import FileForm from './file/File.form';
3738

3839
Components.address.editForm = AddressForm;
39-
Components.content.editForm = ContentForm;
40+
Components.button.editForm = ButtonForm;
41+
Components.checkbox.editForm = CheckboxForm;
42+
Components.columns.editForm = ColumnsForm;
4043
Components.container.editForm = ContainerForm;
44+
Components.content.editForm = ContentForm;
45+
Components.currency.editForm = CurrencyForm;
4146
Components.datagrid.editForm = DataGridForm;
4247
Components.datetime.editForm = DateTimeForm;
4348
Components.day.editForm = DayForm;
44-
Components.htmlelement.editForm = HtmlElementForm;
45-
Components.hidden.editForm = HiddenForm;
4649
Components.editgrid.editForm = EditGridForm;
47-
Components.form.editForm = FormForm;
48-
Components.textfield.editForm = TextfieldForm;
49-
Components.phoneNumber.editForm = PhoneNumberForm;
50-
Components.location.editForm = LocationForm;
5150
Components.email.editForm = EmailForm;
52-
Components.time.editForm = TimeForm;
53-
Components.checkbox.editForm = CheckboxForm;
54-
Components.currency.editForm = CurrencyForm;
5551
Components.fieldset.editForm = FieldsetForm;
56-
Components.signature.editForm = SignatureForm;
57-
Components.select.editForm = SelectForm;
58-
Components.resource.editForm = ResourceForm;
59-
Components.textarea.editForm = TextAreaForm;
60-
Components.tags.editForm = TagsForm;
61-
Components.button.editForm = ButtonForm;
52+
Components.file.editForm = FileForm;
53+
Components.form.editForm = FormForm;
54+
Components.hidden.editForm = HiddenForm;
55+
Components.htmlelement.editForm = HtmlElementForm;
56+
Components.location.editForm = LocationForm;
6257
Components.number.editForm = NumberForm;
63-
Components.password.editForm = PasswordForm;
6458
Components.panel.editForm = PanelForm;
65-
Components.tabs.editForm = TabsForm;
66-
Components.columns.editForm = ColumnsForm;
67-
Components.table.editForm = TableForm;
59+
Components.password.editForm = PasswordForm;
60+
Components.phoneNumber.editForm = PhoneNumberForm;
6861
Components.radio.editForm = RadioForm;
62+
Components.resource.editForm = ResourceForm;
63+
Components.select.editForm = SelectForm;
6964
Components.selectboxes.editForm = SelectboxesForm;
65+
Components.signature.editForm = SignatureForm;
7066
Components.survey.editForm = SurveyForm;
67+
Components.table.editForm = TableForm;
68+
Components.tabs.editForm = TabsForm;
69+
Components.tags.editForm = TagsForm;
70+
Components.textarea.editForm = TextAreaForm;
71+
Components.textfield.editForm = TextFieldForm;
72+
Components.time.editForm = TimeForm;
7173
Components.well.editForm = WellForm;
72-
Components.file.editForm = FileForm;
7374

7475
export default Components;

src/components/button/Button.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ export default class ButtonComponent extends BaseComponent {
113113
this.createElement();
114114
this.createInput(this.element);
115115
this.addShortcut(this.buttonElement);
116-
this.hook('input', this.buttonElement, this.element);
117116
if (this.component.leftIcon) {
118117
this.buttonElement.appendChild(this.ce('span', {
119118
class: this.component.leftIcon
@@ -379,7 +378,7 @@ export default class ButtonComponent extends BaseComponent {
379378
}
380379

381380
focus() {
382-
this.button.focus();
381+
this.buttonElement.focus();
383382
}
384383
}
385384

src/components/datetime/DateTime.js

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ export default class DateTimeComponent extends BaseComponent {
192192
getCalendar(input) {
193193
if (!input.calendar && !this.options.noCalendar) {
194194
input.calendar = new Flatpickr(input, this.config);
195+
this.addFocusBlurEvents(input.calendar.altInput);
195196
}
196197
return input.calendar;
197198
}

src/components/day/Day.js

+3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export default class DayComponent extends BaseComponent {
165165
id
166166
});
167167
this.hook('input', this.dayInput, dayInputWrapper);
168+
this.addFocusBlurEvents(this.dayInput);
168169
this.addEventListener(this.dayInput, 'change', () => this.updateValue());
169170
dayInputWrapper.appendChild(this.dayInput);
170171
this.setSubinputStyle(dayInputWrapper);
@@ -206,6 +207,7 @@ export default class DayComponent extends BaseComponent {
206207
id
207208
});
208209
this.hook('input', this.monthInput, monthInputWrapper);
210+
this.addFocusBlurEvents(this.monthInput);
209211
this.selectOptions(this.monthInput, 'monthOption', this.months);
210212
const self = this;
211213

@@ -262,6 +264,7 @@ export default class DayComponent extends BaseComponent {
262264
});
263265

264266
this.hook('input', this.yearInput, yearInputWrapper);
267+
this.addFocusBlurEvents(this.yearInput);
265268
this.addEventListener(this.yearInput, 'change', () => this.updateValue());
266269
yearInputWrapper.appendChild(this.yearInput);
267270
this.setSubinputStyle(yearInputWrapper);

src/components/file/File.js

+1
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ export default class FileComponent extends BaseComponent {
302302
},
303303
class: 'browse'
304304
}, this.text('browse'));
305+
this.addFocusBlurEvents(this.browseLink);
305306

306307
return this.browseLink;
307308
}

src/components/form/Form.js

+20-15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import _ from 'lodash';
12
import BaseComponent from '../base/Base';
23
import Promise from 'native-promise-only';
34
import { isMongoId, eachComponent } from '../../utils/utils';
@@ -217,14 +218,16 @@ export default class FormComponent extends BaseComponent {
217218
// This submission has not been submitted yet.
218219
if (this.component.submit) {
219220
return this.loadSubForm().then(() => {
220-
return this.subForm.submitForm().then(result => {
221-
this.subForm.loading = false;
222-
this.dataValue = this.component.reference ? {
223-
_id: result.submission._id,
224-
form: result.submission.form
225-
} : result.submission;
226-
return this.dataValue;
227-
});
221+
return this.subForm.submitForm()
222+
.then(result => {
223+
this.subForm.loading = false;
224+
this.dataValue = this.component.reference ? {
225+
_id: result.submission._id,
226+
form: result.submission.form
227+
} : result.submission;
228+
return this.dataValue;
229+
})
230+
.catch(() => {});
228231
});
229232
}
230233
else {
@@ -243,12 +246,10 @@ export default class FormComponent extends BaseComponent {
243246

244247
setValue(submission, flags) {
245248
const changed = super.setValue(submission, flags);
246-
if (this.subForm) {
247-
this.subForm.setValue(submission, flags);
248-
}
249-
else {
250-
this.loadSubForm().then((form) => {
251-
if (submission && submission._id && form.formio && !flags.noload) {
249+
250+
(this.subForm ? Promise.resolve(this.subForm) : this.loadSubForm())
251+
.then((form) => {
252+
if (submission && submission._id && form.formio && !flags.noload && _.isEmpty(submission.data)) {
252253
const submissionUrl = `${form.formio.formsUrl}/${submission.form}/submission/${submission._id}`;
253254
form.setUrl(submissionUrl, this.options);
254255
form.nosubmit = false;
@@ -258,7 +259,7 @@ export default class FormComponent extends BaseComponent {
258259
form.setValue(submission, flags);
259260
}
260261
});
261-
}
262+
262263
return changed;
263264
}
264265

@@ -268,4 +269,8 @@ export default class FormComponent extends BaseComponent {
268269
}
269270
return this.dataValue;
270271
}
272+
273+
getAllComponents() {
274+
return this.subForm.getAllComponents();
275+
}
271276
}

src/components/nested/NestedComponent.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ export default class NestedComponent extends BaseComponent {
4242
return this.components;
4343
}
4444

45+
getAllComponents() {
46+
return this.getComponents().reduce((components, component) => {
47+
let result = component;
48+
49+
if (component.getAllComponents) {
50+
result = component.getAllComponents();
51+
}
52+
53+
return components.concat(result);
54+
}, []);
55+
}
56+
4557
/**
4658
* Perform a deep iteration over every component, including those
4759
* within other container based components.
@@ -417,7 +429,7 @@ export default class NestedComponent extends BaseComponent {
417429

418430
get errors() {
419431
let errors = [];
420-
_.each(this.getComponents(), (comp) => {
432+
_.each(this.getAllComponents(), (comp) => {
421433
const compErrors = comp.errors;
422434
if (compErrors.length) {
423435
errors = errors.concat(compErrors);

0 commit comments

Comments
 (0)