6

Im developing a project with primefaces 5, one page uses a js file that needs jquery, but shows Uncaught TypeError: undefined is not a function, but when I change my jquery source from <h:outputScript library="primefaces" name="jquery/jquery.js" target="head"/> to

<h:head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
</h:head>

works fine but I lost many primefaces features like contexMenu

How can I solve this conflict?

This is my javascript file:

(function($, $S) {
//$ jQuery
//$S window.localStorage
//Variables Declaration
var $board = $('#notesForm\\:board'),
//Board where the Posticks are sticked
Postick, //Singleton Object containing the Functions to work with the LocalStorage
len = 0, //Length of Objects in the LocalStorage
currentNotes = '', //Storage the html construction of the posticks
o; //Actual Postick data in the localStorage

//Manage the Posticks in the Local Storage
//Each postick is saved in the localStorage as an Object 
Postick = {
    add : function(obj) {
        obj.id = $S.length;
        $S.setItem(obj.id, JSON.stringify(obj));
    },

    retrive : function(id) {
        return JSON.parse($S.getItem(id));
    },

    remove : function(id) {
        $S.removeItem(id);
    },

    removeAll : function() {
        $S.clear();
    }

};

//If exist any postick, Create it/them
len = $S.length;
if (len) {
    for (var i = 0; i < len; i++) {
        //Create all posticks saved in localStorage
        var key = $S.key(i);
        o = Postick.retrive(key);
        currentNotes += '<div class="postick"';
        currentNotes += ' style="left:' + o.left;
        currentNotes += 'px; top:' + o.top;
        //data-key is the attribute to know what item delete in the localStorage
        currentNotes += 'px"><div class="toolbar"><span class="delete" data-key="'
                + key;
        currentNotes += '">x</span></div><div contenteditable="true" class="editable">';
        currentNotes += o.text;
        currentNotes += '</div>';
    }

    //Append all the posticks to the board
    $board.html(currentNotes);
}

//When the document is ready, make all posticks Draggable
$(document).ready(function() {
    $(".postick").draggable({
        cancel : '.editable',
        "zIndex" : 3000,
        "stack" : '.postick'
    });
});

//Remove Postick
$('span.delete').live('click', function() {
    if (confirm('Are you sure you want to delete this Note?')) {
        var $this = $(this);
        //data-key is the attribute to know what item delete in the localStorage
        Postick.remove($this.attr('data-key'));
        $this.closest('.postick').fadeOut('slow', function() {
            $(this).remove();
        });
    }
});

//Create postick
$('#notesForm\\:btn-addNote')
        .click(
                function() {
                    $board
                            .append('<div class="postick" style="left:20px;top:70px"><div class="toolbar"><span class="delete" title="Close">x</span></div><div contenteditable class="editable"></div></div>');
                    $(".postick").draggable({
                        cancel : '.editable'
                    });
                });

//Save all the posticks when the user leaves the page
window.onbeforeunload = function() {
    //Clean the localStorage
    Postick.removeAll();
    //Then insert each postick into the LocalStorage
    //Saving their position on the page, in order to position them when the page is loaded again
    $('.postick').each(function() {
        var $this = $(this);
        Postick.add({
            top : parseInt($this.position().top),
            left : parseInt($this.position().left),
            text : $this.children('.editable').text()
        });
    });
}
})(jQuery, window.localStorage);
Juan Camilo Mejia
  • 952
  • 3
  • 14
  • 28
  • does primefaces include jqueryui by default? looks like the first version you haven't included the ui library, which would mean `draggable` is undefined – Pete Aug 26 '14 at 14:50
  • Thanks boot for the answers i have to add a sticky note when the user press right click, de code what I posted above is the js sticky note code, if i use primefaces jquery, the contextMenu detect the rigth click but the stiky note code doesn´t runs, if I use the jquery links the sticky note code works but the contex menu doesn´t, this is the notes code working: http://pastie.org/9504320 and this is the contextMenu working : http://pastie.org/9504322 In the last one the sticky note shows Uncaught TypeError: undefined is not a function . – Juan Camilo Mejia Aug 26 '14 at 15:00
  • BalusC I found the code in internet, that is the truth. The google chrome debugger show me error in this line $('span.delete').live('click', function() – Juan Camilo Mejia Aug 26 '14 at 16:46
  • Man i just moved from "live" to "on" and works but now i habe to refresh the page to call the delete method – Juan Camilo Mejia Aug 26 '14 at 16:54
  • This is annother problem but the originall was fixed, thankyou so much I´ll take more care about the versions. Create a answer to set as solved please – Juan Camilo Mejia Aug 26 '14 at 17:13
  • @JuanCamiloMejia you're able to create it yourself and mark as answered, if you want. – Aritz Aug 27 '14 at 11:32
  • I reposted it as an answer. In the future, when you want to respond on a specific comment while more than one other user has commented, then please use `@BalusC` to notify me. – BalusC Aug 27 '14 at 11:52
  • Possible duplicate of [Adding jQuery to PrimeFaces results in Uncaught TypeError over all place](https://stackoverflow.com/questions/16166039/adding-jquery-to-primefaces-results-in-uncaught-typeerror-over-all-place) – Jasper de Vries Jan 28 '19 at 11:00

2 Answers2

35

PrimeFaces as being a jQuery based JSF component library already ships with jQuery (and UI) out the box. PrimeFaces loads them all by itself once you use PrimeFaces components on the page. There's absolutely no point of manually loading another jQuery files along it. It'll only conflict in all colors as you experienced.

If you actually want to use jQuery/UI on a page which doesn't necessarily include PrimeFaces components and thus jQuery/UI doesn't necessarily get auto-included, then you need to manually include the PrimeFaces-bundled jQuery as follows:

<h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
<h:outputScript library="primefaces" name="jquery/jquery-plugins.js" target="head" />

Note: this won't end up in duplicate inclusions. JSF/PrimeFaces is capable of detecting that you already manually declared them and won't auto-include another one.

Or, if you actually want to upgrade PrimeFaces-bundled jQuery/UI to a newer version, then place those files on exactly the following location and file names:

WebContent
 |-- resources
 |    `-- primefaces
 |         `-- jquery
 |              |-- jquery.js          <-- newer jQuery version
 |              `-- jquery-plugins.js  <-- newer jQuery UI version
 :

When a JSF resource is found in WAR instead of JAR, then those in WAR will have higher loading precedence over those in JARs.

If you're still facing Uncaught TypeError errors, then make sure that the jQuery snippet you found in the Internet is compatible with the PrimeFaces-bundled jQuery version. PrimeFaces 5.0 ships with jQuery 1.11.0 and jQuery UI 1.10.3. Your snippet seems to be targeted at jQuery 1.4 and a lot has been changed in the path to jQuery 1.11. So is for example $.live() deprecated in 1.7 and removed in 1.9. See also the documentation.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 'There's absolutely no point of manually loading another jQuery files along it' ............Today I needed to use the jquery autocomplete method and I couldn't because cannot run primefaces jquery along with jquery. So at least I think that there could be point in using this. Primefaces has autocomplete but the autocomplete was already implemented with jQuery, so in this case I should implement everything with primefaces, or to use only jQuery – makkasi Jun 23 '16 at 13:06
  • @BalusC would you mind explaining the 'why' of why jquery-ui.js should be renamed to jquery-plugins.js please? i.e. we've seen that it doesn't work if you try to upgrade by placing a newer jquery-ui.js in resources/primefaces/jquery, it must be named jquery-plugins.js, but why is that? – johnd Aug 16 '22 at 05:49
  • @johnd because that's the resource name internally hardcoded/used/recognized by PrimeFaces. – BalusC Aug 16 '22 at 08:24
  • Thank you! So is it safe to assume that jquery-plugins.js will always be just jquery-ui.js? The reason I ask is that I had a look at the POM on the PrimeFaces repo, and it looks almost as if it's bundling together multiple JS files into one jquery-plugins.js – johnd Aug 16 '22 at 08:26
3

I had also like you problem. Make sure script declaration as below example. Don't use $(....) sing. Use jQuery(...). It is ok for me.

<h:head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
    <h:outputScript library="primefaces" name="jquery/jquery.js" target="head"/>
    <script type="text/javascript">
        jQuery(document).ready(function(jQuery){

            ..don't use $

        });
    </script>       
</h:head>

Multiple different versions of jQuery co-existing

Zaw Than oo
  • 9,651
  • 13
  • 83
  • 131