window.onbeforeunload detect if POST or GET - javascript

In the window.onbeforeunload event is there a way to detect if the new request is a POST (on the same page) or a GET (going to a page)? It would also be great to see the new document.location.
window.onbeforeunload = winClose;
function winClose() {
//Need a way to detect if it is a POST or GET
if (needToConfirm) {
return "You have made changes. Are you sure you want?";
}
}

This is how I just did it:
$(document).ready(function(){
var action_is_post = false;
$("form").submit(function () {
action_is_post = true;
});
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (!action_is_post)
return 'You are trying to leave this page without saving the data back to the server.';
}
});

Sounds like something you'd need to attach to a form, or specific links. If the event is raised by a link, and there is a request string full of variables, it will act as a GET. If it's a form, you'll have to check the METHOD, and then figure the URL based on the data being submitted in the form itself.
No method
GET method
<form method="GET" action="thisPage.php">
<!-- This is a GET, according to the method -->
<input type="text" name="usrName" value="jonathan" />
</form>
<form method="POST" action="thisPage.php">
<!-- This is a POST, according to the method -->
<input type="text" name="usrName" value="jonathan" />
</form>
So the detection would take place not in the window method, but in the click method of your links, and form submissions.
/* Check method of form */
$("form").submit(function(){
var method = $(this).attr("method");
alert(method);
});
/* Check method of links...UNTESTED */
$("a.checkMethod").click(function(){
var isGet = $(this).attr("href").get(0).indexOf("?");
alert(isGet);
});

Related

JS - Collecting data from one function to run in another [duplicate]

