Manually adding / loading jQuery with PrimeFaces results in Uncaught TypeErrors
I'm using PrimeFaces 3.5 and JSF 2.0. I wanted to use a jQuery plugin, so I included jQuery in my webapp.
<h:head>
<h:outputScript name="js/jquery.min.js" />
<h:outputScript name="js/jquery-ui.js" />
</h:head>
However, when using PrimeFaces components, I get uncaught type errors like this:
Uncaught TypeError: Cannot read property 'length' of undefined
Uncaught TypeError: Object [object Object] has no method 'autocomplete'
Uncaught TypeError: Cannot read property 'keyCode' of undefined
Uncaught TypeError: this.jq.draggable is not a function
Uncaught TypeError: Cannot read property 'LinearAxisRenderer' of undefined
Uncaught TypeError: Object [object Object] has no method 'fileupload'
Uncaught TypeError: this.jqEl.datetimepicker is not a function
Etc.
How is this caused and how can I solve it?
PrimeFaces is a jQuery based JSF component library. It already ships with jQuery and jQuery UI out the box. It is not right to manually load another copy of jQuery/jQuery UI for some reason. Multiple different versioned jQuery files would only conflict with each other this way, because they do not necessarily use/share exactly the same variables/functions.
Get rid of all those manually loaded jQuery/UI files. This makes no sense.
If you did this because you need to utilize some jQuery/UI magic in some page which doesn't necessarily use any PrimeFaces components (and thus its bundled jQuery won't be auto-included and thus $()
would be unavailable), then you can always manually explicitly include PrimeFaces-bundled jQuery in some master template as below:
<h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
<h:outputScript library="primefaces" name="jquery/jquery-plugins.js" target="head" />
(the target="head"
is unnecessary if you specify them directly inside <h:head>
)
If you absolutely need to supply your own version of jQuery, because the one bundled in PrimeFaces is outdated, then you have 2 options:
Let your webapp supply its own on exactly the same resource identifier (library/name)
/resources/primefaces/jquery/jquery.js
(don't change the path nor filename!). This one will then be picked instead of the PrimeFaces-bundled one.Unpack
primefaces.jar
, replace/META-INF/resources/primefaces/jquery/jquery.js
file with the newer version (don't change the path nor filename!), repack a newprimefaces.jar
.
(and don't forget to remove all those <h:outputScript>
references to own copy)
Test however thorougly. Some PrimeFaces-specific functionality may break with the upgrade because of minor changes/bugfixes in the newer jQuery version as compared to the PrimeFaces-bundled one.
Above all, you should make absolutely sure that you do not provide multiple copies of jQuery/UI, or you will still face conflicts/clashes as currently. Using $.noConflict()
as some people may suggest is absolutely not intented to be able to use multiple jQuery libraries together. It's intented to be able to use jQuery together with another JS library which coincidentally also uses $()
as global function, such as Prototype. See also a.o. Jquery and prototype noconflict.