So firefox has a nifty mechanism which will try to autocomplete values in fields when a page is reloaded or the back button is used. Which is great and all except when you have something like a drop-down which when set to a value modifies the page using ajax.
What winds up happening is that the browser reloads the page, the drop down is pre-filled with the remembered value, and then no change event is fired when the dom is ready. And therefore the change handlers attached don't fire and thus the page does not update.
Is there a good way to "fix" this behavior so that it works for the user as expected:
a) We do want the browser to auto-complete because that is a good user experience.
b) Still want that onchange event firing.
The only thing I can think of doing at the moment is to add an on-ready event to the document which has javascript pre-populated with initial values in the form, when the document loads the javascript will check the pre-populated values and if not matching what is in the input will trigger the change handlers.
Anyone have a better solution? Is there a lib that does this already?
(Using Rails 2.3.5 + jQuery)
Unfortunately there appears to be no way of actually disabling firefox from auto-filling fields when reloading a page or using the back-forward button. Fortunately the values are already there during $(document).ready() event so as long as everything in those inputs can have the .change even initially fired on them, it don't matter where the values came from and it just works.
I think you can add autocomplete="off" to prevent the browser from prefilling those fields.
You can also have a function that runs onload and basically checks to see if the value of the field matches what was specified in the value="" parameter.
Related
I'm after what seems to me to be a straightforward pattern for handling page refreshes when I've got a drop-down that reacts to the onchange event.
I've used the following in the vb code behind (in the Load handler):
MyDropDown.Attributes.Add("onchange", "ProcessDDChange(this.value);")
Function ProcessDDChange() is in-page JavaScript that grays out some other form inputs for certain values of the drop down.
This works fine, but after a postback, onchange is apparently not fired when the previous state is restored, so disabled boxes are enabled again.
I've investigated load events (page and drop-down), but both fire too early to be of use and I can't see any later options.
Is there a standard way of doing this? I need a hook for running a js function post DOM setup, post asp state restore.
Info
I'm using .net 3.5 and I'm looking for a cross browser solution. This is not my project, so I can't add jQuery (much as I'd like to) or other libs.
You could wrap the dropdown in an update panel and set the trigger for the change event like epascarello suggests. Have you tried adding it to the markup like
<asp:DropDownList runat="server" ID="MyDropDown" onchange="ProcessDDChange(this.value);"></asp:DropDownList>
EDIT:
So you are loosing the onchange listener when you postback, the above example should preserve it. But if not you could also try this in the codebehind event that you would like to have call the ProcessDDChange: for vb.net
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "err", "ProcessDDChange(this.value);", true);
FINAL EDIT:
Thanks for sticking it out with me Bob, while I was attempting to understand the question:
The document.ready event is raised after the PageLoad event is complete and the DOM is constructed. This would be the proper place to call your ProcessDDChange().
document.addEventListener("DOMContentLoaded", function(event) {
ProcessDDChange(ddlId.selectedValue);
});
onchange does not fire when the page loads. You would need to trigger the function on page load OR you need to have the server set up the page correctly from the start.
I'm working on a JavaScript 'form' (it's not actually a form - it's a Knockout interface that makes a request to another JavaScript object, but that's not important) and I'm a bit worried about some behavior I'm not sure I can rely upon.
Let's say I have an input and I've attached a change event, either natively through onChange or via jQuery change. That change event updates a model that I'm going to validate and then send off to the server as part of my form 'submission'.
I also have a button with a click event that performs the submission.
If I click the button, as far as I can tell, the form element change event triggers first. But can I rely on this behaviour? Is the fact the change event fires first part of a recognized specification, or just a browser implementation detail?
I took a look at the events specification (http://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/) but couldn't find an answer to my specific question, just that click, blur and focus events are treated synchronously - that is, they're added to a queue and executed in order. But I don't know if the order is consistent between user agents.
Is this behaviour guaranteed by any specification?
I'm not really sure how to go with this, but here goes:
I have form elements that trigger a function (mainly for validation purposes). This triggers on click, on change etc. These are written with vanilla JavaScript.
If it's a straight-forward HTML element then everything works fine. E.g. a element fires on change.
However, if I use a jQuery script (e.g. a jQuery colour selector), then although that jQuery script populates an field, the validation script doesn't fire.
This I suppose is obvious as you don't click, blur, change it, it's just the jQuery script changing it.
Of course I could change the JavaScript in the colour selector jQuery script so it also fires the validation script, but there must be a better way where as well as on click, on change, on blur etc. I can also activate the function when it picks up that another script is changing it. I need this for various occasions and scripts.
Another example is a rating script (rate out of 5). It uses radio buttons as a non-jQuery fallback and the jQuery script just hides those radios (with CSS), displays the star images and then changes the radios when the user interacts with the star images. That way the server handles a form submit the same way regardless of the availability of jQuery. However, the validation script doesn't fire.
Any ideas?
Apparently the elements are being inserted on the dom after the javascript run.
try using $.live() instead of $.blur()
so even if this script elements are inserted after the page rendered, events will be bound to em.
http://api.jquery.com/live/
How do I force blurring, but without calling onBlur event in JavaScript/jQuery?
I'll try to describe you what I need it for:
when onBlur is called, I call a PHP script via jQuery and validating input. If there's something wrong, it returns a message and then I display it back in jQuery script.
if a blurred field isn't filled, script should focus user back to that field.
And the problem is that if you press TAB to change field, and your first field is not filled, script will focus you back, but then is called onBlur from second field that is also not filled, and then it causes an infinite loop.
So, i want to blur a field and focus to another without calling onBlur event.
It's not an answer as spec'ed in your question, but what I'd suggest you do (in a somewhat UX sort of perspective) is to scrap the auto-refocus on invalid input, and instead mark the invalid field (may I suggest red, for example?). Now, you can go and deal with the (arguably) simpler problem of preventing a form submit on invalid data, instead of the problem of preventing a natural browser behavior type of an event.
Additionally, I'd dare to say that auto-refocusing is irritating for the user. Imagine tabbing to the second field, start typing, then suddenly yoink! You get dragged to the first field.
Why not just use on "change" and "keyup" instead of on blur?
I agree with Richard above, there's nothing more annoying than losing focus in the middle of typing, but if you do need to do this (Due to a customer requirement etc) - in the code that auto-focuses the field, disable the onBlur function temporarily until you've focused the field, then re-enable it.
Safari has a feature to prompt you if you're sure you want to close/refresh the page on which there are some forms which you typed into. This is useful in most cases, but in this case it's bugging me.
I'm hijacking the "submit" event on some forms and sending them to the server via XMLHttpRequest. However, Safari doesn't know that, so when I want to close the tab it displays that damn warning that form values have changed.
I know how to turn it off in OS X and I don't want that. I want to turn it off on this specific web page I'm building, and for all users with Safari. Surely there must be some JavaScript way—I don't care if it's proprietary to webkit.
Update: I tried this, but to no effect. Safari first warns about unsaved data, then triggers the "beforeunload" event.
if (Prototype.Browser.WebKit)
window.addEventListener('beforeunload', function(e) {
forms.invoke('reset')
})
I don't know Safari that deeply, but if you just submit the values and don't need them afterwards, why not simply reset the form? I would expect no change = no warning.
If you don't want to reset it straight away, you could even try hooking the reset command to the unbeforeunloadevent to do it when you close the page. Whether that works depends on when Safari checks for the changed form, though - before or after calling unload.
That's application behavior, so there mustn't really be any JavaScript way of modifying it. Every WebKit specific feature is documented pretty well, and I've never seen anything of the sort. Just clear your form fields if you're really that worried about it.
https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html#//apple_ref/doc/uid/TP40002079-SW1
https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariHTMLRef/Introduction.html#//apple_ref/doc/uid/30001261
The only way I see left around this is having a form consisiting of hidden inputs only, and a bunch of input elements that are not associated with the form. On submit, you fetch the values from the the elements, make your request and reset the internal form. You could even do the moving of the input elements out of the form via DOM so it would even degrade gracefully.
A lot of work and a bit hacky, but as far as I can see the only option if you can't change the workflow.
Try removing the action and method attributes from your form tag with Javascript after you bind submit. This way, Safari should no longer see the inputs as being part of a real form.