TypeError: $(...).cycle is not a function: jQuery cycle in a JSF application

user2911374 picture user2911374 · Jan 16, 2014 · Viewed 10.9k times · Source

I want to use jquery cycle in one of my pages of a JSF application. I include jquery form google and I host jquery.cycle.all.js file on my local host and I have another extra js file which contains my jquery cycle slideshow script and I include these files respectively in my page. However the slideshow does not work. Below I include firebug error and my code:

my xhtml page:

<h:form>
                                        <div>
                                            <div id="view-slider" class="pics">
                                                <img src="#{request.contextPath}/resources/images/1.jpg" width="400" height="200"/> 
                                                <img src="#{request.contextPath}/resources/images/2.jpg" width="400" height="200"/>  
                                            </div>
                                            <ul id="thumbnails"></ul>
                                        </div>
                                    </h:form>
                                    <br/>
                                    <p:separator/>
                                    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" ></script> 
                                    <h:outputScript name="js/jquery-cycle-all.js"/>
                                    <h:outputScript name="js/view-slides.js"/> 

view-slides.js

$.fn.cycle.updateActivePagerLink = function(pager, currSlideIndex) {
    $(pager).find('li').removeClass('activeLI')
        .filter('li:eq('+currSlideIndex+')').addClass('activeLI');
};

$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
    $(pager).each(function() {
        console.log(clsName + '; ' + currSlide ); 
        $(this).children().removeClass('activeLI').filter(':eq('+currSlide+')').addClass('activeLI');
    });
};

$(function() {
    $('#view-slider').cycle({
        timeout: 3000,
        pager:  '#thumbnails',
        pagerAnchorBuilder: function(idx, slide) {
            return '<li><a href="#"><img src="' + slide.src + '" width="50" height="50" /></a></li>';
        }
    });
});

Firebug error:

TypeError: $(...).cycle is not a function
view-slides.js.xhtml (line 17)

So far I have tried the following without success:

wrapped my script inside a function. checked loading sequence and it is as it should be: jsf.js, jquery, jquery.cycle, view-slides.js tested this script in a plain html file and it worked.

Extra info: I have a template which includes the same version jquery.js file from google and has a tabs.js script. These are also loaded and tabs are working. I inserted these too into my html file and it worked fine. I removied jquery from my xhtml file since I had it in the template and it gave me jquery not found error.

I don't know if it's a conflicting issue or not and if so what does it conflict with?

I appreciate your replies.

Answer

BalusC picture BalusC · Jan 16, 2014

Those kind of TypeError errors on jQuery functions are typically caused by having duplicate different versioned jQuery JS files loaded by the webapp. PrimeFaces as being a jQuery-based JSF component library already automatically loads jQuery by itself. You thus do not need to manually load another jQuery JS file yourself on top of PrimeFaces one via <script>/<h:outputScript>. If you remove it, then this error should disappear.

If you happen to have a page wherein you'd like to use some jQuery, but the page itself doesn't utilize any PrimeFaces component and thus doesn't necessarily have PrimeFaces-bundled jQuery automatically loaded, then you can always explicitly load it yourself by simply adding the following line:

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

This will explicitly load the PrimeFaces library-bundled jQuery file. Note: the target="head" can be omitted when it's already inside the <h:head>. Otherwise, e.g. when inside <h:body> or <ui:define> of a template client, it would be automatically relocated to head. Another note: you can safely use this line in a page which actually requires PrimeFaces-bundled jQuery. It won't end up in a duplciate load.