prevent HTML5 date field from triggering change event on keypress - html

When using a HTML5 date field, every key input triggers the change event on the field on Chrome.
See jsFiddle and try to input the date manually to see the effect:
https://jsfiddle.net/hx3zcenj/4/
document.getElementById('dateFilter').addEventListener('change', function(){
document.getElementById('msgContainer').innerHTML += 'Change triggered<br>';
}); //triggers on every keypress
I would like this event to trigger like it does in a normal text field, i.e. after either selecting the date from the picker or on blur. I don't want it to trigger every time I input a character.
This is mostly relevant for Chrome, since other browsers deal with this field in different ways.

Once the date input has all the three fields, i.e. dd, mm and yyyy; it starts triggering. Which is logical as the date has all the fields and the date is a valid date, though might not be valid for business case.
You can bind the blur event which will do your job. And provide the other attributes like min and max which will also trigger errors.
And if you are going to bind the change event, then first thing you should do is check that data is valid and in the range.

How about using the focusout event instead. This will trigger when they leave the field/change the focus
document.getElementById('dateFilter').addEventListener('focusout', function() {
document.getElementById('msgContainer').innerHTML += 'Change triggered<br>';
});
<input type="date" id="dateFilter">
<div id="msgContainer"></div>

Related

Tab order with paper input and own element

