formBuilder icon indicating copy to clipboard operation
formBuilder copied to clipboard

formBuilder is not a function

Open IntuzJatanTrivedi opened this issue 1 year ago • 24 comments

Description:

  • I have used the Form Builder library for react based on your documentation. I have previously built a feature for one of my projects where I wanted custom fields and not the predefined ones. However I was able to achieve it as it was react based on simple JavaScript(.js extension).
  • Now I have to achieve the same functionality in my another project which is based on Vite + TS and I am unable to get the result and the error that is thrown is formBuilder is not a function. The same code which I have used in .js file(my other project) does not work here and behaves weirdly.
  • I have also tried to configure my latest project such that it can support js/jsx configurations but at the end I end up with the same error.

Environment Details:

  • formBuilder Version: ^3.18.0
  • Browser: Google Chrome Version 120.0.6099.216 (Official Build) (64-bit)
  • OS: Ubuntu 20.04.6 LTS

Expected Behavior

  • Form Builder should render with dynamic fields coming from the API/ DB.

Actual Behavior

Uncaught TypeError: $(...).formBuilder is not a function

  • This error pops up and also it crashes the application if I do not use .ready method of jQuery or do not put it in setTimeout.

Steps to Reproduce

  • Setup a project with MUI theme with the latest versions of React JS and Vite.
  • Use the library and try to make the fields dynamic.

Screenshot - (optional)

IntuzJatanTrivedi avatar Jan 24 '24 09:01 IntuzJatanTrivedi

@kevinchappell Please look into this issue as soon as possible. Hope you understand the urgency.

IntuzJatanTrivedi avatar Jan 24 '24 09:01 IntuzJatanTrivedi

@kevinchappell @lucasnetau We are facing this issue and have tried multiple solutions for it as mentioned in the issue itself. After some brainstorming we decided to reach out to you. Hope you can help :)

IntuzDarpitM avatar Jan 24 '24 11:01 IntuzDarpitM

@kevinchappell @lucasnetau
We've encountered an issue and explored various solutions as detailed in the problem statement. After thoughtful consideration, we've chosen to reach out for your assistance, and we're hopeful that you can provide guidance.

IntuzVishalC avatar Jan 24 '24 11:01 IntuzVishalC

@kevinchappell @lucasnetau We've encountered a challenge and attempted various solutions as outlined in the issue. Following some deliberation, we've decided to seek your assistance. We hope you can provide guidance.

IntuzHardP avatar Jan 24 '24 11:01 IntuzHardP

@kevinchappell @lucasnetau We've encountered an issue and explored various solutions as detailed in the problem statement. After thoughtful consideration, we've chosen to reach out for your assistance, and we're hopeful that you can provide guidance.

IntuzRajZ avatar Jan 24 '24 11:01 IntuzRajZ

Please stop spamming the issue tracker with irrelevant duplicated prompts from multiple accounts from your company.

lucasnetau avatar Jan 24 '24 22:01 lucasnetau

Uncaught TypeError: $(...).formBuilder is not a function

The formBuilder plugin is not loaded or was loaded before jQuery was loaded. As with all jQuery plugins you need to load them after jQuery. .ready() is required if you are defining your script in the head because the DOM is not ready.

This is not an issue with formBuilder

lucasnetau avatar Jan 24 '24 22:01 lucasnetau

@lucasnetau Sir, sorry for the spam. This happened due to a small miscommunication from my side. I assure you this won't be repeated again.

Coming to the solution you suggested, I have previously tried it and after you suggested I tried it again but it does not work resulting in the same error. However I forgot to mention that my project is built upon Vite, do you think that Vite is causing the formbuilder to behave in this unexpected manner?

IntuzJatanTrivedi avatar Jan 29 '24 12:01 IntuzJatanTrivedi

@IntuzJatanTrivedi without being able to replicate the problem it's hard to provide any insight into the cause or solution. codesandbox allows you to create online dev sandbox based on React and Vite, if you do that we may be able to see the issue you're encountering.

