Knockout value binding to HTML5 date picker (Chrome) - javascript

I noticed in a Knockout binding to an HTML5 date input, that the binding was firing whenever a key was pressed when typing into the control. This is in contrast to the regular <input type="text"/> box where the value only causes the observable to update when focus is lost, or enter is pressed.
I believe Knockout by default is using the change event, and so for a simple example of how this behaves without Knockout, I produced a small fiddle here (http://jsfiddle.net/qm282xdm/).
You can see that the input text box doesn't fire the change event until you lose focus or hit Enter on the box, but if you type a new date into the <input type="date"/> then every keystroke causes the change event to fire.
Is this supposed to behave this way? The differing behaviour of the text vs date input is a little counter-intuitive. I'm running Chrome Version 34.0.1847.116 and I have a feeling an older version behaved more like I am expecting, but I can't be sure.
Edit: I would like to know if this is a problem with Chrome or 'by-design'. The firing of the change event is intuitive on a text type input, and I would expect it to be the same from a date type input. In the absence of any ideas on how to work around this, I will write a custom binding that fires in the cases I expect.

It's not really clear what kind of answer you're looking for. If the question is just "is it supposed to behave this way?" then the answer is "yes". The answer to "Why?" is a bit less clear.
If you want to make them a bit more consistent, you can use the textInput binding instead of the value binding, which ensures you get immediate updates from textbox bindings. Or, with older versions of knockout, use value binding with valueUpdate: 'afterkeydown'.

Related

vuejs-datepicker Typeable Input submit delay

I have am using the Vuejs-datepicker
The problem I am having is I want to use a typable input as well as the datepicker, but when I type into this input field it fires the keyup event which triggers its v-on:selected event.
Meaning if I start typing in '2012-02-02' with it submits on ever key up.
Usually this would be easy to solve as you can use a .length but this vue component always hands back a Date that is parsed. So that won't work.
I have the idea to deconstruct the component and build my own but was hoping someone might have an idea for a different solution
Did you tried the Event Modifiers?
You could try to use then in #keyup, something like #keyup.prevent...
Se at, look for "Event Modifiers":
https://v2.vuejs.org/v2/guide/events.html

input type "number" binding issue with Knockout in Firefox

We have an input of type number with a knockout binding like this:
<inputtype="number" data-bind="value: quantity" />
This works perfectly on Chrome and EDGE but not on Firefox. Whenever we change the value and press save, the value gets reset to the previous value.
Any idea why this is not working?
Please use 'textInput' binding instead of 'value' for 2-way bindings. From the documentation:
Browsers are highly inconsistent in the events that fire in response
to unusual text entry mechanisms such as cutting, dragging, or
accepting autocomplete suggestions. The value binding, even with extra
options such as valueUpdate: afterkeydown to get updates on particular
events, does not cover all text entry scenarios on all browsers.
The textInput binding is specifically designed to handle a wide range
of browser quirks, to provide consistent and immediate model updates
even in response to unusual text entry methods.
http://knockoutjs.com/documentation/textinput-binding.html
In case it doesn't help, please post your view model and recheck that there are no other event handlers bound to the same DOM element.

How to force blur without calling onBlur event

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.

Launch event on value change

I made simple date picker using JavaScript and jQuery. After choosing date it is shown in input box. This input box is not launching change event, probably because it was changed using JavaScript. Is there any way to launch this event, or to make custom one?
Run this code after you assign new value:
$('input').change();
.change just points to the .on function inside jquery, so it's better to use the .on directly.
$('#inputID').on('change', function() {
});
$("input#yourInputId").change();
or
$("input#yourInputId").trigger("change");
Should do the trick. Replace the #yourInputId with an id that represents the ID="abc" part of your HTML for the textbox
Be aware of potential browser irregularities or lack of support for change events - behaviour may vary, particularly in older browsers.
There is a change and an input event. The first fires after an input changed and lost focus. The latter fires immediately when the input changes. However there are no events that fire after programatically changing an input.
If you have control over the code that changes your inputs you can of course trigger the events manually like described in the other answers.

Cross-browser JavaScript input live change/paste detection

Is there a cross-browser way to detect live changes to an input field?
By live, I mean not when the field loses focus, and not on the next keypress, and so on. Immediately or something like it.
Using combinations of jQuery and .change(), .keyup(), .bind('paste') and so on I can get working live change detection in some browsers, but not all. Using different combinations will make it work somewhat in other browsers.
The trickiest thing to get working is mouse manipulation of the input field - selecting text and moving it (which is essentially cut and paste), right-clicking and pasting or cutting, etc. For some reason even .mousedown() and .mouseup() don't seem to cut it.
The only cross-browser solution I can think of right now is to check the input field value every 100-or-so milliseconds and compare the value against a stored value. But this seems like overkill when the event-based solution comes so close.
Is there a jQuery plug-in that does this already? Or is there some other way to achieve this?
To complete your change and key handlers, you can add handlers for cut/copy/paste. They work in Firefox >=3, IE, Safari and Chrome (but not in Opera/Konqueror).
Would that cover everything for your use case?
Depending on the Browsers you need to support you might use HTML5's oninput.
It fires immediately when the monitored input changes. In jQuery you would just do:
$('#my-input').bind('input', function(e) {
console.log("#my-input's value changed");
});

Categories