kevinchappell / formBuilder

A jQuery plugin for drag and drop form creation
https://formbuilder.online
MIT License
2.63k stars 1.39k forks source link

Strings set in a custom control that use custom lang file show as undefined when first rendered but work on second render #1577

Open breagol37 opened 3 months ago

breagol37 commented 3 months ago

Description:

If you create a custom control that references strings via mi18n that are set in a custom .lang file.

All works fine in the builder and strings are set correctly, however if you then render the form the strings that are set show as undefined. If you then render a second time strings will set correctly.

Below test custom control in builder image

Then when rendered

image

When rendered a second time show as normal.

image

It will also work as expected if you render the form first before adding the custom control then adding the control and rendering.

Example of the ref in code to one of the strings.

image

And the i18n options passed to render in the main index (for this test) image

In debugging it seemed that the html is displayed before the applyLanguage function has finished.

Environment Details:

Expected Behavior

Strings should be applied from the custom lang file on first render.

Actual Behavior

Strings do not get applied from the custom .land file until second render.

Steps to Reproduce

Create a custom .lang file and add the details to the i18n location. Create a custom control and add refs to any custom strings in your custom lang file using controlClass.mi18n("yourCustomStringKey"). Start Form builder and add your control to your form (All strings added as expected) Render the form (Custom strings used show as undefined) Render again (Strings now show as expected)

You can also. In form builder have either blank or any other controls (NOT your custom) added. Render Go back to builder and add your custom control Strings in your control show as expected as its a second render.

lucasnetau commented 3 months ago

Can you please provide a custom control script and lang file to reproduce the issue.

breagol37 commented 3 months ago

testControl.txt en-US.txt

Thanks added above but as text files as could not upload as js or lang.

lucasnetau commented 3 months ago

Hi @breagol37, thank you. I will take a look.

breagol37 commented 3 months ago

Thank you @lucasnetau

lucasnetau commented 3 months ago

HI @breagol37

The issue occurs because the formRender render() function does not wait for the translation library to be ready.

This patch fixes your issue but render() is not meant to be async and breaks the Jest tests and possibly a BC break.

@kevinchappell Thoughts on this one? formBuilder aways the mi18n library to initialise, formRender does not.

diff --git a/src/js/form-render.js b/src/js/form-render.js
index 8331960..4a79197 100644
--- a/src/js/form-render.js
+++ b/src/js/form-render.js
@@ -67,8 +67,9 @@ class FormRender {
     //Override any sanitizer configuration
     setSanitizerConfig(this.options.sanitizerOptions)

+    this.mi18nLoading = null
     if (!mi18n.current) {
-      mi18n.init(this.options.i18n)
+      this.mi18nLoading = mi18n.init(this.options.i18n)
     }

     // parse any passed formData
@@ -186,7 +187,7 @@ class FormRender {
    * @param {number} instanceIndex - instance index
    * @return {Object} rendered form
    */
-  render(element = null, instanceIndex = 0) {
+  async render(element = null, instanceIndex = 0) {
     const formRender = this
     const opts = this.options
     element = this.getElement(element)
@@ -197,6 +198,11 @@ class FormRender {
       }
     }

+    if (this.mi18nLoading) {
+      await this.mi18nLoading
+      this.mi18nLoading = null
+    }
+
     // Begin the core plugin
     const rendered = []
kevinchappell commented 3 months ago

@lucasnetau this is a good patch. My only doubt is if we should await all of formRender or just the render method.

Await only render method may have least impact though so let's go with your solution.

breagol37 commented 3 months ago

Thanks for looking into this so quickly @lucasnetau greatly appreciated.

breagol37 commented 3 months ago

@lucasnetau Will that fix be put into a release?

lucasnetau commented 3 months ago

Hi @breagol37, once I find some time to test this it will land in a release.

@kevinchappell I think the change to render() keeps any possible BC change to a minimum. I'll also look at moving the mi18n.init higher up in the formRender constructor to get the request going ASAP.