JQuery "undo" an action by calling another function when back clicked - javascript

Is there a way to "undo" a function executed by jQuery when the back button is clicked? For example, my function that I want to execute is named doSomething:
function doSomething(button) {
...clicking the button does something...
}
And I have an undo function that undoes the above function, undoDoSomething:
function undoDoSomething(button) {
....undoes the doSomething function...
}
How do I call the function for the button and then if the back button is clicked right after I execute the function, I can call the undoDoSomething function to undo that function?
I know jQuery History goes back to a previous page saved in history but how do I use that to call a function?

the history api makes this easy: http://jsfiddle.net/Z9dRY/
html:
<button>Increase</button>click back button to decrease
<span id="counter">0</span>
js:
$("button").click(function(){
var count = +$("#counter").text() + 1;
history.pushState({count:count});
$(counter).text(count);
})
$(window).on("popstate",function(e){
if (e.originalEvent.state)
$(counter).text(e.originalEvent.state.count);
})
On each action, add to the history, and then each back button click will undo each change (of course, you have to develop the undo part. In this case, i just stored what the count should be changed to at that point and changed it.)
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Take note of the browser support, this code will work in all modern browsers and IE10+. oldIE will need a workaround either using an iframe or a hash in the url.
Here's the same example with an added decrease button to show that it doesn't really change anything: http://jsfiddle.net/Z9dRY/1/ it even inherantly supports the forward button(redo).
Update: fixed losing initial state: http://jsfiddle.net/Z9dRY/2/

You could call your undo function on the window.unload event
window.onbeforeunload = function(e) {
undoDoSomething();
};

You can usue beforeunload that is executed when leaving the page
var called = false;
function doSomething(button) {
called = true;
}
$(window).on('beforeunload',function(e){
if(called){
//call your function here
undoDoSomething()
}
});

Related

jQuery onclick call function

I've found a script that converts json file into quiz using jquery.
I am playing with it's code for almost a day now and I can't come with what I wanted to have.
Functions quiz().init(); and quiz().bindSubmit(); are called when page loaded.
What I want is the START button must be clicked first to load the Quiz.
$("#start").click(function(){
currentQuestion = 0;
questionCount = 0;
answerArray = [];
infoMode = false;
gotData = false;
inMemoryData = [];
quiz().init();
quiz().bindSubmit();
});
HTML:
<button type="button" id="start">Start</button>
<div id="quiz-content"></div>
It works at first click of START button also in the next clicks, it successfully reset the quiz and goes back to #1.
But the problem is after the first click of Start Button, the quiz won't work normally when submitting the quiz. The quiz began to stucked in #1.
For better understanding, JSfiddle here.
Edited:
Basically when the user click start button more than once,the quiz gets started from the beginning ,but didn't get to the next question(Gets stuck on the 1st question itself)
When you call bindSubmit function, inside it you are attaching to the submit event of the #quizForm. So when you press Start button twice, there two event handlers attached to the same event and that is because it is not behaving as it should be. So inside the bindSubmit function you need always disconnect all submit handlers ($(document).off('submit');), like this:
var bindSubmit = function () {
$(document).off('submit');
$(document).on('submit', '#quizForm', function (event) {
event.preventDefault();
next(this);
quiz().init();
});
};
Here is your original fiddle with mentioned update
https://jsfiddle.net/t4p8x02b/35/
There are couple of things i observed in your code, which needs to be rectified for better management of code:
There is no need to expose init() outside your quiz library, for first time initialization, you can call init() before your return from the library(end of quiz() module code).
Also exposing init() makes your quiz() module vulnerable since it can be modified by any external program which could spoil your entire quiz() logic.
Inside bindSubmit(), you dont need to re-initialize your quiz instance to call init(), rather just call init()(refer below code snippet), your event handler will call it without any error [This is the magic of Closure].
bindSubmit():
$(document).on('submit', '#quizForm', function (event) {
event.preventDefault();
next(this);
init();
});

How to capture the Print Event?

Note :- Here Check = Cheque ( In USA cheque is spelled as check )
In a website, we've given the functionality to print the check to super-admin.
Super-admin can print the check by clicking on print button.
After clicking on the print button, it generates a popup to complete the action. Also, there are two events named as print and cancel(This is browser specific).
When super-admin clicks on the print event, then check comes out with all the details and all the orders belonging to the same check will get paid automatically in DB. When super-admin clicks on cancel, there is no action to be performed.
What we need to do :- We need to capture the event of print and cancel with 100% accuracy in all browsers, because here it's the matter of money (check).
So, I Need help on the way to get cancel and print events.
Why not just call the print() function from within an other function?
Like:
function myPrint() {
$("#myDiv").css({"border-color":"red"});
window.print();
}
Then you could call it from where you need it.
if you need to capture the print event you can use the beforeprint javascript event
Using addEventListener():
window.addEventListener('beforeprint', (event) => {
console.log('Before print');
});
Using the onbeforeprint event handler property:
window.onbeforeprint = (event) => {
console.log('Before print');
};
https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeprint_event

Set variable on back button click

