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?

leora
  • 188,729
  • 360
  • 878
  • 1,366
  • http://stackoverflow.com/questions/4347483/jquery-datepicker-that-supports-multiple-formats. The second answer is an implementation that allows multiple formats, hope it helps – Liviu Boboia Feb 22 '16 at 13:17
  • 3
    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. – Eric Guan Feb 29 '16 at 01:08
  • @Eric Guan - can you show by an example what you mean – leora Feb 29 '16 at 05:02
  • http://ux.stackexchange.com/questions/1232/most-user-friendly-form-fields-for-entering-date-time – Eric Guan Feb 29 '16 at 05:06

7 Answers7

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.

Mayur Patel
  • 1,741
  • 15
  • 32
  • 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. – Borys Serebrov Mar 04 '16 at 23:26
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).

ling
  • 9,545
  • 4
  • 52
  • 49
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.

adeneo
  • 312,895
  • 29
  • 395
  • 388
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.

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/

Koustav Ray
  • 1,112
  • 13
  • 26
0

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

Santosh Jadi
  • 1,479
  • 6
  • 29
  • 55
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];
                   }
          });
Batsheva Hansav
  • 316
  • 2
  • 11