diff --git a/src/Form.js b/src/Form.js index 9a4c695e94..0597454956 100644 --- a/src/Form.js +++ b/src/Form.js @@ -161,11 +161,43 @@ export default class Form extends Element { }; } + /** + * Check Subdirectories path and provide correct options + * + * @param {string} url - The the URL of the form json. + * @return {*} + */ + getFormInitOptions(url) { + const options = {}; + const urlParts = Formio.getUrlParts(url); + if (!urlParts) { + return options; + } + const baseUrl = `${urlParts[1]}${urlParts[2]}`; + // Subdirectories path must be '/projectId/formId' + const path = urlParts[3]?.split('?')[0]?.split('/'); + if (path?.length !== 3) { + return options; + } + path.shift(); + const [projectId, formId] = path; + // Detect Subdirectories path type when baseUrl wasn't set for this url + if (baseUrl !== Formio.baseUrl && projectId && formId) { + return { + base: baseUrl, + project: `${baseUrl}/${projectId}`, + }; + } + + return {}; + } + setForm(formParam) { let result; formParam = formParam || this.form; if (typeof formParam === 'string') { - const formio = new Formio(formParam); + const options = this.getFormInitOptions(formParam); + const formio = new Formio(formParam, options); let error; this.loading = true; result = this.getSubmission(formio, this.options) @@ -185,7 +217,7 @@ export default class Form extends Element { } this.loading = false; this.instance = this.instance || this.create(form.display); - this.instance.url = formParam; + this.instance.setUrl(formParam, options); this.instance.nosubmit = false; this._form = this.instance.form = form; if (submission) { diff --git a/src/Formio.unit.js b/src/Formio.unit.js index 452d059828..abc5e79372 100644 --- a/src/Formio.unit.js +++ b/src/Formio.unit.js @@ -2224,6 +2224,46 @@ describe('Formio.js Tests', () => { ]; } }, + { + name: 'Should return correct options for form url with Subdirectories path', + test() { + let form = new Formio.Form(); + let options = form.getFormInitOptions('http://localhost:3000/fakeproject/fakeform'); + assert.deepEqual(options, { + base: 'http://localhost:3000', + project: 'http://localhost:3000/fakeproject', + }); + + form = new Formio.Form(); + options = form.getFormInitOptions(`${Formio.baseUrl}/fakeproject/fakeform`); + assert.deepEqual(options, {}); + } + }, + { + name: 'Should set correct formio base and project url for form with Subdirectories path', + test() { + const formElement = document.createElement('div'); + return Formio.createForm(formElement, 'http://localhost:3000/fakeproject/fakeform') + .then((form) => { + assert.equal(form.formio.base, 'http://localhost:3000'); + assert.equal(form.formio.projectUrl, 'http://localhost:3000/fakeproject'); + }); + }, + mock() { + return { + url: 'http://localhost:3000/fakeproject/fakeform', + method: 'GET', + response() { + return { + headers: { + 'Content-Type': 'application/json', + }, + body: {} + }; + } + }; + }, + }, ]; tests.forEach(testCapability); diff --git a/src/components/form/Form.js b/src/components/form/Form.js index 957c802be3..6b489b99c0 100644 --- a/src/components/form/Form.js +++ b/src/components/form/Form.js @@ -487,7 +487,13 @@ export default class FormComponent extends Component { } else if (this.formSrc) { this.subFormLoading = true; - return (new Formio(this.formSrc)).loadForm({ params: { live: 1 } }) + const options = this.root.formio?.base && this.root.formio?.projectUrl + ? { + base: this.root.formio.base, + project: this.root.formio.projectUrl, + } + : {}; + return (new Formio(this.formSrc, options)).loadForm({ params: { live: 1 } }) .then((formObj) => { this.formObj = formObj; if (this.options.pdf && this.component.useOriginalRevision) {