Force datepicker use for mat-input - javascript

I have an issue with the native mat-input type date. At the moment if a user manually types in a date that isn't a real date i.e. 02/31/2022 the value of the input isn't set which leaves it with a "required" error. Obviously, that would make sense and does stop the user and makes them change the date to something that does exist. I'd like something a little more user friendly.
The Material DatePicker handles this very nicely
https://material.angular.io/components/datepicker/overview
When this situation happens it rounds it up to the next available date i.e. 02/30/2022 -> 03/01/2022. However, it is very important that I achieve this goal using the native tag.
<mat-form-field required>
<mat-label>Date</mat-label>
<input matInput type="date" formControlName="dateControl"/>
</mat-form-field>
Some ideas that I am researching and will add to this post if I find insight
Disabling typing the date manually (forcing use of the DatePicker UI)
Rounding up the date to a useful date

Related

vue2 datepicker Clearing the date or choosing a date has no effect

I just downloaded this today and using it in my project. Everything seems to work where I see it displaying my date from the v-model. However, when choosing a date, it doesn't change the value in the text box.
Also, clicking on "x" doesn't clear the value and show placeholder
I'm displaying this text inside a client table from vue-tables-2
Here's how I'm using it btw
<DatePicker
v-model="props.row.DueDate"
lang="en"
format="MM-DD-YYYY"
:not-before="new Date()"
placeholder="Select a Date"
input-class="form-control"
#change="selectDate"
append-to-body>
Also, I just realized that when clicking on "x" icon it's actually calling the CHANGE event where my function "selectDate" is getting called with an invalid date of course. This doesn't make any sense. Any idea why this may be happening?
I have created an issue on github for this as well
https://github.com/mengxiong10/vue2-datepicker/issues/278
I think the vue datepicker has custom # functions? try using:
#selected, #opened, and #closed
let me know if that works!

Something like input type date

I need something like input type='date' when i'm clicking the input on mobile to appear the specific datepicker from phone.. Example for iphone
But I want to display the date how I want.. Exactly what I need is to display the date like this: dd/mm/yy
You can try this HTML5 tag:
<input type="date" value="YYYY-MM-DD"/>
where you can set "value" as the default date.
You can also use min="YYYY-MM-DD" and max="YYYY-MM-DD" for maximum and minimum dates.
and as for the mask "DD/MM/YYYY", I recommend using bootstrap-datepicker, where you can have tons of options to mask as you want.

How to validate HTML5 date format

I want to use the HTML5 date input field
<input type='date' name='customDate'>
So that other users can make use of the build-in datepicker from their browser.
I would like to check if the input is actually in date format. As I found here: Is there any way to change input type="date" format? there is no unique presentation format. For example, in Chrome the input of the date field is given in the form of dd.mm.yyyy and in Firefox 24 or IE 9/10 the date in the input field is presented as YYYY-MM-DD.
My first problem is, how do you tell the user in which format you want him to type in the date? In Firefox I would need something like
<label>Enter Date(YYYY-MM-DD)</label><input type='date'
name='customDate' placeholder='YYYY-MM-DD'>
But this would be wrong for Chrome.
Secondly, how can I check before submission if the current input is in the valid date format (of the browser)?
I know that I could check with PHP after submit if the date format is given as YYYY-MM-DD, but how do you check it with JavaScript before submission?
Use it like this:
<label>Enter Date(YYYY-MM-DD)</label>
<input type='date' name='customDate' placeholder='YYYY-MM-DD' pattern="(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))" >
For all other HTML5 Dates Pattern Please visit this:
http://html5pattern.com/Dates
I think the best way to validate HTML5 date format is to leave the job to the datepicker if one is available.
For instance, the native datepicker of chrome or ios5 does not allow wrong user date input. In chrome it even checks if the date does exists in a human calendar.
If the browser does not have native datepicker (like firefox), then this should be detected with Modernizer and one should use the jQuery UI datepicker. Here is a nice article that explains how to do this.
Unfortunately, the jQuery datepicker does not check if the input is valid.
However, one can set the dateType and constrainInput, but they dont check if the date actually exists, just if the syntax is correct. Note that the jquery validation plugin has troubles with the date attribut.
just change the type of date dynamically with onfocus and onblur and validate like below.
<input type="text" id="startDate" onfocus="(this.type='date')" onblur="{this.type='text'}" name="startDate" placeholder="Start Date(yyyy-mm-dd)"/>
$("#startDate").val()=""
finally your date value will be yyyy-mm-dd
The best way is to use a calendar/datepicker (ie: jquery-ui).
You can specify the format you want and is also userfriendly.
jquery-ui details and examples for datepicker