kevinchappell avatar Jan 29 '24 16:01 kevinchappell

@kevinchappell As per your suggestion I have created a sandbox for my error. I will attach the link as well as the screenshot of the error. You will need to refresh the sandbox's preview panel once it's loaded for seeing the error.

Here is the sandbox link: https://codesandbox.io/p/devbox/mk2zjz Screenshot from 2024-01-31 15-41-52

IntuzJatanTrivedi avatar Jan 31 '24 10:01 IntuzJatanTrivedi

Please take a look at the comments in the React demo https://codesandbox.io/p/sandbox/725zk1mx1?file=%2Fsrc%2Findex.js%3A8%2C1&from-embed=

This is the order you are loading

import jQuery from "jquery";
import React, { useRef, useState, useEffect } from "react"; // For react component

...snip

import "jquery-ui-sortable"; // For FormBuilder Element Drag and Drop
import "formBuilder"; // For FormBuilder

(window as any).jQuery = jQuery; // JQuery alias
(window as any).$ = jQuery; // JQuery alias

from the demo comments the order is important and it calls out that require() should be used not ES6 imports.

/* 
The order of the imports and requires is very important, especially in the online enviornment.
The two jQuery libraries must be imported using Node's require(), and not ES6 import.
Also, these two requires MUST come after setting the global jQuery and $ symbols.

In my Babel/Webpack project, the type and order of the imports is a little less sensitive.
For my project, the following alternative works:

    import $ from 'jquery';
    import React from 'react';
    import ReactDOM from 'react-dom';
    import 'jquery-ui-sortable';

    window.jQuery = $;
    window.$ = $;

    require('formBuilder');
*/

Can you please try your demo with the order corrected and require used to see if it resolves the issue

lucasnetau avatar Feb 01 '24 11:02 lucasnetau

@lucasnetau Thank you for the response. I have tried this approach before, but it does not work and gives an error that says "require is not defined". If I try to include the script for require js in the index file then it gives an error that says "Script error". I have used form builder in one of my other projects and it works fine which I have mentioned before. I think there is an issue with the configuration in my project so after trying many different approaches including converting the existing file system into js and configuring my config files to support js and jsx modules I am facing the same error of formBuilder is not a function.

However I have tried to replicate the error again in the devbox and the result is the same. You can see it here and tell me what's wrong with my approach: https://codesandbox.io/p/devbox/unruffled-dawn-th8jzx Screenshot from 2024-02-01 18-17-35 Screenshot from 2024-02-01 18-35-52

IntuzJatanTrivedi avatar Feb 01 '24 13:02 IntuzJatanTrivedi

Right, we still have a Vite issue here, unless you can replicate without Vite?

Try a plugin like https://www.npmjs.com/package/vite-plugin-require

lucasnetau avatar Feb 01 '24 22:02 lucasnetau

@lucasnetau As I have mentioned, without Vite there is no issue. Form Builder works fine without Vite. However as per your suggestion I have tried using the package you mentioned and still I am facing an error from the formbuilder/vite-plugin-require.

  • For the first time when I added the package and edited the vite config I faced this error. Screenshot from 2024-02-05 15-13-43

  • After this I replaced my require function with vitePluginRequire function, then I got this error. Screenshot from 2024-02-05 15-14-03

  • As mentioned in their library here: https://github.com/wangzongming/vite-plugin-require?tab=readme-ov-file#1vitepluginrequire-is-not-a-function I made the appropriate changes and still faced an error. Screenshot from 2024-02-05 15-14-25

You can see my approaches here: https://codesandbox.io/p/devbox/reverent-bose-np547v?file=%2Fvite.config.ts%3A9%2C1

IntuzJatanTrivedi avatar Feb 05 '24 09:02 IntuzJatanTrivedi

The first issue is you are trying to 'import' formBuilder. There is no default name to import. You cannot use import for formBuilder

The second and third error are from vite unable to load the plugin you have requested.

lucasnetau avatar Feb 07 '24 08:02 lucasnetau

