I am trying to call some script in a newly ajax loaded tab but it looks like the script blocks inside the tab are not being processed at all so when I go to call a function in the tab the function cannot be found. Is there a way to properly load the tab content such that the scripts are interpreted?
I have tried playing with the ajax options but that doesn't seem to help.
$("#tabs").tabs({
ajaxOptions: {
error: function (xhr, status, index, anchor) {
$(anchor.hash).html("This tab not yet built, sorry bub.");
},
dataType: 'html'
},
spinner: 'Loading tabs...',
});
In the tabs I have something like
<script type="text/javascript">
function SetupTab(){
alert('loaded');
}
</script>
but
$("#tabs").bind("tabsshow", function(event, ui){ SetupTab();});
cannot find SetupTab. Even if I allow the tab to load and then attempt to call SetupTab from firebug it can't be found.
if you try and bind any events/actions to a html element that does not exist yet i.e.
$(document).ready(function(){
//apply elemnt bindings here
});
when you do load the elements using ajax the elements will not take on the bindings you supplied on document ready because they did not exist at that point.
Add a call back to your ajax call to then bind any events/functions to ur new html elements, then this should work.
I think thats what you was reffering to.
EDIT: try this.
$("#tabs").bind("tabsshow", function(event, ui){ alert('loaded');});
EDIT AGAIN: you could try this.
make sure the page you are loading just contains the script itself and not the script tags and then use:
//lets say the data returned from your ajax call:
data = function SetupTab(){alert('loaded');}
eval(data);
then you could call that function no problem.
EDIT 3RD TIME: if you cant remove the script tags from the page your load you could regex the html. with this pattern.
pattern = /<script\b[^>]*>(.*?)</script>/i
urscript = data.match(pattern);
eval(urscript[1]);
this should work.
What you can do is also to detach your ajax call from the element (do just $.getScript for example).
Your loading tabs function should do something like this:
<div class="tabs" onclick="$.getScript('myScript.php?index='+$(this).index(#tabs"))">...
Then the server-side script should return something like this:
echo '
$("#tabs").eq('.$_GET['index'].')html("'.$myHTML.'");
/* Then the rest of your JS script (what you had in your HTML output) */
';
Related
So, I have the following code:
$(document).ready(function(){
//Retrieve menu html
$.get('/modules/menu.php', function(data) {
//Load menu html
$('main#main').prepend(data);
});
//Initialize Menu
menuInit();
$('#menuToggle').click(function() {
$('#main_menu').fadeToggle();
});
});
menuInit() successfully modifies DOM elements when included in the html directly instead of using $.get(),so the intialization has no issues, however, when using ajax, the intialization of the menu starts before the DOM elements are fully loaded.
I've made a little research and .prepend() does not support callbacks, so not an option.
Surrounding menuInit() with a setTimeOut() with 100 ms works, but it will most certainly fail with slow connections, I need something more dynamic.
Just put the rest of the code inside the callback so it executes after the data has been added to the page:
$(document).ready(function(){
//Retrieve menu html
$.get('/modules/menu.php', function(data) {
//Load menu html
$('main#main').prepend(data);
//Initialize Menu
menuInit();
$('#menuToggle').click(function() {
$('#main_menu').fadeToggle();
});
});
});
I'm loading the content of a document into a div when I click one item of the menu. This foreign document contains jQuery commands. But is not running.
$(document).ready(function() {
$("ul.subnav li a").click(function() {
link = $(this).attr("href");
$.ajax(link).done(function(data) {
$("#div-page").html(data);
});
return false;
});
});
In the document that will be loaded there is more jQuery commands like this:
$(document).ready(function() {
// get lista de estados
$.ajax("../php/get_lista_estados.php").done(function(data) {
$("#estados").append(data);
});
$("#estados").change(function() {
id = $(this).val();
// get lista de estados
$.ajax("../php/get_lista_municipios.php?id=" + id).done(function(data) {
$("#municipios").html(data);
});
});
});
But when I load this document into div the commands don't run. Do I speak clear?
When it comes to jQuery and Ajax combined - it is important to understand how JavaScript is being implemented on DOM while script loads.
The reason why you are seeing answers suggesting using $.getScript() or to add <script src="your.js"></script> is because, once DOM is loaded - then that's it. If you wanted addition functions to be fired as long as it is coming from external script via ajax, just like what you are trying to do. You are attempting to load new function to 'already-loaded' DOM - and it's not how it works.
If you want any functions to respond to the ajax injection, then you need to have your script to be among those that get preloaded when DOM is run. So, that's how $.getScript() comes into the picture.
Usually, with that kind of injection you want to do, you will want to use $.getScript() to fetch your javascript functions / definitions, meanwhile your ajax to get/post the script that contains your HTML structures. You will be able to do this fancy injection in this method and play it around with jQuery.
You can use $.getScript to load and run it. Read the jQuery docs for more info
Example:
$.getScript("test.js", function(){
alert("Running test.js");
});
Use jQuery.getScript() or:
$(document).ready(function() {
$("ul.subnav li a").click(function(e) {
e.preventDefault();
link = $(this).attr("href");
$.ajax({
url: link,
dataType: "script"
}).done(function(data){
// No need to append data as the script has already been loaded and run.
// $("#div-page").html(data);
// Do any other stuff here..
});
});
});
I have an application that builds page content from multiple page fragments comprising the template page. One or more of these fragments need to run JavaScript when the document has loaded, and it does not make sense to put fragment specific code in the template page comprising the fragments. While this approach has worked out for me quite well, I have a problem when attempting to update a fragment via Ajax based on the user's interaction with the page.
I am using jQuery and $(document).ready(function() {...}); rather liberally, both in the template page (for globally scoped code) and the fragments (for fragment specific code). Problem is, when a fragment is updated using jQuery's .html(HTML code from Ajax response) on the jQuery enriched version of the HTML element and the Ajax response itself contains $(document).ready(function() {...}); code, the HTML content gets updated nicely but the JS does not execute.
Some suggest use of eval() on the JS fragments inside the Ajax response while others forbid it. I am hoping someone will push me in the right direction with this.
$.ajax({
type: 'POST',
url: $(formObj).attr('action'),
data: $(formObj).serialize(),
})
.done(function(data, textStatus, jqXHR) {
$response = $(data.replace(/<body(.*?)>/,'<body$1><div id="ajaxResBody">').replace('</body>','</div></body>'));
$('#fragmentContent').html($response.find('#fragmentContent').html());
});
<div id="fragmentContent">...</div> is one of the fragments updated using partial content extracted from the Ajax response. When the page is initially loaded, the fragment's content DOM looks approximately like this:
<div id="fragmentContent">
<p>...</p>
<div>...</div>
<script type="text/javascript">
$(document).ready(function() {
// JS code
});
</script>
</div>
But when the same fragment's content is replaced via Ajax, the DOM looks like this:
<div id="fragmentContent">
<p>...</p>
<div>...</div>
</div>
So it is quite apparent scripts are stripped. I verified that by using the following code:
if (data.indexOf('accordion(') >= 0) {
console.log('scripts found in Ajax response');
if ($response.find('#fragmentContent').html().indexOf('accordion(') >= 0) {
console.log('scripts inserted into fragment');
}
else {
console.log('scripts stripped before content inserted into fragment!');
}
}
else {
console.log('scripts did not even make it in the Ajax response!');
}
and the following log output was yielded:
scripts found in Ajax response
scripts stripped before content inserted into fragment!
is there a way to alter .load behavior so that it load a spiner inside any div that is loading data ?
example
<div class='content lside'></div>
<script>
$(document).ajaxStart(function() {
$('body').append('<div class="notice" style="position:fixed;top:40%;left:30%;z-index:99999;"id="loadingspin">loading</div>'); });
$(document).ajaxStop(function() {
$('#loadingspin').fadeOut().remove();
});
$('.content').load("<?=base_url();?>booking/<?=$day?>");
</script>
i use above script.
but what i actually want is that when ever ajaxstart the content of $('.content') is replaced with spinner until it finish loading the new content.
so is there a way i can extend .load to do that by it self and replace the ajaxstart,
so where ever $(div).load() is called a $(div).html('spiner'); is fired.
if not, is there a way .ajaxstart can reference the div that the content will be loaded into ?
please note: im currently using .ajaxstart and .ajaxstop in my header script in all my webpage to handle showing the spinners in general, but i want to replace it/extend it with div specific solution that would still work on any page without further editing into each and every ajax request.
thanks
probably something like this should do the trick. Override jQuery's prototype and save the old function.
(function(){
var oldLoad = jQuery.fn.load;
jQuery.fn.load = function( url, data, complete ){
/*
* do your stuff
*/
oldLoad.call( jQuery, url, data, complete );
}
})();
That changes the globally available jQuery.load() method for the whole page so »your stuff« should be executed even if other scripts call that method, a least after your re-definition of that function is parsed.
Ok the following HTML code is parsed when I load a page:
<div id="clip-wrapper">
<script type="text/javascript">
alert("bla");
</script>
</div>
This obviously leads to an alert saying "bla", after my AJAX call, the parsed HTML code looks like this:
<div id="clip-wrapper">
<script type="text/javascript">
alert("ajaxbla");
</script>
</div>
This on the other hand, doesn't result in an alert. Why? And how do I fix this?
If there are any scripts loaded into your dom from an Ajax call, they will not be executed for security reasons.
To get the script to execute, you'll need to strip it out of the response, and run it through eval
Ideally though, you'll want to run your script as a callback for when your ajax request completes. If you're using jQuery, this would be the success event of your ajax call, and if you're doing it natively, it would be the readyStateChange event of your xhr object.
EDIT
If you really want to opt for the eval option, you could try something like this:
document.getElementById(contentDiv).innerHTML = xmlHttp.responseText;
eval(document.getElementById("clip-wrapper").innerHTML);
put you code in
$(document).ready(function()
{
alert(msg);
});
or make use of readysatchange event of XMLHttp object.
XMLHttpobject.readyStateChange( furnction() { alert('msg'); } );
Edit
if you are using jquery than go for
$.ajax({
url: "test.html",
context: document.body,
success: function(){
$(this).addClass("done");
}
});
here in sucess event you can write your code which get executed once you are done with the ajax.
any code inside body in between script tag will executed only while loading the document.
in ajax call,make use of callback or success: or oncomplete: to handle the ajax response if you are using jQuery.
You mean the second html code is coming as an ajax response?? Did you even inserted the html to the current page?
Something like,
document.body.innerHTML = ajax_response;
But even with innerHTML replacement I don't thing the script inside it will be auto executed. The browser will parse the script but won't auto execute it. (For eg, if you have a function definition in the html, after the ajax call you will be able to call those functions)
Another option is to use document.write, it will replace the whole page content with the new html and the script tags in it will be auto executed.
document.write(ajax_response);
Hope this helps,