preventDefault of a link depending on the Ajax response - javascript

I've created a controller in Magento which check whether or not there are products in a list. If there are products in list it will return true otherwise false.
Here is the front-end which triggers the ajax call, bare in mind I can not change this to be a form. It has to be a link.
Compare Products
Here is the ajax call.
jQuery(".compare-product-link").on("click", function(e) {
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed != true) {
e.preventDefault();
}
}
});
});
The problem I have is that the async is deprecated and is not good for user experience, saying that there are many answer out there which add a delay of 3 seconds, I also don't want that because thats not good for user experience.
I've also tried using a promise call but it only works with async : false.
jQuery(".compare-product-link").on("click", function(e) {
var response = false;
jQuery.ajax({
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
console.log(data);
if(data.isAllowed) {
response = true;
}
}
}).done(function (){
console.log(response);
if(response != true) {
e.preventDefault();
}
});
});
EDIT
Another problem I also have is if I store the link into a variable and then open a new window as so window.location = href; most browser will block it and users will have to manually accept pop ups from the target site, which again is not good for user experience.

you cannot really achieve this using preventDefault like you said - because of async.
what I would try is:
preventDefault
store href as a variable
call ajax
redirect to href variable if true and not if false
jQuery(".compare-product-link").on("click", function(e) {
var href = $(this).attr('href');
e.preventDefault();
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed == true) {
window.location = href;
}
}
});
});
if you need to create a link action you can use this code:
function triggerClick(url){
$('body').append('<span id="click_me_js"></span>');
$('span#click_me_js a')[0].click();
$('span#click_me_js').remove();
}
which will mimic a regular click on <a>

Related

Jquery - Ajax : Unhandled multiple clicks event with ajax button "on Click method"