I have made my own "date" input which consists of a paperinput, the pikaday date picker and a date validator (also my own). The reason for this is I have a requirement to both allow "vague" dates (if someone types 4 digits with a value between 1901 and 2050 that means any time in a specific year) and complex other rules so 2811 means 20th November current year (I am british so working with dd/mm/yy - but system I am replacing doesn't need the user to enter the / character).
I have a form with two paper-input fields followed by my date field. Tabbing moves nicely between them until I tab away from my special element, when for one tab nothing is selected and then the next tab the next field is selected.
I put some code on the blur event of my date elements paper input, and the did a var test = document.activeElement; in the event handler. The result of this is the body element from my page.
How do I make the tab order play nicely?
As I explained in the comment under the question, the pikaday date picker had received the tab on the blur, but was then immediately hidden. This left the tab with the body. I changed the various buttons on the picker to have tabindex="-1" added as the picker is created. This resolved the problem

Html5 datetime-local control shows incomplete date

I'm new to HTML5 and Knockout.js I am facing an issue in datetime-local control.
Here is the HTML datetime-control I'm using
<script type="text/html" id="DATE.template">
<input type="datetime-local" data-bind="value: Prompt.CurrentValue, enable: Prompt.IsEnabled, valueUpdate: 'input'" />
</script>
Here is the Save button and it's binded to savecommand to javascript file.
<div class="buttons-wrapper">
<button class="button save-idoc-button" data-bind="command: SaveIdocCommand, activity:SaveIdocCommand.isExecuting">Save</button>
<button class="button cancel-save-button" data-bind="command: CancelIdocCommand, activity:CancelIdocCommand.isExecuting">Cancel</button>
</div>
When I enter the date without entering any time, date is being passed null on SAVE. I understand it's a incomplete date, hence the browser considers it a invalid date, but the entered date is not saved. The Selected date is binded to Prompt.CurrentValue; When user enters an incomplete date (without time), prompt.currentvalue is null, and I get a tooltip message on the datetime control that "Please enter a valid date or date entered is incomplete". (browser validates and provides i think)
What is the best approach to take?
a. should we need to provide the custom validation and disable the SAVE button, until the datetime-local control has a valid value. If so, how we can achieve in html5/knockout.js?
b. Is there a way to disable the browser validation of datetime-local control, so that the date can be passed even though time is not entered.? (I tried with using "novalidation", but it didn't work)
c. any other better approach?
EDIT:
Here is the computed observable for validation in viewmodel; Prompt.CurrentValue is the value to binded to UI controls. When it's date control, this validationerror doesn't work.
> hasValidationErrors = ko.computed(function () {
> //loop through fields and filter out fields that are set up with validation and has invalid data.
> var invalidFieldsArray=ko.utils.arrayFilter(fields(), function (field) {
> return !_.isUndefined(field.Prompt) && !_.isNull(field.Prompt)
> && (
> ((_.has(field.Prompt.CurrentValue,"isValid"))&&!field.Prompt.CurrentValue.isValid())
>
> ||
> ((_.has(field.Prompt.AdditionalData, "isValid")) && !field.Prompt.AdditionalData.isValid())
> );
> });
> return invalidFieldsArray.length > 0;;
> })
,
this selected datetime-local value is not binded (to the corresponding viewmodel: Prompt.CurrentValue),until the user selects the date and enters the full time ... I understand browser does this validation for this control. how can computed observable recognize this invalidity of date control ? (as value is not passed until the value is valid)
Is there a way to disable the browser validation of datetime-local control, so that the date can be passed even though time is not entered
If possible, can you use a combination of <input type="date"> and <input type="time"> instead? (and use the textInput binding while you're at it)
A couple of things - if you are submitting the form to a server your <inputneeds a name attribute to save properly. And you can preset it to a current value if you want e.g. <input name="date" etc.
You need to show your viewModel if you want help with that.
Re validation - a simple Google search shows this validation suite https://github.com/Knockout-Contrib/Knockout-Validation
However, in Javascript anything to do with dates (date validation, date presentation, date tranformation) you should be using Moment.js
EDIT:
Will have a look at your code above when I get a chance. Please note value is not a good binding for date inputs. I suggest you change
data-bind="value: Prompt.CurrentValue, enable: Prompt.IsEnabled, valueUpdate: 'input'"
to
data-bind="textInput: Prompt.CurrentValue, enable: Prompt.IsEnabled"
EDIT 2:
OK, so date-time is NOT supported in ANY version of Firefox, IE, or Safari - it is a pure text input.
Check out https://github.com/Knockout-Contrib/Knockout-Validation/wiki/Native-Rules and Knockout date validation not working correctly, but I think it is best to switch to moment.js (isValid()) and stick to a specifically formatted date string or use a jquery style popup calendar.

datapicker write something different in date field

I want to use Zebra datapicker... but if I attach it to the input, I can't write somethig different from data which is picked in calendar... so how I can choose what I can write into textbox...
P.S I am using only one textbox in my page
Whilst I'm not familiar with the date picker you mention, it ought to have some means of specifying a callback function that acts as an intermediary between the selected value and what, ultimately, gets put in the text field.
I wrote a date picker some years ago which does this - see the callback_func param.
Without a callback, it inserts the selected date into the field. With a callback, it passes the selected date to the callback and uses the function's return value to decide the new value for the field.
var cal = new Calendar({
callback_field: '#myField',
focusElements: '#myField',
callback_func: function(d, m, y, date) { return 'hijack!'; }
});
You need to use a plugin that validates your keyup event on the text field.
Here's a small piece of code I wrote that does just that:
https://github.com/cassilup/jquery.keyup.validator
Unfortunately, it does not have code for date, but you tweak it freely to suit your needs.
Alternatively, you could assign the text field as readonly and let the datepicker do the date input.

Input Textfield date mask

I need to restrict my users to input only dates with a custom format. I want to have something like this example in JQuery: http://www.youtube.com/watch?v=BMaTiGKykl8&feature=player_embedded
How can i archieved this in AS3?
You'll have to catch the KeyPressed event on the TextField. Check if the key pressed is OK at the specified position, if yes, do nothing, if not, cancel the event (Event.cancel = true).
Alternatively (for more features, like these auto added slashes) you can ALWAYS cancel the Event, and use the TextField's selection together with a String and some checking to always make a new version of the TextField's text.
Why not use a DateField and format the data as you see fit?
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/DateField.html?filter_flex=4.1&filter_flashplayer=10.1&filter_air=2

TextField() - filter backspace key away with event listener

How to prevent a specific key such as backspace key functioning from TextField editable field, preventDefault does not seem to work:
public function handleEvents(evt:KeyboardEvent):void {
if (evt.type == KeyboardEvent.KEY_UP) {
if (evt.keyCode==8){
evt.preventDefault () ;
}
}
I recommend listening for the KEY_DOWN event if anything, but likely that won't work either. IIRC these type of events are a bit special and you can't really stop them.
What I suspect you need to do is to store a copy of the text and whenever you detect a change you don't like just set it back to your stored version.
What I have done is set focus to another temporary (and off-stage) text field and in my keydown handler return focus to the my text field for the keys I want to get through. Setting focus just for keys you want to filter out also works.
Try adding evt.stopImmediatePropagation()