Rails multi step form with Javascript – browser back button behavior - javascript

I have 1 form that I've separated into multiple divs, each with their own Next button.
Upon clicking "Next" some javascript fires (see below) that hides the current div and unhides the next div (i.e. next step in the form). The URL is also updated with an # and the name of the step (e.g. example.com/booking turns into example.com/booking#contact-info)
$('#booking-details-complete').click(function(event) {
$("#booking-details").css("display", "none");
$("#contact-info").css("display", "block");
});
The Next button code that fires this JS is:
<%= link_to "Next", '#contact-info', :id => "booking-details-complete"%>
The final piece of the form has a Submit button instead of a Next button, which sends one big POST request to the various models.
My problem is back button behavior: going back doesn't update the page. The URL changes correctly, but the parts of the form (i.e. the divs) don't update their show/hide state.
I'm so close to finishing this project, but just can't figure out this last piece. Any help much appreciated.

So you mean hitting "back" on your browser updates your hash in the URL properly, but your page remains static with the desired behavior being that the section you are on collapses and the previous one re-opens?
You need a hash listener, there isn't a particularly standard way of getting one I don't believe. Push and Pop history just manipulate the history stack, it won't give you what you want.
Once you have a hash listener you have to write a JS function that can set your page state based on the hash of the URL.
I've never implemented a hash listener so here's something I found that might help http://benalman.com/projects/jquery-hashchange-plugin/

Related

How to prevent multidocument form page from reloading?

I'm working on a web app that takes the user through multiple forms with simple interface of a 'back' button, form, 'save' button and a 'next' button.
Clicking 'save' only calculates a number from given answers and sends it to localStorage.
When I then click 'next', it opens the next html file I prepared, constructed the same way, just with a different form. The problem is that if I press 'back', the form on the first page is empty, but when I use the browser's 'back' button, it's all there. How do I get this result with my 'back' and 'next' buttons? I'd like the user to be able to browse their answers as well as see a certain form already completed if they encounter it on a different path (there are various paths through 3 to 5 of 11 forms created, depending on what the user wants to calculate).
I understand it's opening the html file every time I click an 'a href', but I don't know how to change it. I tried searching for html form reloading prevention etc. but it doesn't seem to yield any answers. I'm not sure I know how to formulate my problem in a simple enough way.
Best simple solution would pretty much be what "Manolo" suggested.
Put all the forms you need in one HTML doc
Set all the form's style to "display: none" except the first
Create a simple JS function that changes the "display" style accordingly and attach it with the "onclick" attribute to your buttons.
Sorry for the lack of code. Typed this on mobile and hoped it would be straight forward enough. Hope this helped.
Load the forms as you need them using javascript to request them to your server. Use fetch api.
Other solution is to add all the forms to one page and hidde them all from the user. When the user click next you hide firstForm and show secondForm.
You can use History_API of DOM to manipulate the history
let stateObj = { foo: "bar" }
history.pushState(stateObj, "page 2", "bar.html")
And can catch thee event of back and next button of navigator with
WindowEventHandlers

Browser Back button changes dynamic url Parameters

I am working on a website, where url parameter gets updated based on user action, according to which I update the webpage without refreshing.
Consider the scenario of E-commerce where url changes when user clicks on filters and then updated products gets displayed.
Now the problem is, when user clicks on Browsers's back button the browser goes back to previous url-parameter, but page did not gets changed. I want to change the page also based on url parameter that gets changed after back button clicked.
I have tried this solution:
$($window).on('popstate', function (e) {
// Update the page also
});
The problem with this code is, this gets fired as url changes, means it does not care about if browser back button is clicked, or url is changing using the jQuery. So if I am changing url based on user interaction, the popstate callback will be called and my custom function also. To update the page I am using https requests, so http api gets called two times.
Is there any way to check if only "Back button" is clicked?
I would recommend you to change your design a litle bit and trigger all content updates (the product list in your case) by listening to url changes, not only url changes caused by the back button. So instead of triggering any re-rendering on click events, let these buttons be regular link to the url that represent your content and trigger the functionality from the popstate event.
This is how all MVVM-frameworks like Angular.js, Backbone etc are designed and meant to be used.
By doing this it will also be so much easier for you to maintain the application in the long run.
Good luck!
You can do this with sessionStorage! Below is the relevant part of an answer I always refer to for stuff like this https://stackoverflow.com/a/45408832
sessionStorage is a storage type like localStorage but it only saves your data for the current tab.
Session storage can be used like this.
sessionStorage.setItem('key', 'value'); //saves the value
sessionStorage.getItem('key'); //gets the saved value
performance.navigation.type is the browser is the variable that hold users navigation info.
if(performance.navigation.type == 2){
//User is coming with back button
}
So to put it all together, you can set/update a sessionStorage item as part of the callback of the click event for your filter, then performance.navigation.type to check if they used the back button to load the page and apply the data!