@lucasnetau I have not used import. I am not importing the form builder here. I have not attached the screenshot of the part where I have used require because I wanted you to check that I have correctly configured the package you mentioned in my vite config file. I will attach the screenshot now but you can also check for the same in my devbox I have mentioned.

Actually in the previous post of mine I desired to convey that I have used the library you have mentioned and as I was facing some errors I presented all the approaches around that error that were mentioned in the library's docs. I had attached 3 pictures so that you can check where I am wrong and point that out.

Now I have made sure that I am not importing formbuilder but using require, but I am facing the same error as that in the first screenshot. I have also tried to use vitePluginRequire.default() and vitePluginRequire() in the config file but I think I am facing type error and I have mentioned that also in the post before this.

I request you to please look at my devbox and analyse my code for possible mistakes. If you cannot access the devbox please tell me so that I can send you an invite or share another link. Thank you for your efforts.

https://codesandbox.io/p/devbox/reverent-bose-np547v?file=%2Fvite.config.ts%3A9%2C1 (Devbox link)

reverent-bose-np547v-CodeSandbox

IntuzJatanTrivedi avatar Feb 07 '24 08:02 IntuzJatanTrivedi

I'm afraid I am not a Vite developer and this is a Vite setup issue. Please raise an issue with the Vite project.

There are other discussions on this exact question of loading jQuery plugins in Vite. https://github.com/vitejs/vite/discussions/3744

Take a look at including externally rather than bundling. This uses traditional script tags https://github.com/vitejs/vite/discussions/9415

lucasnetau avatar Feb 07 '24 08:02 lucasnetau

Alright! I will look into the solutions and revert you back.

IntuzJatanTrivedi avatar Feb 07 '24 08:02 IntuzJatanTrivedi

@lucasnetau thank you!

kevinchappell avatar Feb 07 '24 13:02 kevinchappell

https://stackoverflow.com/questions/73140181/how-to-use-jquery-ui-with-vite-in-laravel-9

Take note that jQuery should be loaded in a bootstrap.js file and the global definitions setup there, then in another file you load in the plugins. Vite will reorder the statements otherwise leading to including the plugins prior to jQuery globals being configured

lucasnetau avatar Feb 08 '24 06:02 lucasnetau

@lucasnetau I have applied this solution in the devbox right now and it is working there! I will post a reply again if the same solution works in my local system and everything goes fine.

Thank you very much for your help. I really appreciate your efforts.

IntuzJatanTrivedi avatar Feb 08 '24 08:02 IntuzJatanTrivedi

Great. Could you please provide a write up of all the steps you did to get it working so that anyone else who comes along using Vite can solve the same issue?

lucasnetau avatar Feb 09 '24 01:02 lucasnetau

Sure! I will mention all the steps here as soon as I get this task done in my local system.

IntuzJatanTrivedi avatar Feb 09 '24 04:02 IntuzJatanTrivedi

Hey @lucasnetau @kevinchappell I have applied the solution today in my local machine and it works as expected. Thank you very much for the solution @lucasnetau.

Now as decided before I am mentioning the steps of the solution. The steps to the Solution are very simple as you can see in the link you just gave me.

  • Create a file separately and import the jquery in that file. The name of the file can be anything. image

  • Make sure to import it in the beginning of the file you want to use Form Builder in or at least at a level in hierarchy were the jQuery can be loaded completely.
    image

  • Remove all the declarations of jQuery in the file where you are using FormBuilder. You do not need any jquery imports rather than this one. image

  • Make sure to import the Form Builder and Jquery UI Sortable in the standard way. image

Final Output will be as expected: image

I think by doing these simple steps the Form Builder should render happily.

Thanks once again for the amazing support! :+1:

IntuzJatanTrivedi avatar Feb 19 '24 13:02 IntuzJatanTrivedi

@IntuzJatanTrivedi glad to hear your issue was resolved.

kevinchappell avatar Apr 07 '24 20:04 kevinchappell