I have a function I dont want to run if the broswer back button was clicked. I am attempting to use something like the below:
var backButtonClicked = false;
window.onpopstate = function() {
alert("Back clicked");
backButtonClicked = true;
};
then later I am trying to use the variable like:
if(!backButtonClicked) {
//run function if not back button clicked
}
However with the code above the alert is not getting fired when I hit the back button.
window.onpopstate = function() {
alert("back clicked");
backButtonClicked = true;
};
history.pushState({}, '');
With the code above the alert gets fired when I click the back button, however the browser doesnt navigate back to the previous page unless I click the back button for the second time. Is there something I am doing incorrect here or is there a better approach to achieve what I am trying to do?
My coding skills are not very good when I have very little time to type. But maybe an eventlistener would be another approach to the problem you can maybe consider?
For examples and reference from an excellent source:
http://www.w3schools.com/js/js_htmldom_eventlistener.asp
Hope this helps, and good luck!

Perform an action after trigger('click') finishes firing?

I manage a SharePoint site and have limited access to the underlying code; I can, however, manipulate things after the page loads via JavaScript. Have been using jQuery and SPServices.
I have a custom button I am adding to a form; it overrides the standard "save" button on the page, so I can perform some other ajax stuff prior to saving/closing. This works fine:
$('#the_save_button').hide();
$("#my_custom_save_button").click(function() {
// do some custom stuff first
$('#the_save_button').trigger('click'); //
window.close();
}
The item saves and the window.close() fires. Great! Now, though, I would rather not close the window but set the window.location.href ... however, when I do that, the page is getting redirected before the trigger('click') is finished firing and my item isn't saving:
$('#the_save_button').hide();
$("#my_custom_save_button").click(function() {
// do some custom stuff first
$('#the_save_button').trigger('click'); //
window.location.href = "/my/new/url.aspx";
}
I've tried using window.setTimout but the $('#the_save_button').trigger('click') has a built-in redirect itself ...
Any ideas on how I can work around this?
Yes, just have your click handler return a deferred object and use it to decide when to redirect.
$("#the_save_button").click(function(e){
e.preventDefault();
return $.ajax({...});
});
Now you can do this:
$("#my_custom_save_button").click(function() {
// do some custom stuff first
$('#the_save_button').triggerHandler('click').done(function(){
window.location.href = "/my/new/url.aspx";
});
});
Note: using triggerHandler instead of trigger in this case is important, triggerHandler allows you to use the returned jqXHR object.

Call a function after form reset

Is there a method for me to call a function after click on the reset button in form, and I mean after, so that the form is first reset and then my function called. Normal event bubbling would call my function and only then reset the form. Now I would like to avoid setTimeout in order to do this.
What I need is to call a function when a form is reset because I use uniform and uniform needs to be updated when values change.
At the moment I do it like this:
//Reset inputs in a form when reset button is hit
$("button[type='reset']").live('click', function(){
elem = this;
//Sadly we need to use setTimeout to execute this after the reset has taken place
setTimeout(function(){
$.each($(elem).parents('form').find(":input"), function(){
$.uniform.update($(this));
});
}, 50);
});
I tried to do al this on $(':input').change() but reseting an element does not seem to trigger the change event.
Thank you in advance for any help.
HTML forms do have an onReset event, you can add your call inside there:
function updateForm()
{
$.each($('form').find(":input"), function(){
$.uniform.update($(this));
});
}
<form onReset="updateForm();">
As pointed out in the comment by Frédéric Hamidi you can also use bind like so:
$('form').bind('reset', function() {
$.each($(this).find(":input"), function(){
$.uniform.update($(this));
});
});
After some testing it appears both ways fire before the reset takes place and not after. The way your doing it now appears to be the best way.
The same conclusion was found in this question here
I haven't yet tested in all browsers, but you can do your own ordering within a click event:
http://jsfiddle.net/vol7ron/9KCNL/1/
$(document).ready(function() {
$("input:reset").click(function() { // apply to reset button's click event
this.form.reset(); // reset the form
window.alert($("input:text").val()); // call your function after the reset
return false; // prevent reset button from resetting again
});
});
Time ago I worked debugging a Google IE related plugin and I solved the main error with a bubbling trick. That's why I think immediately in this solution for your problem (of course should be cross-browser):
<form>
<div id="capture_bubble">
<input type="text"><input type="reset">
</div>
</form>
In this way you can capture the bubbling with $('#capture_bubble') after reset event be triggered.
You can make a quick test with:
(function($) {
$(function() {
$('#capture_bubble').live('click', function(){
console.debug('capture_bubble');
alert('capture_bubble')
})
$("input[type='reset']").live('click', function(){
this.form.reset(); // forcing reset event
console.debug('reset');
alert('reset')
});
});
})(jQuery);
Please note: this.form.reset(); (change made due to a jeff-wilbert observation)
you shouldn't need to wait 50 milliseconds. If you use setTimeout with a timeout of zero, it effectively means "push this code onto the event stack". Since the form-reset is guaranteed to have fired first, the code in the setTimeout is guaranteed (in well behaved javascript interpreters) to have access to the form values you want (post-reset). You should be able to use the code below, guilt-free.
var afterReset = function(){
var pushMeOntoTheEventStack = window.setTimeout(function(){
$("#form input").each(function(){
console.log( this.name + ' = ' + this.value );
});
},0);
};
$("#form").on("reset",afterReset);
Try this solution
Goal:
add on "click" event
prevent the default action (reset)
trigger "reset"
run desired code
Example:
$("button[type='reset']").on('click', function(evt) {
evt.preventDefault();
$(evt.target).trigger('reset');
// enter code to run after reset
$.each($(this).find(":input"), function(){
$.uniform.update($(this));
});
});

Categories