Populate state with values from autocomplete (react) - javascript

I have a component with inputfields and a button which is disabled unless the correct values are entered in the inputfields. This works fine but when chrome autocompletes those values on page load, the state isn't changed and thus the button stays disabled. If you click inside the form or change a value the state changes correctly.
How can I get the value from autocomplete when the component load? Autocomplete doesn't trigger the onChange or onBlur events and autocomplete="off" doesn't work either. (also I'd prefer not to turn off autocomplete anyways)

I recently came across this problem while working on my login page. After a bit of research, I came across this issue reported on the ReactJS github. To quote the key part:
If we are able to access autofilled values once the page loads, it would become very easy to write malicious code to extract information on a form intended for phishing. Giving the user no chance to react. Probably part of the reason why autocomplete="off" is ignored by browsers.
To overcome this problem we need to:
Accept the fact that we won't (and never will) have access to autofilled values when the DOM node mounts
Embrace the security concerns which are brought up by the browsers
tl;dr - It's intentional for security reasons, and it's better to validate the inputs upon submit instead.

Related

Materialize and Bootstrap input fields cache last state and do not respect my chosen state

Take a look at the documentation here:
https://materializecss.com/checkboxes.html
If you check the top checkbox and then reload the page - the top checkbox is still checked and not reset. If you look at the source, the checkbox has no "checked" on it.
How do I get materialize checkboxes to work as I expect? This is a big nuisance for me since a checkbox can appear as checked but not be posted when the form is submitted. Is it my browser? Is it Materialize? Is there a solution?
It works correctly if I press hard refresh - ctrl+f5, but not when I press ctrl+r or refresh button in the browser. The issue is the same with Bootstrap. Normal checkboxes work just as I expect them to.
I made some more research into this and found a solution that fixed it for me:
autocomplete="off" on the input fields.
There seem to be other solutions as well by disabling caching by using "Cache-Control: no-store" header serverside or in meta tag - but this did not work with me so I assume this is an obsolete solution for this kind of issue from a time where browsers respected headers for how to cache html content.
The default is a good thing if it is a form for user input, but I needed it not to be this way because I build an administrative insert/update system and need to have the system to correctly show what is stored rather than reflect and remember what was last clicked.

Chrome Autofill on ASP.NET Partial Postback (Update Panel)

I understand there are many questions and answers surrounding autocomplete and autofill for web browsers. I haven't seen this specific issue raised.
UPDATE: the autofill specifically happens when a partial postback executes inside an update panel
Recently, (chrome versions 70+?), Chrome has begun aggresively autofilling input fields in our webapp when a partial postback is executed. (We use asp.net web forms)
We use the partial postback to dynamically load a user control and add it to the DOM inside an update panel.
Specifically, inputs like the following simple snippet are being populated with an email:
<input type="search" class="newH4" placeholder="Search">
I've tried adding the autocomplete attribute with different values to no avail.
Here is a screenshot of the autofill:
Additionally I have other fields like entering a dollar amount which gets populated with the email as well. Is there a way to prevent this on the latest versions of chrome?
If you have a password field in your form you can add this attribute -
autocomplete="new-password"
<input type="password" placeholder="Password" autocomplete="new-password">
autocomplete="off" should be working, but in lieu of that working and given that it is not a password or email, you could feed it some random string to see if that helps
For example autocomplete="rjftgh"
Note: simply changing the autocomplete attribute to a random string, or even a special one like 'new-password' does NOT work for this issue.
Ultimately I found a solution. It is more of a hack so I'm not too satisfied with it, but it comes from Mike Nelson's answer to the following question: Disabling Chrome Autofill
His solution involves adding input elements with their display property set to 'none' above the inputs that are being autofilled. The idea is that these hidden fields absorb the autofill instead.
I did also learn a bit more about the problem with ASP.NET and Update Panels as well. When the Update Panel triggers a partial postback, it uses an AJAX library. The library contacts the server to complete the update. Whatever AJAX is doing in the background, it is also triggering chrome's autofill logic to reexecute. In other words, whenever I dynamically add a user control, the first input field in that user control's html structure was being autofilled with the user's stored email.
Again, very strange and bad behavior, but the display 'none' input fields did the trick.
If Chrome changes their autofill logic again (they will), I'll update my answer with hopefully a better solution.

Issues with "Recurly.js" form generation and GWT / AJAX

I am building a user interface for Recurly account management in a GWT application.
This means there is no actual browser navigation happening between "pages" in the app, and client DOM state is maintained in memory until the user actually refreshes their browser.
In other words, when the user leaves the billing information "page" - the input elements still exist in memory and are simply detached from the visible area of the user interface.
Unfortunately, the fields that are being provided by "Recurly.js" are somewhat problematic here as they seem to be designed for use in a conventional framework where the user submits the form and then is redirected to a new page.
While they work perfectly for an initial submission of updated billing information (i.e. the first time the "form" is instantiated), if someone re-visits the screen multiple times without refreshing their browser, the fields do not accept input.
I have tried the following:
clearing the inner HTML of the wrapping recurly div elements (into
which the provided fields are drawn by Recurly.JS) and calling
configure() again
Not calling configure() after the first time it is called (in this case, subsequent visits to the page result in unresponsive inputs)
Is there a way I can tell Recurly.js to reset itself so that the provided fields can be redrawn? Or (and preferably) is there a way to configure recurly to use my own "input" fields for number, date, month, and cvv instead of those that are rendered into divs by Recurly.js?
Thank you
Edit:
I have discovered that Recurly.js is setting the visibility of their provided billing inputs to "visibility:hidden" after the form is accessed after being instantiated. If I can't force recurly to redraw the inputs, then I need to prevent this from happening some how...
I discovered a "readyState" variable in Recurly.js.
If I set that back to "0" before calling "reconfigure", the fields correctly reconfigure themselves.
This seems to fix my issue.

Is it possible for the browser to cache Javascript/DOM changes?

I am developing a form using Javascript for styling that will be used to submit many different things. However, the majority of the time the different things will only be slightly different so it would really benefit users if when you press the Back button on the browser, the form is exactly as you left it before you submitted the form.
Note: This already works when using a normal HTML/Javascript-less form, the question I am asking is how I can retain this functionality when using Javascript to hide/replace input fields etc.
I've tried History.js and HTML5's replaceState() but nothing seems to work. Also if it helps, this will be a private website that requires the latest browser installed so don't feel hesitant to recommend solutions only available in the latest browser releases.
Many thanks!
Update #1: Here's an image better explaining what I need.
Update #2: Okay I managed to crack it perfectly, cross-browser included. I'll post a solution tomorrow after I've had some sleep.
Okay so I went back to the drawing board and tried to figure something out using the tools I already know exist. The case with each browser (usually, haven't tested any non-major browsers) is that when you press the Back button after submitting a form, text input fields are usually populated. I wanted to see if this worked the same with hidden input fields, turns out it does!
So next I set up some Javascript events to listen out for the page load.
if($.browser.mozilla)
{
$(window).on('pageshow', pageManager.init);
}
else
{
$(pageManager.init);
}
This works for Chrome, Firefox and IE9. I haven't tested any other browsers but these are the only browsers that will be used for my private site so it's good enough for me. I'm sure you can set up your own preferred solution for your needs but this is what worked best for me.
Anyway the above code means every time the page loads, pageManager.init() will run. Here's an excerpt of the code I use to check if the Back button was pressed and it's not simply just a page refresh or a first-time visit:
if($('input[name="form_submitted"]').val() != '')
{
// back button was pressed
}
As you can see, it's as simple as checking if your hidden form field contains a value. To actually guarantee a value will be set, make sure to set on submission of your form:
$('#my-form').submit(function()
{
$('input[name="form_submitted"]').val('true');
}
It really is as simple as that. This is one of the best methods I can think of for determining if the Back button of a browser was pressed. Now, to cache all the form values for the visible fields it can be as simple as using JSON.stringify() on the fields and sticking it all in one hidden field which you decode later.
AFAIK, this is generally handled manually. That is, you use hashtags or pushState (with appropriate state object) and either on hash change or on popstate you grab the hash/state, and (re)build your DOM as needed.
(note, I combined two very different scenarios into one there, sorry. if you were only using hash changes, you wouldn't likely be using pushState, as pushState doesn't trigger onhashchange according to MDN.)

Why does Firefox + My code Destroys FireFox refresh

I am soo angry right now. I lost hours and i dont know why this happens. Its a semi rant but i'll try to keep it short
My code would not work, even after refreshing it was broken
I fixed my code or so i thought because it stops working without me changing anything (you would think i am imagining this...)
I somehow decide to make a new window or tab i run my code and verifies it works.
I write more code and see everything is broken again
I write test in a new window and see my code does work
I see my code doesnt work and firebug DOES NOT HELP
I notice when i create a new tab everything works
I realize refreshing does not work and i MUST make a new tab for my code to work.
Then i knew instantly what the problem was. I modify a display:none textbox but i set the values incorrectly. I cant see it because it is hidden. Now some of you might say its my fault because when doing a refresh all of the data may be cache. But here is the kicker. I was using POST data. I posted in between of the refresh each and everytime.
Whats the point of using POST when the same data is cached and use anyways? If theres no chance for a search engine to follow a block user get link then why should i bother making anything post when security or repeat actions are not an issue? POST didnt seem to do anything.
Sounds like you're being hit by form-field-value-remembering.
When you use back and forward (but when the bfcache isn't used in browsers that have it), or in some browsers when you hit reload, the browser attempts to keep the values of each form field that were present when the page was last unloaded. This is a feature intended to allow the user to navigate and refresh forms without losing all the data they're laboriously typed into them.
So you can't rely on the value of a form field being the same at page load time as it appears it should be from the HTML source. If you have DOM state that depends on the value of a form field (such as for example a form where some of the fields are hidden or disabled depending on the value of another field), you must update that state at page load time to reflect the field values that the browser has silently dropped into place (no onchange events occur). And don't use hidden inputs to store scripting variables at all.
The exact behaviour varies across browsers. For example some browsers keep the values of hidden fields and some don't. Mozilla and WebKit put the new values in instantly as the fields are parsed into the DOM, whilst IE only does it on window.onload... and Opera, aggravatingly, does it just after window.onload, so you can only catch it by setting a 0-timeout to update state after onload. It's a nasty mess.

Categories