There seems to be lots of info on how to submit a form using javascript, but I am looking for a solution to capture when a form has been submitted and intercept it in javascript.
HTML
<form>
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
When a user presses the submit button, I do not want the form to be submitted, but instead I would like a JavaScript function to be called.
function captureForm() {
// do some stuff with the values in the form
// stop form from being submitted
}
A quick hack would be to add an onclick function to the button but I do not like this solution... there are many ways to submit a form... e.g. pressing return while on an input, which this does not account for.
Ty
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
In JS:
function processForm(e) {
if (e.preventDefault) e.preventDefault();
/* do what you want with the form */
// You must return false to prevent the default form behavior
return false;
}
var form = document.getElementById('my-form');
if (form.attachEvent) {
form.attachEvent("submit", processForm);
} else {
form.addEventListener("submit", processForm);
}
Edit: in my opinion, this approach is better than setting the onSubmit attribute on the form since it maintains separation of mark-up and functionality. But that's just my two cents.
Edit2: Updated my example to include preventDefault()
You cannot attach events before the elements you attach them to has loaded
It is recommended to use eventListeners - here one when the page loads and another when the form is submitted
This works since IE9:
Plain/Vanilla JS
// Should only be triggered on first page load
console.log('ho');
window.addEventListener("DOMContentLoaded", function() {
document.getElementById('my-form').addEventListener("submit", function(e) {
e.preventDefault(); // before the code
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
})
});
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
jQuery
// Should only be triggered on first page load
console.log('ho');
$(function() {
$('#my-form').on("submit", function(e) {
e.preventDefault(); // cancel the actual submit
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
Not recommended but will work
If you do not need more than one event handler, you can use onload and onsubmit
// Should only be triggered on first page load
console.log('ho');
window.onload = function() {
document.getElementById('my-form').onsubmit = function() {
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
// You must return false to prevent the default form behavior
return false;
}
}
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
<form onSubmit="return captureForm()">
that should do. Make sure that your captureForm() method returns false.
Another option to handle all requests I used in my practice for cases when onload can't help is to handle javascript submit, html submit, ajax requests.
These code should be added in the top of body element to create listener before any form rendered and submitted.
In example I set hidden field to any form on page on its submission even if it happens before page load.
//Handles jquery, dojo, etc. ajax requests
(function (send) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
XMLHttpRequest.prototype.send = function (data) {
if (isNotEmptyString(token) && isNotEmptyString(header)) {
this.setRequestHeader(header, token);
}
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
//Handles javascript submit
(function (submit) {
HTMLFormElement.prototype.submit = function (data) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(this);
submit.call(this, data);
};
})(HTMLFormElement.prototype.submit);
//Handles html submit
document.body.addEventListener('submit', function (event) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(event.target);
}, false);
Use #Kristian Antonsen's answer, or you can use:
$('button').click(function() {
preventDefault();
captureForm();
});

How to close popup window after clicking on submit button without page reload?

I have a Script to open one popup with form(for comparing the input field value with one fixed code) on page load & after clicking on the submit button need to close popup without page reload. Here is my code.
"Html form code"
<form method="post" onsubmit="return checkCode(this);">
<div class="form-group">
<input type="text" required class="form-control" placeholder="Name" name="name">
</div>
<input type="submit" name="save" class="btn btn-primary">
</form>
"Script Code"
"popup script"
<script type='text/javascript'>
$(function () {
var overlay = $('<div id="overlay"></div>');
overlay.show();
overlay.appendTo(document.body);
$('.popup').show();
$('.close').click(function () {
$('.popup').hide();
overlay.appendTo(document.body).remove();
return false;
});
});
</script>
"comparing function code"
<script type="text/javascript" language="JavaScript">
function checkCode(theForm) {
if (theForm.name.value != 'SS-2018') {
alert('Code not matched!');
return false;
} else {
return true;
}
}
</script>
Please check this & help me to get it working correctly. Everything is working correctly I just want on click submit page don't reload simply close the popup window & keep on the same page.
Thanks & Regards
Cue
I'm assuming the HTML that you have there is inside of your popup or overlay. It's a bit hard to tell.
If you want to submit the form without reloading or changing the page, you'll have to use some form of AJAX. Since it looks like you are using jQuery, you can use their ajax() function.
To get the data of the form itself, you can use their serialize() function to scoop the data up into a POJO (plain old JavaScript object).
You would do this on whatever makes sense to call submit. You could probably do it instead of your return true in your checkCode() function (and always return false).
It'd be something like this:
<script type="text/javascript" language="JavaScript">
function checkCode(theForm) {
if (theForm.name.value != 'SS-2018') {
alert('Code not matched!');
} else {
$.ajax('http://example.com/post/location', { method: 'post', data: $(theForm).serialize() })
.then(response => { /* do something with response */ })
.catch(err => { /* handle error */ });
}
return false;
}
</script>

Linking using jquery

I have a form which I display when someone clicks a button using the onclick="", and if they submit it, and the information is all correct, then they are redirected to the another page, however if the information is incorrect then the errors are displayed. My problem is people always have to click the button to show the form to even show the error, is there a way I can do mysite/index.php# show_form_by_default Or something that I can redirect to so that they can view the form without having to click it assuming there are errors in it.
<a id="button1" class="submit" onclick="$('#form').show('slow'); $(this).hide('slow');">Form</a></p>
<div class="box" id="form" style="text-align: center; display: none;">
<form class="notice" action="form.php" method="post">
form stuff here
</form>
</div>
Basically if there a way to display the form via the URL by default?
try this:
<script type="text/javascript">
$(document).ready(function(){
var hash = window.location.hash.toLowerCase();
if(hash == "#show_form_by_default")
{
$('#button1').hide();
$('#form').show();
}
});
</script>
If you want to monitor for changes in the hash (i.e a link on the same page that sets the hash without navigating away you can use the following code:
<script type="text/javascript>
$(document).ready(checkHash);
var oldHash = null;
function checkHash()
{
var hash = window.location.hash.toLowerCase();
if(oldHash != hash)
{
if(hash == "#show_form_by_default")
{
$('#button1').hide();
$('#form').show();
}
oldHash = hash;
}
setTimeout(checkHash, 100);
}
</script>
Modify the timeout interval to be as long or as short as you like depending on how often you want it to check for changes.

Response from AJAX request is only displayed once

I've got some code that sends an ajax request when a form is being submitted. This works the first time the form is submitted (it's a search module), but only once. I've added an effect to highlight the table when data is returned, and you can only see it once (the data changes only once as well).
When I look at the response in the chrome dev tools, I can see it contains the data of the new search query but this isn't shown. Why can I only display results once?
JS:
$(function () {
// Creates an ajax request upon search form submit
var ajaxFormSubmit = function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-nn-target"));
var $newHtml = $(data);
$target.replaceWith($newHtml);
$newHtml.effect("highlight");
});
// Prevent default action
return false;
};
$("form[data-nn-ajax='true']").submit(ajaxFormSubmit);
});
HTML:
<form method="GET" action="#Url.Action("Index", "Show")" data-nn-ajax="true" data-nn-target="#contentlist" class="form-search">
<div class="input-append mysearch">
<input type="search" class="span5 search-query" name="query" data-nn-autocomplete="#Url.Action("AutoComplete")" />
<input type="submit" class="btn" value="Search" />
</div>
</form>
<div id="contentlist">
#Html.Partial("_Shows", Model)
</div>
I think you should use html() instead of replaceWith() method:
$target.html($newHtml);
just an idea... try
$target.html(data);
instead of
$target.replaceWith($newHtml);
By replaceWith, you might actually remove the div that you want to fill your content in. Then, the second time, it doesnt find the div to insert the content into.

Intercept a form submit in JavaScript and prevent normal submission

There seems to be lots of info on how to submit a form using javascript, but I am looking for a solution to capture when a form has been submitted and intercept it in javascript.
HTML
<form>
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
When a user presses the submit button, I do not want the form to be submitted, but instead I would like a JavaScript function to be called.
function captureForm() {
// do some stuff with the values in the form
// stop form from being submitted
}
A quick hack would be to add an onclick function to the button but I do not like this solution... there are many ways to submit a form... e.g. pressing return while on an input, which this does not account for.
Ty
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
In JS:
function processForm(e) {
if (e.preventDefault) e.preventDefault();
/* do what you want with the form */
// You must return false to prevent the default form behavior
return false;
}
var form = document.getElementById('my-form');
if (form.attachEvent) {
form.attachEvent("submit", processForm);
} else {
form.addEventListener("submit", processForm);
}
Edit: in my opinion, this approach is better than setting the onSubmit attribute on the form since it maintains separation of mark-up and functionality. But that's just my two cents.
Edit2: Updated my example to include preventDefault()
You cannot attach events before the elements you attach them to has loaded
It is recommended to use eventListeners - here one when the page loads and another when the form is submitted
This works since IE9:
Plain/Vanilla JS
// Should only be triggered on first page load
console.log('ho');
window.addEventListener("DOMContentLoaded", function() {
document.getElementById('my-form').addEventListener("submit", function(e) {
e.preventDefault(); // before the code
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
})
});
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
jQuery
// Should only be triggered on first page load
console.log('ho');
$(function() {
$('#my-form').on("submit", function(e) {
e.preventDefault(); // cancel the actual submit
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
Not recommended but will work
If you do not need more than one event handler, you can use onload and onsubmit
// Should only be triggered on first page load
console.log('ho');
window.onload = function() {
document.getElementById('my-form').onsubmit = function() {
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
// You must return false to prevent the default form behavior
return false;
}
}
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
<form onSubmit="return captureForm()">
that should do. Make sure that your captureForm() method returns false.
Another option to handle all requests I used in my practice for cases when onload can't help is to handle javascript submit, html submit, ajax requests.
These code should be added in the top of body element to create listener before any form rendered and submitted.
In example I set hidden field to any form on page on its submission even if it happens before page load.
//Handles jquery, dojo, etc. ajax requests
(function (send) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
XMLHttpRequest.prototype.send = function (data) {
if (isNotEmptyString(token) && isNotEmptyString(header)) {
this.setRequestHeader(header, token);
}
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
//Handles javascript submit
(function (submit) {
HTMLFormElement.prototype.submit = function (data) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(this);
submit.call(this, data);
};
})(HTMLFormElement.prototype.submit);
//Handles html submit
document.body.addEventListener('submit', function (event) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(event.target);
}, false);
Use #Kristian Antonsen's answer, or you can use:
$('button').click(function() {
preventDefault();
captureForm();
});

Categories