When using jquery datepicker, what is the correct way to handle people typing in dates in different formats?
Asked Answered
S

7

11

I have the following code:

$('#MilestoneStartDate').datepicker({
    dateFormat: 'dd M yy'
});

and it all works fine if you use the mouse to click on a date in the popup to enter a date but if a person types in a date or pastes in a date into the textbox with a different format than above (such as "1/1/2016"), when i have this code:

 var startDate = $('#MilestoneStartDate').datepicker("getDate");

startDate variable shows as current date (even though obviously 1/1/2016 is not the current date)

what is the best way to handle these situations? Should i be preventing people from typing and pasting in dates or is there a way to do a format conversion?

Sylviasylviculture answered 22/2, 2016 at 11:14 Comment(4)
#4347983. The second answer is an implementation that allows multiple formats, hope it helpsWundt
Implementation/UX wise, I think it's easiest to just put your intended format around the input. (MM/DD/YYYY). Then just show a validation error when the input doesn't match the format. This is much easier than trying to parse multiple formats, and still allows user input instead of select menus.Nothingness
@Eric Guan - can you show by an example what you meanSylviasylviculture
ux.stackexchange.com/questions/1232/…Nothingness
C
6

The getDate method of datepicker returns a date type, not a string.

You need to format the returned value to a string using your date format. Use datepicker's formatDate function:

var startDate = $('#MilestoneStartDate').datepicker('getDate');
$.datepicker.formatDate('dd M yy', startDate);

The full list of format specifiers is available here.

EDIT

$('#MilestoneStartDate').datepicker("getDate");

Always give you the correct date if date is selected by mouse to click on a date popup but if someone manually write or paste date in different format this gives you the current date.

So to handle this situation use bellow code.

$(function(){    
    $('#MilestoneStartDate').datepicker({
         dateFormat: 'dd M yy'
    });    
});

var strSelectedDate = new Date($('#MilestoneStartDate').val());
var formatedDate = $.datepicker.formatDate('dd M yy', strSelectedDate);
alert(formatedDate);

Working Demo

As per @Boris Serebrov comment

The key is new Date($('#MilestoneStartDate').val()) - it actually tries to "guess" the format, so things like "2 Mar 2016", "March 2 2016" or "2016, 2 March" will be parsed correctly.

Step by step:

Case 1:

Here strSelectedDate give you the date in standard format lets say if i select 02 Mar 2016 from date popup it give

Wed Mar 02 2016 00:00:00 GMT+0530

Now

$.datepicker.formatDate('dd M yy', strSelectedDate);

give you the date of your format like bellow

02 Mar 2016

Case:2

As you mention in your question if user manually enter date like 1/1/2016 strSelectedDate give you the standard date like bellow

Fri Jan 01 2016 00:00:00 GMT+0530

Then

$.datepicker.formatDate('dd M yy', strSelectedDate);

give you the formated date

01 Jan 2016

Which is correct date as expected.

Case 3:

Now if user write some invalid date manually like 112016 then strSelectedDate returns Invalid Date so here you can implement some client side validation to the user to enter the correct date.

Hope this helps you.

Cenacle answered 1/3, 2016 at 13:56 Comment(1)
There is too much text in the answer which hides the solution. But it's actually a good solution, the key is new Date($('#MilestoneStartDate').val()) - it actually tries to "guess" the format, so things like "2 Mar 2016", "March 2 2016" or "2016, 2 March" will be parsed correctly.Glasses
B
1

