Here is the script. It works fine in all other browsers, so I thought it was a cache problem but not really. I have been banging my head for hours and nothing is working.
$.ajaxSetup({
cache: false
});
$("#send").live('click', function () {
console.log("AAAAA");
$("#loader").show();
$form = $('#reservationForm');
$inputs = $form.find('input[name^="entry"]'),
serializedData = $('#reservationForm :input[name^="entry"]').serialize();
console.log(serializedData);
serializedData += "&pageNumber=0&backupCache=1&submit=Submit";
// fire off the request to /form.php
$.ajax({
url: "https://docs.google.com/spreadsheet/formResponse?formkey=d",
// url: "https://docs.google.com/spreadsheet/formResponse?formkey=d;ifq",
type: "post",
data: serializedData,
// callback handler that will be called on success
success: function (response, textStatus, jqXHR) {
// log a message to the console
console.log("Hooray, it worked!");
$("#loader").hide();
document.getElementById('error<?php echo"$uname";?>').innerHTML = error;
$("#success").fadeIn();
setTimeout(function () {
$("#success").fadeOut();
}, 5000);
},
// callback handler that will be called on error
error: function (jqXHR, textStatus, errorThrown) {
// log the error to the console
console.log("The following error occured: " + textStatus, errorThrown);
alert('Due to an unknown error, your form was not submitted, please resubmit it or try later.');
},
// callback handler that will be called on completion
// which means, either on success or error
complete: function () {
// enable the inputs
$inputs.removeAttr("disabled");
}
});
// prevent default posting of form
event.preventDefault();
});
console.log is available after you open Developer Tools (F12 to open) in IE. Try turning it on or use an alert instead in your code.
or use a try catch;
try{
console.log('worked')
}
catch(err){
}
And You might want to check if your event variable is undefined:
event= event || window.event;
event.preventDefault();
At the beginning of the script you are not adding the "event" declaration in the handler:
$("#send").live('click', function () {
should be:
$("#send").live('click', function (e) {
And at the end of the script there is a reference for the variable event:
// prevent default posting of form
event.preventDefault();
I think that IE doesn't have a 'preventDefualt' function in the global event object (which you are referencing): this function is added to the "e" event object passed by jQuery. Any way, it should fail too in all other browsers with a "event is not defined". Try this too:
// prevent default posting of form
e.preventDefault();
An additional note: jQuery team currently discourage the use of the "live" event binding function, instead you should use the equivalent form of the "on" function.
IE doesn't understand the content type of response in ajax. So put your dataType value in the request and it should work.
for e.g. -
dataType: ($.browser.msie) ? "text" : "xml"
Related
I am trying to communicate with a server using JSONP call back.
Here is my code
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
cache: false,
timeout: 40000,
crossDomain:true,
jsonp: "MyCallbackFunction",
});
});
function MyCallbackFunction(data)
{
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
The issue here is that I keep getting this message in the console
ReferenceError: MyCallbackFunction is not defined
I do have this defined as you can see in my code above
The server respond looks like this
MyCallbackFunction("{'URL': 'http:\/\/example.com:8106\/ghjgj3835396265336634646562363030303122226D616C686179656B22535353557DBE0C305645E2DE110AA1D7F8792E96A3'}");
how can I correct this issue?
EDITED
This is my code after Quentin Answer , this is my new code
$(function(){
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
timeout: 40000,
success: function(data){
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
});
});
});
Unless you have all of that code wrapped in another function, that should work.
Using a hardcoded function name is bad practise though.
Update:
$(function(){
You do have all that code wrapped in another function.
Remove this:
jsonp: "MyCallbackFunction",
Replace it with:
success: MyCallbackFunction
Or you could put an anonymous function expression there instead (as you have done in your edit)
Let jQuery generate a unique function name (which protects you from race conditions) and allow the server to use the callback query string argument to determine what function name to use.
MyCallbackFunction is in the same scope as the ajax call, so it will be available to the function (which can copy it to a suitably named global).
After you fix that, you have an additional problem:
MyCallbackFunction("{'URL':
Your response is JSON encoded in a JavaScript string, but you are trying to treat it as a JavaScript object.
Either:
Fix the server so it doesn't stringify the JSON or
Run the first argument through JSON.parse
crossDomain:true,
Remove that. It doesn't do anything here. (All it does is, when using XHR (which you aren't using) to the same origin (which you aren't targeting), suppress the custom headers that aren't typically allowed on a cross-origin request so that you can perform an HTTP redirect to a different origin).
cache: false,
That's the default for JSONP requests. Including it is pointless.
return false; //this is critical to stop the click event which will trigger a normal file download!
If you want to stop the click event, then you need to return false from the click event handler function (not the Ajax success handler).
You can't wait until the Ajax function has run and got a response before doing that. Ajax is asynchronous.
I'm using this plugin.
I've rewritten my code to work with the example:
function showRequest(formData, jqForm, options) {
var queryString = $.param(formData);
return true;
}
function showResponse(responseText, statusText, xhr, $form) {
$(".afterSend").removeClass("preloader");
$(".afterSend").empty().append(responseText);
}
$(function() {
$('form.wycena').bind("submit", function(e){
e.preventDefault();
if($('.formBox').hasClass('lightBox')) {
$(".afterSend").empty().addClass("preloader");
$("form.wycena").ajaxForm({
target: '.afterSend',
beforeSubmit: showRequest,
success: showResponse
});
}
else {
/* verify before sending */
toggleLightBox(true);
}
});
});
My code works, but ajaxForm and its callback functions (showRequest, showRespons) seems to do nothing at all. It is supposed to run the script defined in form's action field and show response in the .afterSend div, but I get nothing. Not even a single error in console.
I had a question regarding Ajax loading of html into a DIV. Ideally what I want is this:
A toggle div with close button, which I have the code for here: http://jsfiddle.net/tymeJV/uhEgG/28/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle(function() {
if ($(this).is(":visible")) {
alert("im visible!");
}
});
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
Then I want some AJAX code to load a html file into the div when the div is expanded. The trick is that if the HTML is loaded successfully, I want it to avoid reloading the HTML file again if the div is closed and repoened, since I have already loaded it, and just simply toggle the content in and out with the button. The code I have for this (which I got help on from here is this):
http://jsfiddle.net/spadez/uhEgG/55/
$(function () {
$('#country_link').on('click', function (e) {
// Prevent from following the link, if there is some sort of error in
// the code before 'return false' it would still follow the link.
e.preventDefault();
// Get $link because 'this' is something else in the ajax request.
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true)
return false;
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
$("#country_slide").html('Error');
},
complete: function () {
},
});
});
});
I haven't been able to get this working yet though. So my question is, is it actually possible to do this, and if it is, can anyone with more experience with jquery please help me integrate the div toggle with the ajax loading script.
This is one of my first jquery scripts and I am having a bit of a hard time with it, perhaps it is not for beginners. Thank you.
I edited the fiddle you posted adding the call to slideToogle() where appropriate. Also added a div element to hold the loaded html code.
<div id="country_slide">
Close
<div class=".content"></div> <!-- This is the div I added -->
</div>
You can check the log messages in the console to verify that the code is doing what you expect. The URL for the Ajax call you were doing always returned an error so I changed to the URL that jsfiddle provides for testing: /echo/html/.
Here's the modified JS code:
$(function () {
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
$('#country_link').on('click', function (e) {
e.preventDefault();
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true) {
console.log('Not using Ajax.');
$("#country_slide").slideToggle();
return false;
}
$.ajax({
type: 'GET',
dataType: 'html',
url: '/echo/html/',
timeout: 5000,
beforeSend: function () {
$("#country_slide .content").html('<p>Loading</p>')
},
success: function (data, textStatus) {
console.log('Fecthed with Ajax.');
$("#country_slide .content").html(data);
$("#country_slide").slideToggle();
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
},
complete: function () {
},
});
});
});
I try to make a link fire a javascript function wich fires a ajax call to delete an item.
Like so:
<a class="delete" href="#item.Product.Id">(x)</a>
Clicking the cross caries the id of the product to be deleted.
The only reason the href attribute is there is to carry the value.
$(document).ready(function () {
$('.delete').click(function (e) {
e.preventDefault();
var id = $(this).attr("href");
deleteItem(id);
return false;
});
});
Ajax call: as requested:
function deleteItem(id) {
$.ajax({
url: "/Shoppingcart/RemoveItem",
type: "POST",
data: "id=" + id,
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function () {
$.ajax({
url: "/Shoppingcart/Index",
type: "GET",
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function (result) {
success(result);
}
});
}
});
}
The success function is there to get an updated version of the cart.
And this actually works just fine. However I get a wierd page refresh half way trough the cycle.
I click the link.
the page refreshes and the item is not deleted.
I click the link once more.
the page is not refreshed.
the item is deleted.
Why do I have to click two time and what can I do to resolve this?
The most correct answer is: You don't know what the error is,
because the page is refreshing before you see the error.
Return false prevents the page from refreshing after a click event, but if the code runs into an error before that point...
So you could try to remove the href tag and make it an rel (or something else) tag instead. read that and use it for your AJAX call. give the href a value like # or #removeItem.
This will give you the error your craving for.
Hope this helps!
Usually you get such behavior when page the is quite big and the document.ready event just hasn't fired yet when you click the link. The second time it may load faster (scripts/css already downloaded and coming from cache).
As per my knowledge, have a hidden field or a hidden span to save the "ProductId" and remove the href attribute altogether something like below.
<span id="productIdSpan">#item.Product.Id</span>
<a class="delete"></a>
jQuery:
$(document).ready(function () {
$('.delete').click(function (e) {
var id = $("#productIdSpan").html();
deleteItem(id);
return false;
});
});
EDIT:
Approach-2:
You can store the ProductId in the anchor tag's "title" attribute something like below
jQuery:
$(document).ready(function () {
$(".delete").on("click", function (e) {
deleteItem($(this).attr("title"));
return false;
});
});
This should solve your problem. Hope this helps!!
The correct answer is:
When you add an element to your html after the page is loaded ( for example with AJAX ) and you want to have, in any way, fire an event. You have to rebind the click event to the new element.
When the page is loaded and your javascript and jQuery are loaded. The element isn't their yet so they can't find it or interact with it.
So in my situation:
function addItem(id, amount) {
$.ajax({
url: "/Shoppingcart/AddItem",
type: "POST",
data: "id=" + id + "&amount=" + amount,
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function () {
// Calls for the new update version of the shopping cart.
$.ajax({
url: "/Shoppingcart/Index",
type: "GET",
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function (result) {
//Call the function that changes the html
success(result);
}
});
}
});
}
function success(result) {
$("#shoppingcart").html(result);
//The tricky part: rebinding the new event.
$('.delete').click(function (e) {
e.preventDefault();
var id = $(this).attr("data-id");
deleteItem(id);
return false;
});
}
The delete button did work after a refresh because in that way javascript got reloaded and the element was correctly bound.
I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas.
For the most part, this works great:
$(document.ready(function(){$("text_area").resizer('250px')});
However, because it is only called once when the document is ready, it fails to catch text areas that are later added onto the page using Ajax. I looked at the .live() function, which seems very close to what I'm looking. However, .live() must be bound to a specific event, whereas I just need this to fire once when they're done loading (the onLoad event doesn't work for individual elements).
The only thing I can get working is a really obtrusive inclusion of the JavaScript call directly into the Ajax. Is that the recommended way to be doing this?
Edit: Here is the rails source code for what it does for Ajax requests:
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
var link = $(this);
if (!allowAction(link)) return false;
if (link.attr('data-remote') != undefined) {
handleRemote(link);
return false;
} else if (link.attr('data-method')) {
handleMethod(link);
return false;
}
});
// Submits "remote" forms and links with ajax
function handleRemote(element) {
var method, url, data,
dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
if (element.is('form')) {
method = element.attr('method');
url = element.attr('action');
data = element.serializeArray();
// memoized value from clicked submit button
var button = element.data('ujs:submit-button');
if (button) {
data.push(button);
element.data('ujs:submit-button', null);
}
} else {
method = element.attr('data-method');
url = element.attr('href');
data = null;
}
$.ajax({
url: url, type: method || 'GET', data: data, dataType: dataType,
// stopping the "ajax:beforeSend" event will cancel the ajax request
beforeSend: function(xhr, settings) {
if (settings.dataType === undefined) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
return fire(element, 'ajax:beforeSend', [xhr, settings]);
},
success: function(data, status, xhr) {
element.trigger('ajax:success', [data, status, xhr]);
},
complete: function(xhr, status) {
element.trigger('ajax:complete', [xhr, status]);
},
error: function(xhr, status, error) {
element.trigger('ajax:error', [xhr, status, error]);
}
});
}
So in my particular case, I've got a link, that has data-remote set to true, which points to a location that will return JavaScript instructing a form containing a text area to be appended to my document.
A simple way to do this would be to use ajaxComplete, which is fired after every AJAX request:
$(document).ajaxComplete(function() {
$('textarea:not(.processed)').resizer('250px');
});
That says "every time an AJAX request completes, find all textarea elements that don't have the processed class (which seems to be added by the resizer plugin -- terrible name for its purpose!) and call the resizer plugin on them.
You may be able to optimise this further if we could see your AJAX call.
Generally speaking, I would do it this way..
$.ajax({
type : "GET",
url : "/loadstuff",
success: function(responseHtml) {
var div = $("#containerDiv").append(responseHtml);
$("textarea", div).resizer("250px");
}
});
Wondering if you could use .load for this. For example:
$('text_area').load(function() {
$("text_area").resizer('250px');
});