Solomon Closson Solomon Closson - 1 month ago 9
jQuery Question

jQuery UI draggable is not a function Error

Ok, I keep getting an error message and am unable to drag any of the divs...

Error message is as follows:


Uncaught exception: TypeError:
'$(".polaroidpolaroid_attachments_mod_25").draggable' is not a
function Error thrown at line 343, column 4 in ($)
in http://developers.dream-portal.net/test/index.php:
$(".polaroidpolaroid_attachments_mod_25").draggable({ called via Function.prototype.apply() from line 2, column 33900 in (t) in
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:
if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse) called from line 2, column 34244 in () in
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:
(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))
called from line 2, column 22488 in (e) in
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:
return v.ready.promise().done(e),this called from line 276, column 3 in startPolaroids() in
http://developers.dream-portal.net/test/index.php:
jQuery(document).ready(function($){ called from line 1322, column 5 in () in
http://developers.dream-portal.net/test/Themes/default/scripts/script.js?fin20:
aOnloadEventsi;


I am using an external js file that gets loaded in the head of the webpage with the following function:

var aOnloadEvents = new Array();
function addLoadEvent(fNewOnload)
{
// If there's no event set, just set this one
if (typeof(fNewOnload) == 'function' && (!('onload' in window) || typeof(window.onload) != 'function'))
window.onload = fNewOnload;

// If there's just one event, setup the array.
else if (aOnloadEvents.length == 0)
{
aOnloadEvents[0] = window.onload;
aOnloadEvents[1] = fNewOnload;
window.onload = function() {
for (var i = 0, n = aOnloadEvents.length; i < n; i++)
{
if (typeof(aOnloadEvents[i]) == 'function')
aOnloadEvents[i]();
else if (typeof(aOnloadEvents[i]) == 'string')
eval(aOnloadEvents[i]);
}
}
}

// This isn't the first event function, add it to the list.
else
aOnloadEvents[aOnloadEvents.length] = fNewOnload;
}


And in the body of the webpage (which is all I can access from the script that runs it), I have the following code written in PHP (so please excuse the escaping of quotations):

// Only want to load up jQuery 1 time here!
if(!window.jQuery)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
var oScripts = document.getElementsByTagName("script");
var s = oScripts[0];
s.parentNode.insertBefore(script, s);
}

if(!jQuery.ui)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js";
var oScripts = document.getElementsByTagName("script");
var s = oScripts[0];
s.parentNode.insertBefore(script, s);
}

function randomNum_polaroid_attachments_mod_25(minVal, maxVal)
{
var randVal = minVal + (Math.random() * (maxVal - minVal + 1));
return Math.round(randVal);
}