I have a button where i'm injecting an ajax request to a distant web service.
the traitment takes effects after checking a condition given from the success of another ajax request (thats why i am usung "ajaxSuccess")
My fonction looks like this :
$('body').on('click', '#btn', function (e) {
$(document).ajaxSuccess(function (event, xhr, settings) {
if (settings.url === window.annonce.route.testService) {
xhr = xhr.responseJSON;
var msg = {},
if (xhr == 1) { //case of traitement to be done
msg["attr1"] = attr1;
msg["attr2"] = attr2;
msg = JSON.stringify(msg);
console.log(msg);
$.ajax({
method: 'POST',
url: servicePostulation,
data: {msg: msg},
dataType: 'json',
success: function (data) {
console.log(data);
$("#btn").addClass("active");
},
error: function (data) {
console.log(data);
}
});
}
}
})
}
I my case , the "console.log(msg)" shows me a multiple sending of data msg , which means a multiple clicking events , and that's exactly the problem i wanna evitate,
i have tried many solutions with the " $('body').on('click') like :
e.stopImmediatePropagation();
e.preventDefault();
stopPropagation()
one()
off()
unbind()
but nothing works , so is there any further solution or explication ??
My suggest is to disable the button when user click and then enable the button when ajax complete.
**onClick:**
$('#btn').prop("disabled", true);
Ajax complete/success:
$('#btn').prop("disabled", false);

jQuery Anchor Clicked triggered by multiple times

Here is the scenario:
I am sending ajax request when user click on anchor tag to fecht & update instagram media status.
But it take sometime to retrieve the response, in that time user clicked N number of time on that anchor tag.
So each time it sends the request, I am don't want such behaviour ..
Is there any easy way to handle such situation?
Currently I am adding the class when user clicked on it, and using that I am deciding user has click on anchor tag or not??
Please let me know, if it is correct way or not..
Here is fiddle URL (Not clicked on link at least 2+ times, it send 2+ request which is i don't want )
http://jsfiddle.net/bkvaiude/mxb8x/
thanks
You should use should remove the click event and then set it up again when the ajax call is complete:
Instead of setting it in the success call as the others do; you should use the complete callback to set it. To make sure if the server returns an error it is still binding the click event again.
http://jsfiddle.net/eWwZt/
(function (){
console.log("bhushan");
var ajaxCall = function(e){
$("#test").off("click");
console.log("click");
e.preventDefault();
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function(data) {
console.log("data...");
},
complete: function(){
$("#test").on("click", ajaxCall);
}
});
}
$("#test").on("click", ajaxCall);
})();
Put a flag to check if ajax call completed or not this way:
(function (){
var RequestInProgress = false;
console.log("bhushan");
$("#test").on("click", function(e){
e.preventDefault();
if(!RequestInProgress) // if request not in progress send
{
RequestInProgress = true;
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function(data) {
console.log("data...");
RequestInProgress = false;
}
});
}
});
})();
UPDATED FIDDLE
You can use .off() to unbind click to element.
(function () {
console.log("bhushan");
var Myfunction = function (e) {
$("#test").off("click"); //Unbind click
e.preventDefault();
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function (data) {
console.log("data...");
$("#test").on("click", Myfunction);
}
});
};
$("#test").on("click", Myfunction);
})();
DEMO
try this
var gettingData =false;
$('selector').click(function() {
gettingData = false;
if (!gettingData) {
gettingData =true;
$.ajax(//do ajax logic)
.success(
gettingData = false;
//parse data)
.error(
gettingData = false;
//display some error
);
} else {
return false;
}
});

jQuery modal dialog and ASP.NET postback

I have a modal dialog on my page using jQuery that a user enters a password into.
It's a standard jQuery dialog and it works fine. I have linkbuttons in a datagrid that open the dialog using this code:
$('.needsVal').click(function () {
$("#login1").dialog('open');
id = $(this).attr('id');
return false;
});
The problem is later on in the page I make an Ajax call, and based on the value returned, I want to selectively fire a postback for the page. The problem is the postback never fires. My postback code is as follows:
if (returnValue == "true") {
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(id, "", false, "", "", false, true));
return true;
}
else {
alert("Authentication failure!\nPlease check your password and try again.");
return false;
For some reason I can't get the postback to work with the modal dialog, and it's driving me nuts. I had this working with a regular Javascript prompt, but I had to change it because there's no way to mask the password in a prompt.
Any thoughts on how to get the postback to work?
id is a global variable that has the unique ID of the clicked button. I've confirmed that's being passed properly.
I managed to get this to work.
What I found was there are two ASP.NET controls on the page - two gridviews, one with regular linkbuttons and another with a linkColumn.
Because of the way the linkbuttons work in the two types of controls (linkbutton vs. commandbutton) I had to vary how I open the form, and how I interact with the prompt. I had to create two different events. (Maybe there's a way to do it with one, but I couldn't figure it out)
What I finally wound up with jQuery wise:
//Click event for gridview 1 (standard linkbutton)
$('.needsVal').click(function () {
$("#login1").dialog('open');
id = $(this).attr('id');
return false;
});
//Click event for second gridview (command button)
$('.needsValSideMenu').click(function () {
var h = $(this).html();
script = h.substring(h.indexOf("\"") + 1, h.indexOf("\">"));
$("#login2").dialog('open');
return false;
});
//AJAX call for standard linkbutton grid
function checkPassword() {
var returnValue;
$.ajax({
async: false,
type: "POST",
url: "myservice.asmx/Authenticate",
data: { "password": pw.value },
dataType: "xml",
error: function () { alert("Unexpected Error!"); },
success: function (msg) {
returnValue = $(msg).find('boolean').text()
}
});
if (returnValue == "true") {
//alert(id.replace("_", "$"));
id = id.split("_").join("$");
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(id.replace("_","$"), "", true, "", "", false, true));
}
else {
alert("Authentication failure!\nPlease check your password and try again.");
}
}
//Call for second grid (command button) - need to get and execute the script associated with this button
function checkPasswordSideMenu() {
var returnValue;
$.ajax({
async: false,
type: "POST",
url: "myservice.asmx/Authenticate",
data: { "password": pw2.value },
dataType: "xml",
error: function () { alert("Unexpected Error!"); },
success: function (msg) {
returnValue = $(msg).find('boolean').text()
}
});
if (returnValue == "true") {
eval(script);
}
else {
alert("Authentication failure!\nPlease check your password and try again.");
}
}
I couldn't think of a way to do this in one method since I need to call a different checkPassword routine depending on which type of button was clicked.

jquery beforeunload when closing (not leaving) the page?

How can I display "Are you sure you want to leave the page?" when the user actually tries to close the page (click the X button on the browser window or tab) not when he tries to navigate away from the page (click on another link).
My client wants a message to appear when the user tries to close the page "Are you sure you want to leave the page? You still have items in your shopping cart."
Unfortunately $(window).bind('beforeunload') doesn't fire only when the user closes the page.
jQuery:
function checkCart() {
$.ajax({
url : 'index.php?route=module/cart/check',
type : 'POST',
dataType : 'json',
success : function (result) {
if (result) {
$(window).bind('beforeunload', function(){
return 'leave?';
});
}
}
})
}
You can do this by using JQuery.
For example ,
click here
Your JQuery will be,
$(document).ready(function(){
$('a').on('mousedown', stopNavigate);
$('a').on('mouseleave', function () {
$(window).on('beforeunload', function(){
return 'Are you sure you want to leave?';
});
});
});
function stopNavigate(){
$(window).off('beforeunload');
}
And to get the Leave message alert will be,
$(window).on('beforeunload', function(){
return 'Are you sure you want to leave?';
});
$(window).on('unload', function(){
logout();
});
This solution works in all browsers and I have tested it.
Try javascript into your Ajax
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
Reference link
Example 2:
document.getElementsByClassName('eStore_buy_now_button')[0].onclick = function(){
window.btn_clicked = true;
};
window.onbeforeunload = function(){
if(!window.btn_clicked){
return 'You must click "Buy Now" to make payment and finish your order. If you leave now your order will be canceled.';
}
};
Here it will alert the user every time he leaves the page, until he clicks on the button.
DEMO: http://jsfiddle.net/DerekL/GSWbB/show/
Credit should go here:
how to detect if a link was clicked when window.onbeforeunload is triggered?
Basically, the solution adds a listener to detect if a link or window caused the unload event to fire.
var link_was_clicked = false;
document.addEventListener("click", function(e) {
if (e.target.nodeName.toLowerCase() === 'a') {
link_was_clicked = true;
}
}, true);
window.onbeforeunload = function(e) {
if(link_was_clicked) {
return;
}
return confirm('Are you sure?');
}
As indicated here https://stackoverflow.com/a/1632004/330867, you can implement it by "filtering" what is originating the exit of this page.
As mentionned in the comments, here's a new version of the code in the other question, which also include the ajax request you make in your question :
var canExit = true;
// For every function that will call an ajax query, you need to set the var "canExit" to false, then set it to false once the ajax is finished.
function checkCart() {
canExit = false;
$.ajax({
url : 'index.php?route=module/cart/check',
type : 'POST',
dataType : 'json',
success : function (result) {
if (result) {
canExit = true;
}
}
})
}
$(document).on('click', 'a', function() {canExit = true;}); // can exit if it's a link
$(window).on('beforeunload', function() {
if (canExit) return null; // null will allow exit without a question
// Else, just return the message you want to display
return "Do you really want to close?";
});
Important: You shouldn't have a global variable defined (here canExit), this is here for simpler version.
Note that you can't override completely the confirm message (at least in chrome). The message you return will only be prepended to the one given by Chrome. Here's the reason : How can I override the OnBeforeUnload dialog and replace it with my own?
Try this, loading data via ajax and displaying through return statement.
<script type="text/javascript">
function closeWindow(){
var Data = $.ajax({
type : "POST",
url : "file.txt", //loading a simple text file for sample.
cache : false,
global : false,
async : false,
success : function(data) {
return data;
}
}).responseText;
return "Are you sure you want to leave the page? You still have "+Data+" items in your shopping cart";
}
window.onbeforeunload = closeWindow;
</script>
You can try 'onbeforeunload' event.
Also take a look at this-
Dialog box runs for 1 sec and disappears?

Magnific popup closes on content click after replacing content

I am using Magnific Popup version 0.8.9.
I am loading content into it via Ajax, and I use a callback for ajaxContentAdded. This callback sets up an event handler for submitting a form that was loaded into the popup, like so:
$('.add-item-btn').magnificPopup({
type: 'ajax',
closeOnContentClick: false,
callbacks: {
ajaxContentAdded: HandleItemFormSubmit
}
});
This works fine, the form submit is handled correctly. The event handler function posts it to the server, which (in case of errors) returns the entire form including error messages.
For this purpose I let it replace the popup's content with the returned form, and setup the submit handler again.
function HandleItemFormSubmit()
{
var popup = this;
// Submit form using ajax
$('form.item-form').submit(function()
{
var data = $(this).serialize();
var url = $(this).attr('action');
$.post(url, data, function(resp)
{
if (resp == 'OK')
{
// All good, close up
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit();
}
});
return false;
});
}
However, despite setting closeOnContentClick to false at two different points, the popup immediately closes when content is clicked after the content was replaced (it does work the first time).
The content in the popup has a single root element by the way.
I hope the author or someone else can help out here, I have no idea what is wrong here.
Thank you very much!
I've found another solution:
$('html').on('submit', '#UR_FORM', function(e) {
e.preventDefault();
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
var magnificPopup = $.magnificPopup.instance;
magnificPopup.items[0].type = "inline";
magnificPopup.items[0].src = response;
magnificPopup.updateItemHTML();
}
});
});
You need to call the HandleItemFormSubmit for the popup object:
HandleItemFormSubmit.call(popup);
Otherwise when you call it the way you do, HandleItemFormSubmit();, the this will be set to window and this will not work as expected.
Update
Use this in the else clause:
if (resp == 'OK')
{
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit.call(popup);
}

Categories