Regular Expression for HTML5 input type=time

I am trying to find a regular expression that plays nicely with the input type of 'time'. I want to use the new HTML5 input type=time, because this form will mostly be accessed on a mobile device, so it would be nice if the user was presented with a time picker.
However, some browsers don't do anything special with that input type, so I still require a regular expression.
I've tried both these examples:
Validating time-only input in asp.net MVC unobtrusive validation
24 hour time regex for HTML 5
They work when the input type=text, however they fail when I change it to time.
Thank you
EDIT
The regular expression should validate the time with AM/PM, however it doesn't matter if they enter in a leading 0 (03:00AM) or no minutes (3am).
Essentially it just needs to work with a time input:
<input data-val="true" data-val-regex="Invalid Time." data-val-regex-pattern="^(0[1-9]|1[0-2]):[0-5][0-9] (am|pm|AM|PM)$" name="StartTime" type="time" value="" />
This returns invalid time when using the chrome time picker.
I have good and bad news...
The bad one is that you cannot use the pattern attribute in input types different from text, search, url, tel, email, and password.
While this is valid:
<input type="text" pattern="([01]?[0-9]{1}|2[0-3]{1}):[0-5]{1}[0-9]{1}"/>
This would not be:
<input type="time" pattern="([01]?[0-9]{1}|2[0-3]{1}):[0-5]{1}[0-9]{1}"/>
The good news is that you may not need to use any pattern in type=time, since it already has a pattern of its own:
type=time (HH:MM)
- time value with no time zone in 24-hour military format.
EDIT
I noticed your edit with the following code:
<input data-val="true"
data-val-regex="Invalid Time."
data-val-regex-pattern="^(0[1-9]|1[0-2]):[0-5][0-9] (am|pm|AM|PM)$"
name="StartTime" type="time" value="" />
I also noticed that people using those data attributes, they still use type="text".
I assume that is the reason why it "returns invalid time when using the chrome time picker".
I haven't find any case where type="time" works with other patterns (even with data-), and it seems this answer already explained it:
html5 time inputs shows 12 hours
If you really need to have the AM and PM you can try to use type="text" with the regex pattern and trigger the datepicker through Javascript.
Okay, so based on Armfoot's response, I decided to use Modernizr to achieve cross-browser time input support. Like I mentioned in my question, the input type needs to be "time" for mobile purposes, because IMO the time picker improves user experience.
I'm not sure if this is the BEST approach, but here is what I did:
Here is the starting HTML for this particular form element:
<div class="form-group">
<label for="StartTime">Time Started</label>
<input class="form-control" type="text" data-type="time" data-val="true" data-val-regex="Time is invalid" data-val-regex-pattern="^(0?[1-9]|1[0-2]):[0-5][0-9]\s*[aApP][mM]\s*$" data-val-required="Start time is required" id="StartTime" name="StartTime" placeholder="Time Started" value="" />
<span class="field-validation-valid" data-valmsg-for="StartTime" data-valmsg-replace="true"></span>
</div>
The initial type is set to "text", and the regular expression for validating the time is:
^(0?[1-9]|1[0-2]):[0-5][0-9]\s*[aApP][mM]\s*$
I used the same expression from the link posted in my question, however I added "\s*" between the time and the AM/PM and also one afterwards, so the it doesn't matter how many spaces go between AM/PM or if the user accidentally adds a space afterwards. The 0? also makes the leading 0 optional.
For JavaScript, I added:
//detect if time input is supported
if (Modernizr.inputtypes.time) {
$('*[data-type="time"]').attr('type', 'time');
$('*[data-type="time"]').removeAttr('data-val-regex');
$('*[data-type="time"]').removeAttr('data-val-regex-pattern');
}
The Modernizr conditional statement checks if the input type "time" is supported by the browser. If it is supported, it changes the type to "time", and removes the data-val-regex attributes since those are NOT supported for type="time".
This seems to work fine across all browsers and devices. I've tested it on Chrome/Chrome Mobile/IE/Firefox/iPad (Safari). The time pickers show up nicely on the iPad and the Nexus devices making this work well for mobile purposes. The regex works properly on Firefox and IE where the time input doesn't get rendered.

