guillaumepotier / Parsley.js

Validate your forms, frontend, without writing a single line of javascript
http://parsleyjs.org
MIT License
9.04k stars 1.3k forks source link

Browserify and Parsley #1104

Open vvebvvizard opened 8 years ago

vvebvvizard commented 8 years ago

Hi,

I have an issue with Parsley when I'm adding it via Browserify.

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

This is my script

var $ = require('jquery');
require('parsleyjs');

$("[data-parsley-validate]").parsley({
    trigger:      'change',
    errorClass: "parsley-error",
    classHandler: function (el) {
        return el.$element.closest('.form-item, .form-item--inline, .form-item--icon');
    },
    errorsContainer: function(pEle) {
        var $err = pEle.$element.closest('.form-item, .form-item--inline, .form-item--icon').append();
        return $err;
    }
});

I tried to use the window object but I got the same error.

I use Gulp with Browserify, others plugins works well with it. But I got the same error with slick carousel, then I used the build they made especially for Browserify and it worked.

Thanks!

marcandre commented 8 years ago

Mmm, I think it should be compatible but not too sure how it works. I'm travelling right now, won't have time to look it up for a while...

rhk4360 commented 7 years ago

Did you ever have any luck with this gor0n?

vvebvvizard commented 7 years ago

Yeah, with Browserify you can require with a path (useful to require your custom plugins that are not on npm registry).

So I just require parsley like that require('../../../../node_modules/parsleyjs/dist/parsley.min.js') and it works.

marcandre commented 7 years ago

If anyone has a better fix, let me know.

rhk4360 commented 7 years ago

Unfortunately, I still get the error with that workaround so as a temporary workaround I'm loading parsley via a cdn outside of my main JS package for now.

If I find time, I'll try to dig into the root problem a bit more. I thought it might be a problem with jquery loading after parsley because if I reference Parsley in console it's there, but it's just not tied to jquery DOM elements.

This really is a great front-end validation library so a huge thank you to the contributors.

Cheers

vvebvvizard commented 7 years ago

If it can help you, that's how I use parsley.

( function( $ ) {

$("[data-parsley-validate]").length && $("[data-parsley-validate]").parsley({
    trigger:      'change',
    errorClass: "parsley-error",
    classHandler: function (el) {
        return el.$element.closest('.form-item');
    },
    errorsContainer: function(pEle) {
        var $err = pEle.$element.closest('.form-item').append();
        return $err;
    }
});

} )( require('jquery'), require('../../../../node_modules/parsleyjs/dist/parsley.min.js') );`

mockdeep commented 7 years ago

I've been seeing this problem, too. It appears that if parsley is being required via require, it expects to also be able to require('jquery') as well, which isn't necessarily the case if you pull in jquery via another means. It ends up requiring a second copy and applying itself to that one instead.

It would be nice to be able to customize this somehow, maybe via the ParsleyConfig global, or by being able to invoke the factory function manually and inject jquery ourselves.

mockdeep commented 7 years ago

This is also a problem in the minified version.

LeKangouroo commented 7 years ago

I managed to use it with the ES2015 modules import syntax for those who are interested:

import Parsley from 'parsleyjs';

// NOTE: Parsley is not a constructor, therefore new Parsley() doesn't work.
const validator = new Parsley.Factory(formElement, options);

console.log('is valid', validator.isValid());

It doesn't resolve the issue related to jQuery though.

bajax commented 7 years ago

This was blocking one of our projects, and after three hours digging deep in browserify, I think I've at least found an explanation for this:

Browserify treats all require calls as something to be compiled. This makes jQuery, for all intents and purposes, a compile-time dependency for ParsleyJS when referenced via Browserify-- and it REALLY shouldn't be!

There doesn't appear to be a way to fix this and still use es2015 syntax. It may be necessary to just check for a global jQuery variable and use that instead of the require syntax to get a reference to jQuery.

marcandre commented 7 years ago

@bajax Sure, I'm not against this. Let's not rely on a global $, so maybe something like var $ = window.jQuery instead of the require? Care to provide a PR?