function startPolaroids()
{
jQuery(document).ready(function($){
// Set up default values.
var offsetStartX = 0;
var offsetEndX = $(document).width() - $(".polaroidpolaroid_attachments_mod_25").width();
var offsetStartY = 0;
var offsetEndY = $(document).height() - $(".polaroidpolaroid_attachments_mod_25").height();
var objContain = 'document';
var objEle = document.getElementById("placeholder");
if (objEle)
{

var getObjOffset = $("#placeholder").position();

offsetStartX = getObjOffset.left;
offsetEndX = (offsetStartX + $("#placeholder").outerWidth(true)) - $(".polaroidpolaroid_attachments_mod_25").width();
offsetStartY = getObjOffset.top;
offsetEndY = (offsetStartY + $("#placeholder").outerHeight(true)) - $(".polaroidpolaroid_attachments_mod_25").height();

if (offsetEndY < offsetStartY)
offsetEndY = offsetStartY + 1;

if (offsetEndX < offsetStartX)
offsetEndX = offsetStartX + 1;
objContain = '#placeholder';
}

// When everything has loaded, place all polaroids on a random position relative to document or element id!
$(".polaroidpolaroid_attachments_mod_25").each(function (i) {
var tempVal = Math.round(Math.random());
if(tempVal == 1) {
var rotDegrees = randomNum_polaroid_attachments_mod_25(330, 360); // rotate left
} else {
var rotDegrees = randomNum_polaroid_attachments_mod_25(0, 30); // rotate right
}

var cssObj = { 'left' : randomNum_polaroid_attachments_mod_25(offsetStartX, offsetEndX),
'top' : randomNum_polaroid_attachments_mod_25(offsetStartY, offsetEndY),
msTransform: 'rotate('+ rotDegrees + 'deg)', // IE 9
'-moz-transform' : 'rotate('+ rotDegrees + 'deg)', // Firefox
'-webkit-transform' : 'rotate('+ rotDegrees + 'deg)', // Safari & Chrome
'-o-transform' : 'rotate('+ rotDegrees + 'deg)', // Opera
'transform' : 'rotate\('+ rotDegrees + 'deg)' }; // added in case CSS3 is standard
$(this).css(cssObj);
});

// Set the Z-Index (used to display images on top while dragging)
var zindexnr = 1;

// boolean to check if the user is dragging
var dragging = false;

// Show the polaroid on top when clicked on
$(".polaroidpolaroid_attachments_mod_25").mouseup(function(e){
if(!dragging) {
// Bring polaroid to the foreground
zindexnr++;
var cssObj = { 'z-index' : zindexnr,
'transform' : 'rotate(0deg)', // added in case CSS3 is standard
'-webkit-transform' : 'rotate(0deg)', // Chrome and Safari
msTransform: 'rotate(0deg)', // IE 9
'-moz-transform' : 'rotate(0deg)', // Firefox
'-o-transform' : 'rotate(0deg)' }; // Opera
$(this).css(cssObj);
}
});

// Make the polaroid draggable & display a shadow when dragging
$(".polaroidpolaroid_attachments_mod_25").draggable({
cursor: 'pointer',
containment: objContain,
start: function(event, ui) {
dragging = true;
zindexnr++;
var cssObj = { 'box-shadow' : '#888 5px 10px 10px', // added in case CSS3 is standard
'-ms-box-shadow' : '#888 5px 10px 10px', // IE 9
'-o-box-shadow' : '#888 5px 10px 10px', // Opera
'-moz-box-shadow' : '#888 5px 10px 10px', // firefox 3.5 - 4.0
'-webkit-box-shadow' : '#888 5px 10px 10px', // Chrome & Safari
'margin-left' : '-10px',
'margin-top' : '-10px',
'z-index' : zindexnr };
$(this).css(cssObj);
},
stop: function(event, ui) {
var tempVal = Math.round(Math.random());
if(tempVal == 1) {
var rotDegrees = randomNum_polaroid_attachments_mod_25(330, 360); // rotate left
} else {
var rotDegrees = randomNum_polaroid_attachments_mod_25(0, 30); // rotate right
}
var cssObj = { 'box-shadow' : '', // added in case CSS3 is standard
'-ms-box-shadow' : '', // IE 9
'-o-box-shadow' : '', // Opera
'-moz-box-shadow' : '', // firefox 3.5 - 4.0
'-webkit-box-shadow' : '', // Chrome & Safari
'transform' : 'rotate('+ rotDegrees + 'deg)', // added in case CSS3 is standard
'-webkit-transform' : 'rotate('+ rotDegrees + 'deg)', // Chrome & Safari
msTransform: 'rotate('+ rotDegrees + 'deg)', // IE 9
'-moz-transform' : 'rotate('+ rotDegrees + 'deg)', // Firefox
'-o-transform' : 'rotate('+ rotDegrees + 'deg)', // Opera
'margin-left' : '0px',
'margin-top' : '0px' };
$(this).css(cssObj);
dragging = false;
}
});
})
}
// Calling SMF js function, defined in script.js, here.
addLoadEvent(startPolaroids);


I am unable the drag the divs, and they DO EXIST in the HTML. Am getting that error above, so, trying to pinpoint the exact problem here, could use another pair of eyes on this.

Here is a link to the actual page also, if it would help: http://developers.dream-portal.net/test/index.php

Thanks guys :)

So, if I change this:

// Only want to load up jQuery 1 time here!
if(!window.jQuery)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
var oScripts = document.getElementsByTagName("script");
var s = oScripts[0];
s.parentNode.insertBefore(script, s);
}

if(!jQuery.ui)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js";
var oScripts = document.getElementsByTagName("script");
var s = oScripts[0];
s.parentNode.insertBefore(script, s);
}


To this:

if(!window.jQuery)
{
var script = document.createElement("script");
var uiScript = document.createElement("script");
script.type = "text/javascript";
uiScript.type = "text/javascript";
script.async = false;
uiScript.async = false;
script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
uiScript.src = "//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js";
var oScripts = document.getElementsByTagName("script");
var s = oScripts[0];

s.parentNode.insertBefore(script, s);
s.parentNode.insertBefore(uiScript, s);
}


It than WORKS, which seems good and all, but the code does NOT put the jQuery UI in, if jQuery exists and jQuery UI doesn't on the page already. And how would I do that exactly? Cause other software could be manipulating the page also, and adding jQuery to the pages. How should I code this? Thinking we can't use oScripts[0] to be inserted before that element... cause we really won't know where the jQuery is being called from, just that it exists...

Answer

I see that your jQuery UI is not loaded. Your script:

if(!jQuery.ui)
{
   // bla bla
}

Is causing error, since the jQuery is not defined. I think that you should wait for the jQuery to be fully loaded first then continue to the next function to check availability of jQuery UI. You need to use Synhronous execution of your script:

if(!window.jQuery)
{
   var script = document.createElement("script");
   script.type = "text/javascript";
   script.async = false; // CHANGES
   script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
   var oScripts = document.getElementsByTagName("script");
   var s = oScripts[0];
   s.parentNode.insertBefore(script, s);
}