I have an issue:
I am implementing jQuery scroll bar (from here) on my content list that are populating through Ajax. I have two pages. On the first page js/custom_scrollbar.js have main "jp-container" function.
First Page:
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/jquery.jscrollpane.codrops2.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<!-- the mousewheel plugin -->
<script type="text/javascript" src="js/jquery.mousewheel.js"></script>
<!-- the jScrollPane script -->
<script type="text/javascript" src="js/jquery.jscrollpane.min.js"></script>
<script type="text/javascript" src="js/scroll-startstop.events.jquery.js"></script>
<script type="text/javascript" src="js/custom_scrollbar.js"></script>
</head>
<body onload='myContactList();'>
<div id="contentListDiv" class="list jp-container"></div>
</body>
</html>
Second Page:
<ul>
<li>
Z
</li>
</ul>
When i receive Ajax response, it populates <li> list and merge contents in <div> on the first page through .innerHTML. I'm simply calling a part of another page and merging its contents into the main page. Following function is getting Ajax response.
function myContentList() {
var http = createRequestObject();
http.open('GET', 'myContentListURL');
document.getElementById("contactListDiv").innerHTML = '<img src="images/loader-small.gif" border="0" />';
http.onreadystatechange = function() {
if (http.readyState == 4 && http.status == 200) {
if (http.getResponseHeader("SessionExpired") == "true")
window.location = "SessionExpiredURL";
var response = http.responseText;
if (response) {
document.getElementById("contactListDiv").innerHTML = response;
eval(document.getElementById('contactsDivScript').innerHTML);
}
}
};
http.send(null);
}
When I place <ul> on first page without calling Ajax or .innerHTML - jQuery works as expected and it displays jQuery scroll bar on contents. But if i follow above code it doesn't call jQuery script.
Thank You!
The flow of your code goes something like this:
1) You load the page and the javascript.
2) jScrollPane is initialized and <div id="contentListDiv" class="list jp-container"></div> is made scrollable.
3) You call ajax and receive response.
4) You overwrite <div id="contentListDiv" class="list jp-container"></div> with your ajax response making it just plain old html (non scrollable).
You see the problem?
Basically what you need to do is call jScrollPane after you got the ajax response and updated <div id="contentListDiv" class="list jp-container"></div>. So the jspane can make it scrollable again. To do this you need to modify your code after ajax response like following:
document.getElementById("contactListDiv").innerHTML = response;
eval(document.getElementById('contactsDivScript').innerHTML); //eval()? seriously?
$('#contentListDiv').jScrollPane();
You can read more about jScrollPane here -> http://jscrollpane.kelvinluck.com/
Also You should get some javascript and jquery knowledge first, no offense.
Actually you don't use the full functionallity of jquery.
The code you post uses al lot of plain Javascript. Not a real problem, but a little bit strange.
so please look at the documentation of jquery and especially at the Ajax docu.
http://api.jquery.com/category/ajax/
But nevertheless:
I will do it like this:
$("#contactListDiv").load("GET", url ,function(){
//add your content here when loading is finished
});
Using the full potential of jQuery could make this as simple as:
$(function(){
$("#contactListDiv").load('myContentListURL', function(){
$(this).jScrollPane();
});
});
Take a look in:
http://api.jquery.com/ready/
and
http://api.jquery.com/load/
Related
I am receiving an intermittent error from JavaScript in my production environment and was hoping to learn more about the loading process.
The error is simple enough to understand:
'kendo' is undefined.
It states that the kendo variable is undefined at a time that I try to use it. However, I have all of my JavaScript code wrapped inside a jQuery ready event, like so...
<head>
<script src="path/to/jQuery.js"></script>
</head>
<body>
<!-- ... -->
<script>
jQuery(function ($) {
var test = new kendo.data.DataSource({
// datasource options
});
});
</script>
<!-- ... -->
<script src="path/to/kendo.js"></script>
</body>
I was under the impression that doing jQuery(function() { ... }); would cause the inner code to run after the DOM is ready and that it would run only after all of the <script> tags have been parsed and processed.
Is this not the case? Should I be adding my code to the loaded event instead of the ready event?
FWIW, we are using Cloudflare to handle minifying and caching, and the intermittent behavior seems to only be related to IE. I can't replicate the problem, though, I just get notified when one of our pages fails to finish loading and I see the console has this undefined error. Navigating to the page again yields no problem, so I'm a little baffled. Any ideas?
Also, I don't see any duplicate references to the jQuery or kendo libraries in my code.
Use it this way ...
<head>
<script src="path/to/jQuery.js"></script>
</head>
<body>
<!-- ... -->
<script src="path/to/kendo.js"></script>
<script>
jQuery(function() {
var test = new kendo.data.DataSource({
// datasource options
});
});
</script>
<!-- ... -->
</body>
In my parent.htm there's a dropdown list, which is filled dynamically from the database using a JQuery function updateMyList() in parent.js.
If the user wants to add another option to the list, the form child.htm is loaded inside <div id="overlay"> of the parent.htm. To insert new data an AJAX request is called from child.js, which is included in child.htm.
If the request was successful, child.htm is unloaded via $("#overlay").html("") from child.js. When this happens, i'd like to call parent.js's updateMyList(), but i can't find a way to trigger it.
Using opener from inside child.js didn't work (TypeError: opener is null) and i can't find a way to tell if $("#overlay").html() has been changed back to "".
Any help would be greatly appreciated!
Sorry if this is a double post, i'm running out of ideas for search terms...
edit: here's a simplified code:
parent.htm:
<head>
<script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="parent.js"></script>
<script>
$(document).ready(function () {
$('#new-option').click(function(){
$("#overlay").load("child.htm");
});
});
</script>
</head>
parent.js:
$(document).ready(function(){
function updateMyList(){
//send AJAX and write options
});
// and do much more...
});
child.htm:
<head>
<script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/child.js"></script>
</head>
child.js:
$(document).ready(function(){
// do more stuff
$('#save-option').click(function(){
$.post("./inc/savenewoption.php", {
//save user entries
}, function(data){
alert(data);
})
.done(function() {
updateMyList(); // <- this won't work
$("#overlay").html("");
});
});
});
It doesn't work because updateMyList() is inside a different function (one of your $(document).ready() ones). In my experience the only reason you put code into a $(document).ready() function is because Javascript can fire before the document has completely loaded. Trying to fire Javascript on elements before they are in the document will cause errors.
The updateMyList() function doesn't fire until the ajax request is complete, so it should be safe to have it located outside $(document).ready().
I'm trying to implement FullCalendar into a page on my wordpress web site using the built in page editor.
Here's the code:
<code>
<!DOCTYPE html>
<html>
<head>
<link href='../fullcalendar-2.0.2/fullcalendar.css' rel='stylesheet' />
<script src='../fullcalendar-2.0.2/lib/moment.min.js'></script>
<script src='../fullcalendar-2.0.2/lib/jquery.min.js'></script>
<script src='../fullcalendar-2.0.2/fullcalendar.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
// put your options and callbacks here
})
});
</script>
</head>
<body>
<div id="calendar"></div>
</body>
</html>
</code>
The problem I am having is that even though I am following the implementation guides closely I keep getting the error:
Uncaught SyntaxError: Unexpected token <
When I click to go into the code in the console it loads nothing up and after an hour of changing small things it's completely stopped me moving forward
If you want to do this in your page's content, you should not include the <html>, <head>, etc elements. You will also need to use an absolute path to your included files so that they do not products 404 errors (likely where the error you see is coming from) - this means you need to start the URL with a / to point directly to the files.
Try this code, assuming that fullcalendar is in your theme under the directory /wp-content/themes/yourtheme/fullcalendar-2.0.2/:
<link href='/wp-content/themes/yourtheme/fullcalendar-2.0.2/fullcalendar.css' rel='stylesheet' />
<script src='/wp-content/themes/yourtheme/fullcalendar-2.0.2/lib/moment.min.js'></script>
<script src='/wp-content/themes/yourtheme/fullcalendar-2.0.2/lib/jquery.min.js'></script>
<script src='/wp-content/themes/yourtheme/fullcalendar-2.0.2/fullcalendar.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
// put your options and callbacks here
});
});
</script>
<div id="calendar"></div>
I have discovered that the Wordpress plugin for Fullcalendar allows for custom XML feeds. So I have managed to implement the calendar onto my page, which was the aim of this question.
I have been puzzling with this for quite a while and can't get it to work. Here is the situation. I want a SOCIAL MEDIA bar to ONLY appear if people click some DIV. It should not be loaded unless people click the div. For Social Media I have ADD THIS, and the GOOGLE+1 icon. But I can not get them to load by such an external call. Here is the code so far:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=ISO-8859-1" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#socialmedia").live('click',function(){
$("#loadhere").load('html-part.html');
$.getScript('js-part.js');
});
});
</script>
</head>
<body>
<div id="socialmedia">
Show the Social Media
</div>
<div id="loadhere">
</div>
</body>
</html>
In the HTML part I have the HTML info that needs to be loaded:
html-part.html:
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<!-- AddThis Button END -->
<g:plusone size="medium" id="gg"></g:plusone>
</div>
For the JS part I am struggling. Here is what needs to be loaded:
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=ID"></script>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
I have tried to call them one by one:
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=ID');
$.getScript('https://apis.google.com/js/plusone.js');
But I guess this is a crossdomain problem...?
If I use PHP to obtain the content, and load a local PHP file, it still does not work. Before spending one more day on this... is this possible to achieve?
The problem here is that addthis code fires on dom ready event. When you load it with jQuery the dom has already been loaded so the code is not executed. The fix is to use addthis.init() method to force the code execution after you load the code. There is no cross domain problem or anything.
Note that according to addthis documentation it should be possible by just passing a get variable through the widget url like this http://s7.addthis.com/js/250/addthis_widget.js#pubid=[PROFILE ID]&domready=1 but it didn't work for me.
I would also recommend you store the html in a string variable, that way you don't have to do unnecesary requests for a little static html.
See working demo here: http://jsfiddle.net/z7zrK/3/
$("#socialmedia").click(function(){
var add_this_html =
'<div class="addthis_toolbox addthis_default_style ">'+
'<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>'+
'<a class="addthis_button_tweet"></a>'+
'<a class="addthis_counter addthis_pill_style">'+
'</a>'+
'</div>'+
'<g:plusone size="medium" id="gg"></g:plusone>';
$("#loadhere").html(add_this_html);
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=xxx',
function(){
addthis.init(); //callback function for script loading
});
$.getScript('https://apis.google.com/js/plusone.js');
});
Just used amosrivera's answer (huge kiss to you btw :) and ran into another issue :
Addthis object can only be loaded once, so when you have multiple addthis toolboxes on the same page it may only work for the first clicked toolbox.
The workaround is to do :
if (window.addthis){ window.addthis = null; }
before calling
addthis.init();
Here's what I've just done to start loading the buttons only when an article is hovered long enough :
HTML:
<article data-url="someUrl" data-title="someTitle" data-description="someDesc">
.....
<div class="sharing">
<div class="spinner"></div>
<div class="content"></div>
</div>
</article>
JS :
// Only throw AJAX call if user hovered on article for more than 800ms
// Then show the spinner while loading buttons in a hidden div
// Then replace the spinner with the loaded buttons
$(function() {
var t;
$("article").hover(function() {
var that = this;
window.clearTimeout(t);
t = window.setTimeout(function () {
sharing_div = $('.sharing', that);
add_this_html =
'<div class="addthis_toolbox addthis_default_style "> \
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a> \
<a class="addthis_button_google_plusone" g:plusone:size="medium"></a> \
</div>';
if (sharing_div.find('.content div').length == 0) {
sharing_div.find('.spinner').show();
sharing_div.find('.content').html(add_this_html);
sharing_div.find('addthis_toolbox').attr({
'addthis:url': $(that).attr('data-url'),
'addthis:title': $(that).attr('data-title'),
'addthis:description': $(that).attr('data-description'),
})
if (window.addthis){ window.addthis = null; } // Forces addthis to reload
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=xxx&async=1',
function(){
addthis.init();
setTimeout(function() {
sharing_div.find('.spinner').hide();
sharing_div.find('.content').show();
}, 2500);
});
}
}, 800);
});
});
To answer your official question, yes, I believe this is possible to achieve.
But, to further elaborate on this, I believe what you may want to try working with is the order in which your external scripts and external markup are loaded. An interesting situation we find when dealing with asynchronous actions such as these, is that they don't always complete, load, or execute in the order you would like unless you specifically say so. jQuery lets you do this through some callbacks you can pass to the getScript and load methods.
There also should not be a "cross-domain" problem with javascript files on other domains, though there certainly is when loading HTML.
I'm not sure if this will exactly solve the problem you're having, but it certainly feels like this is worth a try. You could try making sure the markup loads before the scripts do:
$(function(){
$("#socialmedia").live('click',function(){
$("#loadhere").load('html-part.html', function() {
// this waits until the "html-part.html" has finished loading...
$.getScript('js-part.js');
});
});
});
Now, we should also ask about how you are building your "js-part.js" file. (You only showed what you wanted, not what you've built.) If this is truly a JS file, you can't just use some HTML <script> tags to load other JS files. (You would instead want to continue calling getScript in this file, or use one of several other approaches to get your other JS stuff loaded, such as manually appending script elements to the document's head, or using another library, etc...)
Good luck!
I've updated the script here to give a better example. For $header I've got an anonymous function now returning $("#header"). Although this works I'm sure its not efficient as it calls $header every time it's used - so its the same as just using $("#header") throughout the code.
What I really want is to store $("header") in a variable. When I try to do this with $header2 (below) it fails. #header is red not blue.
When I use firebug to output lib.page.$header2.selector is correctly displays #header. As you can see the script which calls lib.page.init is at the bottom of the DOM.
Any ideas?
<script type="text/javascript">
var lib = {
page : {
$header : function() { return $("#header")},
$header2 : $("#header"),
init: function() {
lib.page.$header().css("background","red");
lib.page.$header2.css("background","blue");
console.log(lib.page.$header2.selector);
}
}
}
</script>
</head>
<body>
<div id="wrapper">
<div id="header">
<em>Example!</em>
</div>
</div>
<script type="text/javascript">
$(function() { lib.page.init(); });
</script>
</body>
Because when you define $header : $('#header') that element is not available? and when you call lib.page.init it is? I am not sure when you call lib.page.init, but I bet it's in $(document).ready() right? And you define the object literal before the dom is ready.
Ok, your div#header is not available by the time you want to assign it to $header, you have two options and I will show you the best option first. It's what I meant with 'put all scripts at the bottom'!
<head>
<!-- dont put scripts here if you can avoid it, it's bad! -->
</head>
<body>
<div id="wrapper">
<div id="header">
<em>Example!</em>
</div>
</div>
<!-- keep scripts at the end of the page just before the </body> tag -->
<script type="text/javascript">
var lib = {
page : {
// div#header is available
$header : $("#header"),
init: function() {
lib.page.$header().css("background","red");
}
}
}
// you don't need onDomReady anymore.
lib.page.init();
</script>
</body>
Another option if you want to keep scripts in the header, is to assign $header in your onDomReady call.
<script>
// create lib etc here
$(function(){ // this is an onDomReady call in jQuery
lib.page.$header = $('#header');
lib.page.init();
});
</script>
"This happens because the variables are instantiated at the time the script is interpreted.
So at the time of the parser gets to the script the $("#header") isn't in the DOM yet."