I have a form with a slider with which somebody can rate a picture. The form should be submitted when the slider is dragged, so "onmousup". This works fine. However, the page should be refreshed so that the rating that the user did is already submitted. This all happens on the index page so that location where the user scrolled to, should not be lost.
I tried to make the slider like this:
<%= f.range_field :score, class:"form-control-range slider", id:"formControlRange", onMouseUp:"submit(); reload(); " %>
...
<script>
function reload() {
console.log("hi");
location.reload;
}
</script>
This way I hoped that when the onMouseUp event happens, the page is first submitted and the page then reloaded, so that the rating the user did is displayed. If I have the slider without the "reload()" function then the form is submitted, but I have to reload manually so that the changes can be displayed.
Somehow, calling having the slider like this doesnt make both functions happen. Only the function that is called first is executed.
I have seen in other threads that having the slider like onMouseUp:"submit() && reload()", but this also doesnt work for me...
Do you have a way to make this work? Or do you have an idea of how the reload thing would be done better.
Thank you so much for your help!
Vincent
UPDATE:
I have looked up a different way, and it actually works when I set a timer for the reload function like this:
function reload() {
console.log("hi");
setTimeout(function()
{
location.reload(); //Refresh page
}, 50);
}
Funny thing now is that it works 50 ms, but not with 5 ms. This points to that it is somehow related with the order. Does anybody know how to tell the code to only reload the page AFTER the form has been submitted?
location.reload is a function, you need to call it as a function:
function reload() {
console.log("hi");
location.reload();
}
But this will not fix the problem by itself, because you are doing a submit and then reload. What if the reload is faster than the operation performed on submit? Then your old state is reloaded. What if the submit operation fails?
If we assume that you keep your current approach, then you need to do the submit and synchronize in some way before you reload (or rerender). If there is an error, display an error.
You can do this with AJAX. Or, if you prefer post and submit, then your server could resend the output as a response to post, which is pretty well handled by the browsers.
I personally prefer to do an AJAX request, handle the response and refresh the parts of the UI that are to be changed.
EDIT
This is how AJAX request can be sent:
function sendRequest(type, url, callback, async, params) {
if (async !== false) async = true;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = callback;
xhttp.open(type, url, async);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(params);
}
call this function, like:
sendRequest("POST", "yoururl", reload, true, yourparams);
Where reload is your function modified as above and yourparams is a set of parameters, like "firstparam=firstvalue&secondparam=secondvalue".
You've typed location.reload, missing () to call a method.
Please post the code of submit() function.
Related
I know this has been asked multiple times on here, but I would like some input.
The web app I'm working on displays a table from a database via Freemarker. It includes a submit button to delete entries from that database. The button works fine for sending requests, but I wanted to have it automatically refresh the page, to show the new table without that entry. I tried this:
<form onsubmit="location.reload()" method="post" action="http://localhost:8080/person/delete/${profile.id};">
<input type="submit" value="Delete"></form>
and this:
<form onsubmit="location.reload()" method="post" action="http://localhost:8080/person/delete/${profile.id};">
<input type="submit" value="Delete"></form>
Neither had any affect. Further research showed me that reload() will refresh the page from the cache, unless forceGet is set to true. I did this for both methods, and saw no difference. Then I thought that it was a case of the page refreshing before it could get the updated information from the server, so I had it wait 100 ms:
<script>
function reloadPage() {
setTimeout(function () {
location.reload();
}, 100)
}
</script>
<form onsubmit="reloadPage()" method="post" action="http://localhost:8080/person/delete/${profile.id};">
<input type="submit" value="Delete"></form>
This works, but I'd like to know if there is any insight on why the original methods wouldn't work. Also, are there any suggestions on alternatives to my code?
Edit:
To clarify, the path http://localhost:8080/person/delete/${profile.id}; doesn't lead to a page; its meant to call the method in the method in the resource class that will run the delete method:
#POST
#Path("/delete/{id}")
public void deleteProfile(#PathParam("id") int id) {
manager.deleteProfile(id);
}
Because onsubmit is called BEFORE the action is ran. The flow is this one:
Submit form
Call onSubmit events
Run action if event is not prevented
So what is happening is this:
Submit form
Reload page
Action is never reached because you are reloading the page, hence stopping all the page logic. Is like closing a program and opening it again.
Your 100ms is a dirty workaround because altough it works for you, it may not work for anyone that cannot process the action before those 100ms. Imagine a slow device, slow network or slow something that will delay the action more than 100ms. It will reload the page before the action is ran.
What I don't understand is why don't you let the webpage do the reload for you. Natural form submits takes you to the action url, loading it, hence reloading the page if is the same URL.
I'm not sure why your code works, it shouldn't. When submitting a form it will actually redirect you to the URL you specified in action, so reloading and redirecting at the same time is just not possible.
My suggestion is using a http request to delete the data. That would look like this:
<script>
function deleteData(var id) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
location.reload(); // request successfull, so reload
}
xmlHttp.open( "GET", "http://localhost:8080/person/delete/"+id, true );
xmlHttp.send( null );
}
</script>
<button onclick="deleteData(${profile.id})">Delete</button>
Alternatively you can use your form (without the reloadPage()) and have the page at http://localhost:8080/person/delete/xy redirect back to this site.
I'm having a problem always when I try to use the following code in a button in my HTML file.
onClick=window.location.reload();
mapGenerator();
The page reloads but the javascript (mapGenerator) that make a D3JS view doesn't appear. What am I doing wrong?
location.reload() will immediately reload the page and prevent any following code to execute.
You can, however, create a function that executes your method after the page has (re)loaded:
window.onload = function() {
mapGenerator();
};
This method will run every time the page has fully loaded. To only run the code after you have reloaded the page using location.reload(), you could create a method that handles the click by setting a cookie and then reloading the page.
function handleClick() {
document.cookie="reload=true";
location.reload();
}
This would require you to change your onClick value to onClick="handleClick();". Now, whenever the page loads, you can check whether the cookie has been set. Your window.onload function now changes to this:
window.onload = function() {
if(document.cookie.indexOf("reload") >= 0) {
mapGenerator();
}
}
Checking if a cookie exists - answer by Michael Berkowski
After the reload it's up to you whether you want to unset the cookie — if you don't, the page will run the function mapGenerator on every page load until the cookie expires.
If you need more help with cookies, check out W3Schools' tutorial.
As per your description mentioned above two actions are to be taken on click. As the first action reloads the page the second action is lost. If you want any action to be taken on load of the page, mention the same on onload event of the page.
I'm using greasemonkey to manipulate a form on an existing web page. (autofill)
The action attribute of the form is itself, once submitted it prints a success message above the submit button.
What I'm trying to do is, once the form is submitted - I want to redirect the browser to another page. But this doesnt work with greasemonkey. Nothing happens.
I wrote a code to detect when the page is submitted, but doesnt work after the form is submitted.
getData("goingback"); //pulls the goingback data from database using ajax
if (goingback == "yes") {
window.location = "index.php";
} else {
//business as usual
// manipulate the form and get it ready for submission
sendPost("goback","yes"); // this function sends data to a php to be handled via ajax
//ajax stores the data in database
//the form is submitted using a timer and .click();
var submission = Math.floor(Math.random() * 10000) + 5000;
setTimeout(function() {
$('button[value="submit"]:first').click();
}, submission);
}
How can I achieve this?
Thanks in advance
The question is not clear; we might need to see the actual page itself. But, it sounds like the page is submitting the form via AJAX, and not a full post.
In that case, your script won't refire. Instead, monitor the page for the success message. Here's one way:
Suppose the success message is like this:
<div id="post_status">
<h2>Some one set us up the (data) bomb!</h2>
</div>
where the <h2> is added after the form posts.
Then this code will redirect after the post happens:
var postChkTimer = setInterval (checkForPostDoneNode, 200);
function checkForPostDoneNode () {
var postDoneNode = $("#post_status h2");
if (postDoneNode.length) {
window.location.assign ("index.php");
}
}
There is no need for that getData("goingback") or
sendPost("goback","yes"). Also that looks like it's setting goback but checking goingback -- which could be a problem. Although it is not the problem causing the behavior as described in the question.
I have a page where user needs to enter some data and click save to validate the changes, but my problem is if the user is trying to close the browser window or click on a different link to navigate to a different page..I need to delete all the entries the user has saved so far..
I am doing it the following way
window.onbeforeunload = function()
{
if(confirm('Are you sure you want to navigate'))
{
//Invoke `enter code here`server side method
}
else
{
// return false;
}
}
Everything works fine if he click on Yes, the problem comes when he click on "No"..Even if he click on No..the page unload method is getting called and it is redirected to a different page..but I want it to stay in the same page in same state...can you please help me in achieving this.
Thanks and appreciate your response....
You cannot stop the user from leaving the page. What you can do is alert a message to them, asking if they want to leave or not.
The window.onbeforeunload event should return a string (and only a string). This string will be printed on the alert box made by the browser.
You cannot use your own alert box, or block the user from leaving (or redirect them).
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
Or with jQuery
$(window).on('beforeunload', function(){
return 'Are you sure you want to leave?';
});
When a user leaves the page, you can use the onunload event to make an AJAX call (you may need to use async: false here).
Example:
$(window).unload(function(){
$.ajax({
url: '/path/to/page/',
async: false, // this may be needed to make sure the browser doesn't
// unload before this is done
success: function(){
// Do something
}
});
});
NOTE: Instead of doing this, why don't you just save everything when the user is completed? Instead of saving it and then removing it if the user doesn't finish?
First of all: you can't! It's impossible. onbeforeunload only accepts a string as return value and will then close if the user wants that.
But then think about what happens if the computer is being without energy and shuts down? Or the browser will closed by the Task Manager? Or even more "realistic": The internet connection get lost! => Then you got invalid data states too!
You are trying to solve a false problem! Your problem isn't this function, your problem is the state of your formular!
Why do you need some kind of function? Do you saving the data before he clicks on save? Then don't! Or make sure to have another query which detects unfinished data in your database and delete it after a timeout!
onbeforeunload only accepts a string as return value. That string will be displayed by the browser with the option to stay on the page or leave it. But that's ll you can do.
You can use something like this, just call the following function on your page
function noBack() {
window.onbeforeunload = function(){window.history.forward()}
}
this disables Back button if window.history is clean, otherwise it works only first time.
Im make some ajax calls in my website and im trying to implement the history API to make it so I can navigate it with the browser history. This is the code for the "back button":
$(document).ready(function(){
window.addEventListener("popstate", function(e) {
//Flag I use to not fire it on the first page load
if (!ajaxhistory)
return;
do_my_ajaxs_things();
}, false);
});
But I have 2 problems
1) When I type the URL in the address bar to load the page for the first time. This also fires the ajax call, which is undesired obviously. Theres no need to ajax, since I have to load the entire page. This one, I have managed to solve it with a flag, but I wonder if theres a more elegant way to do it
2) Lets say I was in "google.com" and the I type my URL "www.mysite.com", then I make an ajax call and I go to "www.mysite.com/contacts". If I press BACK button once, i will go to "www.mysite.com" allright, but if I press BACK again, I will still be in "www.mysite.com", and I find myself I cant go back to google. How could I solve this issue?
All help appreciated. Thanks.
I think that your approach is wrong. You shouldn't need to do AJAX requests each time the user goes back - that's what the state is for, you should have all the relevant data already there. IMHO the logic should be the following:
If the window loads and window.history.state is already set - just apply this state.
Otherwise trigger an AJAX request to retrieve the default state and replace the current state with it.
Whenever the user navigates to a new "page", trigger an AJAX request to retrieve the new state and push it.
In your popstate handler you should simply apply the state you got in event.state, without doing any new AJAX requests.
Here is some example code with a fake loadPage function, normally you would put your AJAX call there. The applyState function and state data are also absolutely minimal.
<script type="text/javascript">
window.onload = function()
{
if (window.history.state)
{
applyState(window.history.state);
}
else
{
loadPage(0, function(state, title, loc)
{
window.history.replaceState(state, title, loc);
});
}
window.addEventListener("popstate", function(event)
{
applyState(event.state);
});
}
function goToPage(pageId)
{
loadPage(pageId, function(state, title, loc)
{
window.history.pushState(state, title, loc);
});
}
function loadPage(pageId, callback)
{
window.setTimeout(function()
{
var state = {text: "text" + pageId};
applyState(state);
callback(state, "page " + pageId, "#" + pageId);
}, 100);
}
function applyState(state)
{
document.getElementById("content").textContent = state.text;
}
</script>
<div id="content">
???
</div>
<button onclick="goToPage(1);">1</button>
<button onclick="goToPage(2);">2</button>
<button onclick="goToPage(3);">3</button>
For your first problem, this is really a browser issue. A browser should (in my opinion) never fire the popstate event when the page is loaded initially. I think the best thing you can do is only register the event after the page has been loaded.
History.js is a good library which smoothes out the history API quite a bit. Even if you don't use it they have good documentation about the API here:
https://github.com/browserstate/history.js/wiki/The-State-of-the-HTML5-History-API
About your second issue, the browser wil just go to google instead of firing the popstate event for your website. You don't have to worry about that, it's the browsers responsibility