Problems with JS in webskins

This is driving me nuts.

I’m trying to load a jQuery calendar (fullcalendar) into a webskin on a site. I’ve tried many different takes on doing this but will just outline how I understand it should happen (which isn’t working):

In _serverSpecificVarsAfterInit.cfm I’ve created the following to register the two required JS files:

<skin:registerJS id="hubcalendar" baseHREF="/farcry/plugins/hubbub/www/js/" lFiles="calendar_moment.js,calendar_fullcalendar.js" />

In my displayBody I have:

<cfimport taglib="/farcry/core/tags/webskin" prefix="skin">
<skin:loadJS id="hubcalendar" />

When I view the source this appears to have worked as I can see the hubcalendar content.

Now I need to call the fullCalendar function which I’ve tried a few different ways:

  1. Created a <script> tag and used $(document).ready(function() { $('#calendar').fullCalendar({ etc.
  2. <skin:onReady> which contains the function call tried in 1) above (without the $(document).ready….
  3. Put the function call into its own JS file and loaded it via <script src=….
  4. Using the JS file above, assigned it a new id in _serverSpecificVarsAfterInit and tried loading it via <skin:loadJS

The above (and a few other attempts) result in “TypeError: $(…).fullCalendar” is not a function error in the browser.

The only way I’ve got any of this to work is by putting all the JS calls as <script src=..> into the site footer webskin. However as the calendar is only used by a single webskin (and most likely only a very small number of instances of the calendar will ever be created on the site) I wanted all the calendar related scripts to only be loaded when this particular webskin is required. Even if the footer does load the fullCalendar functions (but not the call to the function), I still can’t get the browser to wait until the DOM is loaded before calling the function for some reason.

If I have used <skin:onReady> to load the function call, I can see in the HTML source that it seems to be all correct (noting that FC appears to be changing $ to $j):

$j(document).ready(function(){ 
	$('#calendar').fullCalendar({....

But like above, this still errors out. It gives the appearance that the (document).ready is being ignored.

I’m using FarCry 7.2.4

Regards
Mark

It depends how the JS on the front end of your site works, the order of loading jQuery and it’s plugins are important;

  1. If it’s using Core’s version of jQuery loaded with (e.g. skin:loadJS id="jquery") then you always need to use registerJS for your plugin and then load your library after you load jQuery, and you access Core’s jQuery using $j
  2. If it’s using a custom registered jQuery e.g. (e.g. skin:loadJS id="myjquery") then as above you need to use registerJS for all your plugins and then load your library after you load jQuery, and you access your custom jQuery using $
  3. If it’s using a jQuery JS file directly in the header then you should load your jQuery plugins after it in the same manner (without using registerJS/loadJS), and you access your custom jQuery using $

For front end development the third option is usually easiest since most libraries come minified and the .map files allow you to see the source in human readable form in the browser for simple debugging purposes.

Core’s jQuery will load last, followed by Core’s jQuery plugins. When you “view source” on your page, have a look at the order that all the .js files are loaded in – if the order doesn’t match the below then that’s most likely the source of the problem:

Your jQuery JS
Your jQuery plugins JS
Core jQuery JS
Core jQuery plugins JS

Of course the other option is, if jQuery is loaded in the footer then it’s plugins would need to come directly after it in the footer too, so the order I mentioned above would be reversed: :slightly_smiling:

Core jQuery JS (in head)
Core jQuery plugins JS (in head)
Your jQuery JS (in footer)
Your jQuery plugins JS (in footer)

Thanks Justin. There is a mix of scripts being loaded in both header and footer. In the header a non FC jQuery is being loaded, a library of plugins and then additional js files are also loaded in the footer.

I really wanted to avoid loading all the calendar files for the whole site when it is likely only one webskin will use (and probably not many users will visit the page using it…) which was why I was trying to get everything loaded from displayBody or displayPageStandard.

The order that I’m loading the calendar functions seems to match what you have outlined but still getting errors. I’ll try putting the two JS files in the site footer (normal way - not using registerJS/loadJS) and then put the function call in a skin:onReady in the displayBody for the calendar webskin.

Thanks for your help!