I'm trying to display a loading image after an AJAX call has been made.
Currently I have the following Javascript code:
window.onload = function(){
var img = document.createElement("IMG");
img.src = "http://i.stack.imgur.com/FhHRx.gif";
function getCategories(){
$.ajax({
url: //url here,
dataType:'jsonp',
success: function(data){
//code here
},
statusCode: {
404: function() {
alert:('There was a problem with the server');
}
}
});
}
$(document).ajaxStart(function(){
alert('here');
var div = document.createElement("div");
div.id = "id1";
document.getElementById('id1').appendChild(img);
document.body.appendChild(div);
}).ajaxStop(function(){
var element = document.getElementById('id1');
element.parentNode.removeChild(element);
});
However, I am finding that the code is not even getting to the ajaxStart function as the alert is not appearing... I have tried other methods (eg: How to show loading spinner in jQuery?) to try and get this working but have not been successful as of yet...
Would anyone be able to help with this please?
Thank you.
You are more than likely getting an error for Unexpected Token, since you are declaring a function incorrectly.
Uncaught SyntaxError: Unexpected token {
You need to declare a function with either:
function getCategories () { }
Or:
var getCategories = function () { };
I think I found the solution here ($(document).ajaxstart not firing)
It seems that ajaxStart only works when XMLHttpRequest is used. If you use JSONP, XMLHttpRequest isn't used. Rather, it inserts a <script> tag to achieve this goal.
I simply used the workaround suggested in the above link.
Related
I don't know what's wrong with the code, ever since we updated to PHP 5.4 I've been seeing this and the scripts aren't working. Can someone help make this more compliant?
function remove_next_step(q_id,index_number,a_id) {
var confirm_var = confirm('Are you sure you want to remove?');
if(confirm_var) {
var ajax_url = $('#ajax_url').val();
var data = {
action: 'delete_next_step',
index_number:index_number,
question_number:q_id,
answer_id:a_id
};
jQuery.post(ajax_url, data, function(response) {
if(response == 1) {
$('#row_'+q_id+"_"+index_number).remove()
}
});
}
}
specifically, it hates this line:
var ajax_url = $('#ajax_url').val();
Seeing that you reference jQuery.post later in the sample, I'm assuming $ is not referencing window.jQuery so that selector function would not be defined.
Try changing your culprit line to var ajax_url = jQuery('#ajax_url').val();
If that doesn't work, ensure jQuery is loaded - in the head, add this:
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I am new to working with AJAX and have some experience with Java/Jquery. I have been looking around for an solution to my problem but i cant seem to find any.
I am trying to build a function in a webshop where the product will appear in a popup window instead of loading a new page.
I got it working by using this code:
$(".product-slot a").live('click', function() {
var myUrl = $(this).attr("href") + " #product-content";
$("#product-overlay-inner").load(myUrl, function() {
});
$("#product-overlay").fadeIn();
return false;
});
product-slot a = Link to the product in the category page.
product-content = the div i want to insert in the popup from the product page.
product-overlay-inner = The popup window.
product-overlay = The popup wrapper.
The problem that i now have is that my Javascript/Jquery isnt working in the productpopup. For example the lightbox for the product image or the button to add product to shoppingcart doesnt work. Is there anyway to make the javascript work inside the loaded content or to load javascript into the popup?
I hope you can understand what my problem is!
Thank you in advance!
EDIT: The platform im using has jquery-ui-1.7.2
I know this is an old thread but I've been working on a similar process with the same script loading problem and thought I'd share my version as another option.
I have a basic route handler for when a user clicks an anchor/button etc that I use to swap out the main content area of the site, in this example it's the ".page" class.
I then use a function to make an ajax call to get the html content as a partial, at the moment they are php files and they do some preliminary rendering server side to build the html but this isn't necessary.
The callback handles placing the new html and as I know what script I need I just append it to the bottom in a script tag created on the fly. If I have an error at the server I pass this back as content which may be just a key word that I can use to trigger a custom js method to print something more meaningful to the page.
here's a basic implementation based on the register route handler:
var register = function(){
$(".page").html("");
// use the getText ajax function to get the page content:
getText('partials/register.php', function(content) {
$(".page").html(content);
var script = document.createElement('script');
script.src = "js/register.js";
$(".page").append(script);
});
};
/******************************************
* Ajax helpers
******************************************/
// Issue a Http GET request for the contents of the specified Url.
// when the response arrives successfully, verify it's plain text
// and if so, pass it to the specified callback function
function getText(url, callback) {
var request = new XMLHttpRequest();
request.open("GET", url);
request.onreadystatechange = function() {
// if the request is complete and was successful -
if (request.readyState === 4 && request.status === 200) {
// check the content type:
var type = request.getResponseHeader("Content-Type");
if (type.match(/^text/)) {
callback(request.responseText);
}
}
};
// send it:
request.send(null); // nothing to send on GET requests.
}
I find this a good way to 'module-ize' my code into partial views and separated JavaScript files that can be swapped in/out of the page easily.
I will be working on a way to make this more dynamic and even cache these 'modules' for repeated use in an SPA scenario.
I'm relatively new to web dev so if you can see any problems with this or a safer/better way to do it I'm all ears :)
Yes you can load Javascript from a dynamic page, but not with load() as load strips any Javascript and inserts the raw HTML.
Solution: pull down raw page with a get and reattach any Javascript blocks.
Apologies that this is in Typescript, but you should get the idea (if anything, strongly-typed TypeScript is easier to read than plain Javascript):
_loadIntoPanel(panel: JQuery, url: string, callback?: { (): void; })
{
// Regular expression to match <script>...</script> block
var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
var scripts: string = "";
var match;
// Do an async AJAX get
$.ajax({
url: url,
type: "get",
success: function (data: string, status: string, xhr)
{
while (match = re.exec(data))
{
if (match[1] != "")
{
// TODO: Any extra work here to eliminate existing scripts from being inserted
scripts += match[0];
}
}
// Replace the contents of the panel
//panel.html(data);
// If you only want part of the loaded view (assuming it is not a partial view)
// using something like
panel.html($(data).find('#product-content'));
// Add the scripts - will evaluate immediately - beware of any onload code
panel.append(scripts);
if (callback) { callback(); }
},
error: function (xhr, status, error)
{
alert(error);
}
});
}
Plain JQuery/Javascript version with hooks:
It will go something like:
var _loadFormIntoPanel = function (panel, url, callback) {
var that = this;
var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
var scripts = "";
var match;
$.ajax({
url: url,
type: "get",
success: function (data, status, xhr) {
while(match = re.exec(data)) {
if(match[1] != "") {
// TODO: Any extra work here to eliminate existing scripts from being inserted
scripts += match[0];
}
}
panel.html(data);
panel.append(scripts);
if(callback) {
callback();
}
},
error: function (xhr, status, error) {
alert(error);
}
});
};
$(".product-slot a").live('click', function() {
var myUrl = $(this).attr("href") + " #product-content";
_loadFormIntoPanel($("#product-overlay-inner"), myUrl, function() {
// Now do extra stuff to loaded panel here
});
$("#product-overlay").fadeIn();
return false;
});
I'm having trouble reading this xml with jQuery.
http://jsfiddle.net/VLtqY/2/
XML:
<myElements type="AA" coID="A923">
<element1>01</element1>
<element2>02</element2>
<element3>03</element3>
</myElements>
I'm looking for the following output:
element1=01
element2=02
element3=03
A little help please.
First, you need to wrap your xml variable in a call to the jQuery function, as in $(xml). Then, a call to children() will get all of your target elements.
Here's a very basic (and sloppy), working example of iterating through the elements, but it's just the selector that needs changing:
var xml = '<myElements type="AA" coID="A923"><element1>01</element1> <element2>02</element2><element3>03</element3></typeData>';
var myOutput = $("#output");
myOutput.append("=== start ===<br />");
$(xml).children().each(function () {
var xmlnode = $(this);
myOutput.append(this.tagName + xmlnode.text() + '<br/>');
});
myOutput.append("=== end ===");
Working demo: http://jsfiddle.net/UByfW/2/
Try this
$('*', xml).each(function () {
replacing the the line
$(xml).find("myElements").each(function () {
or
$(xml).children().each(function () {
The reason is self-explanatory: you must fetch the children, not the root element.
You can use the jQuery parseXML (see docs) function to parse the string of XML into an XML document object. Just add this line somewhere between the variable declaration and your each loop:
xml = $.parseXML(xml);
The rest of it should work fine then. You can see an example here.
I would really suggest ajax for this. IE hates the way jquery grabs the xml.I have been using this for a very long time with lots of success and no problems.
$.ajax({
url: "path-to-file.xml",
dataType: ($.browser.msie) ? "text" : "xml",
success: function(data){
var xml;
if (typeof data == "string") {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
alert($(xml).find('element1').text());
alert($(xml).find('element2').text());
alert($(xml).find('element3').text());
},//END SUCCSESS
error: function(){
alert("Sorry, There was an error loading this information. Refresh the page or try again later. ");
history.go(-1);
}
});//END AJAX CALL
I know this looks like a lot, but it really isn't that bad. Put your path to your xml, in the .each() do what you want to do.
I am using jQuery to grab some JSON and then plug it into some elements and display it on my page.
It works fine on all pages except one, where the response seems to be the page itself.
I have placed alert()s in the callbacks (success and complete) and they never seem to be fired (though Firebug shows the request returning 200 OK which should trigger the success handler).
I don't know what to do, I've never encountered this before.
Here is the jQuery code I am using:
var specials = (function() {
var specials = false,
specialsAnchor;
var init = function() {
specialsAnchor = $('#menu-specials a');
specialsAnchor.click(function(event) {
event.preventDefault();
if (specials != false && specials.is(':visible')) {
hide();
} else {
show();
}
});
};
var load = function(callback) {
specialsAnchor.addClass('loading');
specials = $('<div />', { 'id': 'specials' }).hide().appendTo('#header');
var specialsUl = $('<ul />').appendTo(specials);
$.ajax(specialsAnchor.attr('href'), {
dataType: 'json',
success: function(data) {
$.each(data, function(i, special) {
specialsUl.append('<li><h4>' + special.heading + '</h4><p>' + special.content + '</p></li>');
});
specialsAnchor.removeClass('loading');
callback.call();
}
});
}
var show = function() {
if (specials == false) {
load(show);
return;
}
specials.slideDown(500);
}
var hide = function() {
specials.slideUp(500);
}
$(init);
})();
What is going on?
I noticed that you're including jquery.validate on this page, but not the others. jQuery validate with jQuery > 1.5 causes some issues with AJAX calls.
I realize the linked question/answer aren't exactly what you're seeing, but I've seen all kinds of weird issues with AJAX calls and this combination of validate and jQuery, so I figured it would be worth mentioning.
Hope that helps.
This is probably not a complete answer, but could be a step in the right direction. Using Charles Proxy it seems on your other pages when I click specials, it makes a request to http://www.toberua.com/~new/specials however on the contact-us page the ajax request is instead going to http://www.toberua.com/~new/contact-us (which of course is not json)
One other interesting note:
The XMLHttpRequest on other pages sets the Accept header properly (i.e. Accept application/json, text/javascript, */*; q=0.01 , whereas on the contact-us page it is set to Accept */*). I'd bet there's a different code branch being invoked...
hoping some one can shed some light on my problem. Basicly I only want to execute a block of code if a certain DOM element exists. If it does I then perform a few bits and bobs and then call a function. However it complains that the function is not defined, suggesting that the function is not in scope. Below is the code :
$(document).ready(function ()
{
if ((document.getElementById("view<portlet:namespace/>:editSplash")!= null)) {
console.log("notifications scripted started");
// hide loading box/ notify on body load
$('.ajaxErrorBox').hide();
$('.loadingNotifications').hide();
$('.notifyWindow').hide();
getFeed();
// set up refresh button for reloading feed
$('.refreshFeed').click(function() {
$('.notifyWindow').hide();
$('.notifyWindow').empty();
console.log("notifications clicked");
getFeed();
});
// begin ajax call using jquery ajax object
function getFeed ()
{
$('.notifyWindow').empty();
console.log("ajax call for feed starting");
$.ajax ({
type: "GET",
url: "http://cw-pdevprt-05.tm-gnet.com:10040/notificationsweb/feed?username=uid=<%# taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %><wps:user attribute="uid"/>",
dataType: "text/xml",
timeout: 10000,
success: parseXml
});
};
// show loading box on start of ajax call
$('.notifyWindow').ajaxStart(function() {
$('.refreshFeed').hide("fast");
$('.notifyWindow').hide();
$('.ajaxErrorBox').hide();
$('.loadingNotifications').show("fast");
});
// hide loading box after ajax call has stopped
$('.notifyWindow').ajaxStop(function() {
$('.loadingNotifications').hide("slow");
$('.refreshFeed').show("fast");
});
$('.notifyWindow').ajaxError(function() {
$('.loadingNotifications').hide("slow");
$('.ajaxErrorBox').show("fast");
$('.refreshFeed').show("fast");
});
// parse the feed/ xml file and append results to notifications div
function parseXml (xml) {
console.log("xml parsing begining");
if (jQuery.browser.msie)
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
$(xml).find("entry").each(function()
{
var $item = $(this);
var title = $item.find("title").text();
var linkN = $item.find("link").attr("href");
var output = "<a href='" + linkN + "' target='_self'>" + title + "</a><br />";
$(".notifyWindow").append($(output)).show();
});
}
}
else {
console.log("notifications not available");
return false;
}
});
If the DOM element exists I then try and call the getFeed function "getFeed();" however it comes back undefined. If anyone could shed some light on this it would be greatly appreciated.
Thanks in advance
It seems that you're calling getFeed before it is defined. Try moving the if statement to after the function definition. Note that this behaviour is actually implementation specific, so some browsers may work this way and some may not.
Oh - And seriously? view<portlet:namespace/>:editSplash for an id?
Problem solved - I moved my functions outside of the if statement. We live and learn lol :-)