How to close the date picker on change for <input type="date" /> HTML5 Input date element

I have a HTML5 <input type="date" /> field, and I want to instantly respond to changed dates.
Currently, the input field partially obscures the data that changes when the date is changed, so I'd prefer to auto-close the calendar picker after a date is changed.
I've tried to .blur() on change, but this doesn't have any effect. The event fires, and I can get the new date value, but the date picker is not hidden. Any suggestions are welcome.
.bind('change', function(){
var input = $(this);
if(input.is(':valid'))
{
input.blur();
}
});
[UPDATE]
By now, I have also resorted to adding an additional input element on the page (<input type="text" id="hideMyCalendar" />) and instead of input.blur(); to do a $('#hideMyCalendar').focus(); but this also doesn't hide the picker, even though the focus is visually brought to a different control. By now, I assume, the only possible way would be to call a chrome (webkit) specific method, but I haven't fount such a method to exist (yet).
01/30/14 This no longer works
This is ugly, but it works for Chrome.
function closeDate() {
$('#txtDate').attr('type', 'text');
$('#txtDate').attr('type', 'date');
}
This is the only way I was able to close the html5 date after selecting a date.
Just remove the date attribute, then apply it again.
The value is retained, and it just looks as if it was closed manually.
UPDATE:
This is the method I use to make all date types close like this:
$(document).ready(function () {
//make all date html5 close on change in chrome
$('input[type="date"]').change(function () {
closeDate(this);
});
});
function closeDate(dateInput) {
$(dateInput).attr('type', 'text');
$(dateInput).attr('type', 'date');
}
so I'd prefer to auto-close the calendar picker after a date is changed
HTML 5 input type="date" does not specify how this input should be realized by browsers. It can be a graphical datepicker, it can be a simple validation on a user input - whatever the browser vendor wants to implements.
So, hiding the "datepicker", which is in fact browser dependend, is not possible in a cross-browser way.
However, you can use the jQuery UI datepicker, where you have full control how it is shown and hidden.
You said (in your comment):
I prefer the HTML5 input element because I hope this brings unity to the web.
And yet you are willing to call a webkit specific method? (in the update to the question):
By now, I assume, the only possible way would be to call a chrome (webkit) specific method, but I haven't fount such a method to exist (yet).
I think that defies the purpose. Then you will need an Opera specific method, an IE specific method, a Firefox specific method and so on... no more unity to the web.
If you really want a single user experience across browsers, then go for jQuery UI. It doesn't only give you the versatility to do what you want (as Nil'z points out), it also give you the same behaviour across heterogeneous browsers.
Instead of using HTML5 where available. What you should want to do is to fall back to HTML5 when JavaScript is not available. That is using unobstructive JavaScript principles. In fact jQuery is designed to do that by default...
Just create your HTML5 (and HTML4 compatible) field:
<input type="date" name="date" id="date" value="" />
Your jQuery:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js></script>
<script type="text/javascript" src="js/jquery-ui.js"></script>
And your script:
<script type="text/javascript">
$('#date').datepicker();
</script>
The end result will be that all browsers where jQuery can run will use the jQuery based datepicker, if JavaScript is not available then it will use HTML5 datepicker, and finally if the browser doesn't support HTML5 then it will be just a text field. That's graceful degradation.
And of course you will use the hide method from jQuery datepicker:
$( ".selector" ).datepicker( "hide" );
Note: +1 to Nil'z
I know I didn't answer the question, but this solves the problem.
Try this:
$( ".selector" ).datepicker( "hide" );
Reference: http://api.jqueryui.com/datepicker/#method-hide

Categories