Back button / bfcache: Object hidden in DOM via jquery is visible again when going back?

I have a webpage with a box that appears on the first visit.
In other parts of the site, there are 'back' buttons, and also, of course, the browser back button.
However, the when using the back button (browser or html), the box is visible again.
Is there a way to ensure that the box will not be displayed again when going back? Even removing the object completely with .remove() doesn't work.
I've made an example jsbin here:
http://jsbin.com/losilu/2/
First, click the link to hide the box, then click the second link to go forward.
HTML:
<div id="hide-on-back">
Make this go away
</div>
1. Click First To Hide<br/>
<br/>
2. Go Forward
JS:
$(document).ready(function(){
$('a#hide-box').click(function(e){
e.preventDefault();
$('#hide-on-back').fadeOut();
});
});
HTML/JS (Back Button):
<a id="go-back" href="#" onclick="function(){history.go(-1);}">Go Back</a>
As soon as you reload the page any modification you've done to the dom via javascript gets reset to its initial state. So, either you use ajax (e.g. with jquery.load I believe) to avoid getting the whole page reloaded or you provide a url parameter which you can check for via jquery (Get url parameter jquery Or How to Get Query String Values In js)
Last solution would be saving the information using cookies.

Is Javascript code being processed after clicking on a submit button?

I am working on a ECommerce Project. During the checkout process there is the button to purchase the item at the end of the checkout process. Clicking on that button submits the form on the page using a POST request (Standard, no AJAX). However, if you click on that submit button multiple times really quick, multiple POST Requests are sent to the server and so there are also multiple Orders being created.
My Question: Is it save to prevent these multiple button clicks by javascript, or is the page in a weird state at some point because the new page load kicks in?
Is there a difference about that if I do it with inline script:
onsubmit="if(submitted) return false; submitted = true; return true"
Or in my JS external file?
Another option would be to disable the submit button right after the form submit, but IE adds really Ugly Font Color to the button, which cannot be removed by CSS.
The page continues to process events and run javascript until the form Post returns new content which then replaces the current document, thus loading a new document. It is not in a weird state and works normally until the new content arrives and the current document is closed.
There are various techniques for preventing multiple presses of the button. Your code can keep track of the fact that a post has already been sent (in a global variable) and block any more being sent whenever that variable is set. In the UI, you can disable the button as soon as the first post is initiated so the button can't be pressed again.

Previous form data getting posted along with the current data

I am creating an application which has a slide in and slide out window. This slide in and slide out window has a form which the user needs to fill. On click of the 'Save' button the POST request is fired. Everything goes well till here. But the second time when the user tries to post, there are 2 POST requests sent over network, the first request has the older data and the 2nd request carries the new data. Third time, when the user fills the form, 3 POST requests are sent.
I am using backbone to create this application, I tried cleaning up the views before sending the data, but that didn't work, can someone suggest me where am I going wrong?
Check your events and make sure that you don't have a submit event and a click event.
Also, if you are rendering the view several times, you might end up with several events attached to one button.
It would be helpful if you had some code so we could actually see what is going on. As #fbynite noted, you might also check your event bindings.

Categories

Resources