kevinchappell / formBuilder

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

Vue 2: Uncaught TypeError: $(...).formBuilder is not a function #1561

Closed giannicolac closed 5 months ago

giannicolac commented 6 months ago

Description:

Hello, i'm using Vue 2 (specifically 2.6.14), and i've been trying to make the formBuilder work for a little while to no avail. Right now i'm getting the "Uncaught TypeError: $(...).formBuilder is not a function" error. I'm not sure what i'm doing wrong. in the "Steps to reproduce" part, you can see the code i'm using. Feel free to ask any detail i may be missing, have a good day.

I installed formBuilder through npm, just as the docs say.

Environment Details:

Expected Behavior

I'd expect to see the form builder.

Actual Behavior

the console gives me "Uncaught TypeError: $(...).formBuilder is not a function", and the form builder is nowhere to be seen.

Steps to Reproduce

<template>
  <v-container fluid>
    <div id="fb-editor"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
  <script src="https://formbuilder.online/assets/js/form-builder.min.js"></script>  
  </v-container> 
</template>  
<script>
  import jQuery from 'jquery'
  export default {
    mounted() {
      jQuery(function($) {
    $(document.getElementById('fb-editor')).formBuilder();
  });
    }
  }
</script>

Screenshot - (optional)

image

lucasnetau commented 6 months ago

I don't use Vue, however looking at your code I would suspect you are reloading jQuery again with the import jQuery (after including it first globally with the script src tag. You need to import jquery-ui sortable and require formBuilder after importing jQuery

Please see previous issue #789

@kevinchappell provided a sandbox demo https://codesandbox.io/p/sandbox/n91zzl4vpp

Specifically https://codesandbox.io/p/sandbox/n91zzl4vpp?file=%2Fsrc%2Fcomponents%2FformBuilder.vue%3A24%2C10

window.$ = window.jQuery = require('jquery');
require('jquery-ui-sortable'); //or import 'jquery-ui/ui/widgets/sortable';
require('formBuilder');

More info on StackOverflow

https://stackoverflow.com/questions/51648926/vue2-jquery-jquery-ui

If you get it working please consider submitting a PR for a documentation page

giannicolac commented 5 months ago

Alright so i have been testing this, using the provided code in the sandbox, requiring jquery-ui-sortable, formBuilder, and form-render (not sure if this is needed). It does not give me the type error anymore, but i receive a different one now, it says: ERROR in ./node_modules/formBuilder/dist/form-builder.min.js 2:144575 Module parse failed: Unexpected token (2:144575) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders... for formBuilder, and something similar for the form-render.

Not sure if i have missed something with the loaders.

the code right now is:

<template>
  <v-container fluid>
    <div id="fb-editor"></div>
  </v-container> 
</template>

<script>
  import jQuery from 'jquery'
  window.$ = window.jQuery = require('jquery');
  require('jquery-ui-sortable')
  require('formBuilder')
  require('formBuilder/dist/form-render.min.js')
  export default {
    mounted() {
      jQuery(function($) {
    $(document.getElementById('fb-editor')).formBuilder();
  });
    }
  }
</script>

I have babel-loader 8.2.5 and babel-core 6.26.3 installed.

giannicolac commented 5 months ago

UPDATE: I fixed the "you may need an appropiate loader" error by configuring the nuxt.config.js properly, inside build for form-builder.min.js (not for form-render):


      config.module.rules.push({
        test: /form-builder\.min\.js$|form-builder\.js$/,        
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['babel-preset-env']
            }
          }
        ]
      })

However, i now have another error, one that says:

ERROR in ./node_modules/formBuilder/dist/form-builder.min.js Module build failed (from ./node_modules/babel-loader/lib/index.js): TypeError: /opt/lampp/htdocs/thani/dirisalud-front/node_modules/formBuilder/dist/form-builder.min.js: path.inShadow is not a function

So now i'm stuck at that one.

lucasnetau commented 5 months ago

I would guess these are all babel-loader errors now, likely need to install some plugins

https://stackoverflow.com/questions/54298816/how-to-fix-path-inshadow-is-not-a-function-when-transpiling-code-using-grunt https://github.com/WebReflection/babel-plugin-transform-builtin-classes/issues/16

giannicolac commented 5 months ago

Installed a few plugins: plugins:['babel-plugin-transform-es2015-modules-commonjs', '@babel/plugin-transform-runtime', 'babel-plugin-transform-vue-jsx', '@babel/plugin-syntax-jsx', '@babel/plugin-proposal-private-property-in-object', '@babel/plugin-transform-classes']

with this, the path.inShadow error is gone.

The "you may need an appropiate loader" error remains for form-render.

Maybe i'm missing a specific plugin?

kevinchappell commented 5 months ago

im a bit confused why any babel-loader would be needed for formBuilder or formRender. is your custom babel config not excluding node_modules?

giannicolac commented 5 months ago

I don't think so, no. This is the extent of my loader configuration in the nuxt config file:

  build: {
    extend(config) {
      config.module.rules.push({
        test: /form-builder\.min\.js$|form-builder\.js$/,        
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              plugins:['babel-plugin-transform-es2015-modules-commonjs', '@babel/plugin-transform-runtime', 'babel-plugin-transform-vue-jsx', '@babel/plugin-syntax-jsx', '@babel/plugin-proposal-private-property-in-object', '@babel/plugin-transform-classes']
            }
          }
        ]
      })

      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    },
  },

Not sure what to say, if i didnt have babel loader, it would just tell me i need a loader for those files (which it doesnt anymore for formBuilder, but it does for formRender).

giannicolac commented 5 months ago

Fixed it. Now i can see the form editor.

image

The fix was pretty obvious this time around. I forgot to actually use the loader on form-render, that's on me.

  extend(config) {
      config.module.rules.push({
        test: /form-(builder|render)\.min\.js$/,        
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              plugins:['@babel/plugin-transform-modules-commonjs', '@babel/plugin-transform-runtime', '@vue/babel-plugin-transform-vue-jsx', '@babel/plugin-syntax-jsx', '@babel/plugin-proposal-private-property-in-object', '@babel/plugin-transform-classes']
            },
          }
        ]
      })

      config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      })
    }
kevinchappell commented 5 months ago

Glad you got it sorted it out 👍