Short answer: let the user fix her errors (you can allow pasting, it's not a problem). Just stick to a simple validation mechanism.

Long answer:

I believe you should allow users to paste text, but it makes no sense to validate the form until all controls are valid.

So if the user pastes an erroneous date in your date control, then when she clicks the submit button, your ui should display an error message saying something like: "the date doesn't have the correct format. The correct format is dd M yy".

Be aware that the user could really paste anything, even a string like "izeoif zoi"; so you NEED validation anyway.

When the user is the culprit, she should fix her errors (I believe).

It's very common to tell the user that a control is erroneous: for instance I suppose that you know that error message: "The name is required". That's the same idea here.

As @Eric Guan pointed out, you can use tips to help the user getting the idea of your date format in the first place (before she types/pastes anything).

Bigley answered 3/3, 2016 at 19:0 Comment(0)
D
1

The proper thing to do, would be to tell the user what date format is expected and would be valid to input.

This is considered good UX, and is so commonly used that most users would expect it.

Also, you can't possibly parse all kinds of dates inputted, for instance some countries use MM/DD/YYYY while others use DD/MM/YYYY, and who's to say if 01/07/2015 is the seventh of january or the first of july, there's just no way to tell without knowing the format.

As you're using jQuery UI, here's a quick way to validate the datepicker using the built in Tooltip widget

$('#MilestoneStartDate').datepicker({
    dateFormat: 'dd M yy'
}).on({
	change : function() {
        if ( !this.checkValidity() ) {
        	$(this).tooltip({
				close: function( event, ui ) {  ui.tooltip.stop() }
			});
            setTimeout(function(x) { $(x).tooltip('open') }, 0, this);
        } else {
        	$(this).tooltip('destroy');
        }
    }
}).datepicker('setDate', new Date());
.ui-datepicker{ z-index: 999999999!important;}
.ui-tooltip-content {font-size: 14px;}
<link href="https://code.jquery.com/ui/1.11.4/themes/trontastic/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

<p>Type an invalid date</p>
<input id="MilestoneStartDate" pattern="[0-9]{2}\s[a-zA-Z]{3}\s[0-9]{4}" title='valid format is : "10 Mar 2015"' >

Note that the pattern to validate against is added directly to the input, so is the tooltip content.
There's many other ways to do this, if you're using a regular form submit, HTML5 validation would be one option etc. but at the end of the day, requiring that the user inputs a valid date according to the given pattern, is better than trying to deal with all sorts of date formats.

Dictaphone answered 5/3, 2016 at 4:54 Comment(0)
A
0

You can disable the text box from people to edit and place an icon beside it. People need to click the icon and enter the date. So copy paste wont work here.

Appointor answered 3/3, 2016 at 14:17 Comment(0)
C
0

Validation is a good idea. Also you could write your own plugin to change date formats or look at this: https://plugins.jquery.com/formatDateTime/

Cramp answered 4/3, 2016 at 16:2 Comment(0)
W
0

It's better to prevent the user from typing or pasting the dates. Make your date textbox readonly with readonly='readonly'

Weaverbird answered 6/3, 2016 at 14:50 Comment(0)
R
0

You can change the user's date to a valid date when the user finish typing the date,
The function will support every format:

  • d-m-yy or d-m-yyyy

  • d/m/yy or d/m/yyyy

  • d.m.yy or d.m.yyyy

will be displayey as d-m-yyyy

      //initializing the datePicker
       $('#datePickerId').datepicker ({
        format: 'dd-mm-yy',
        shortYearCutoff: 0,
        autoclose: true,
        todayHighlight: true,
      })

        //change to the correct format
         $('#datePickerId').datepicker()
                 .on("hide", function(e) {
                   var temp=e.delegateTarget.firstElementChild.value.split('-');
                   if(temp.length==3 && temp[2].length<=3)
                   {
                    var year;
                    if(temp[2].length==2)
                      year="20";
                      else if(temp[2].length==3)
                        year="2";
                        else year="200";

                    $(e.delegateTarget).datepicker("setDate", new Date(temp[1]+'-'+temp[0]+'-'+year+temp[2]));
                    e.delegateTarget.firstElementChild.value=temp[0]+'-'+temp[1]+'-'+year+temp[2];
                   }
          });
Rostellum answered 4/2, 2019 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.