This is a migrated thread and some comments may be shown as answers.

Minimal Text Entry of Date

7 Answers 279 Views
Calendar, DateTimePicker, TimePicker and Clock
This is a migrated thread and some comments may be shown as answers.
Andrew Powrie
Top achievements
Rank 1
Andrew Powrie asked on 15 Feb 2012, 02:46 AM
Have recently upgraded to 2011 Q3 SP1 and have noticed a change in the behaviour of the DateTimePicker when entering a date manually (using the format "dd/MM/yyyy"). Previously when you entered "1/1/1" into a blank DateTimePicker the result would be "01/01/2001" as the initial key press in each section would overwrite the whole section. The behaviour has now changed so the initial keypress only adds to the right of each section, so "1/1/1" results in "11/11/9001" (as it edits the null date instead of overwriting it).

Is there anything I can do so it goes back to the old behaviour?  It is essential for our users to enter dates in with as minimal keystrokes as possible.

7 Answers, 1 is accepted

Sort by
0
Peter
Telerik team
answered on 17 Feb 2012, 02:36 PM
Hi Andrew,

Thank you for writing.

We have changed the input behavior in Q2 2011, because we want to have a strictly validated date in every moment in which the user types.

When you start typing, the DateTimePicker will append the typed number to the initial value of the year- in your case 0001. So if you want to enter 0015, you should press 5 and this will concatenate 1 and 5, the result will be 0015.

As a workaround for your case, you can set the initial value for the year to 200 - in this case when user types 1, the result will be 2001.

Please refer to the code below:
this.radDateTimePicker1.NullableValue = new DateTime(200,12,29);//this will set the base date for the editor – user typing will be appended to these numbers
this.radDateTimePicker1.NullableValue = null; //this line will clear the text from the editor

Let me know if this is this an applicable solution in your case - if not, I will try to find another solution based on KeyPress or Validate event.

Regards,
Peter
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Andrew Powrie
Top achievements
Rank 1
answered on 19 Feb 2012, 11:08 PM

I'm sorry but that is not a solution at all.  What if the user wants to enter 11 for 2011? It doesn’t even address the issue of the end user trying to enter a single digit day or month.

Your comment that "We have changed the input behaviour in Q2 2011, because we want to have a strictly validated date in every moment in which the user types" does not make sense. The new behaviour is more likely to lead to invalid dates being entered (as 0015 is not valid as opposed to the original behaviour interpreting this as 2015). 

The new behaviour also leads to a lot more end user confusion, as your date control does not behave like a standard date control. Date controls are expected to handle partial date entry. This control used to work perfectly fine. Why did it have to change?




0
Peter
Telerik team
answered on 21 Feb 2012, 04:27 PM
Hi Andrew,

Thank you for your feedback.

For Q2 2011 we had completely rewritten our RadMaskedEditBox in order to fix a few shortcomings.
In this version we do not allow incomplete input of the date - e.g. value is always equal with user input.
I would like to propose a workaround for your case. Check the year OnValidate event to and if it smaller than 2000, then add 2000 to year:
this.radDateTimePicker1.NullableValue = new DateTime(20, 1, 1);        
this.radDateTimePicker1.NullableValue = null;          
this.radDateTimePicker1.Validated += new EventHandler(radDateTimePicker1_Validated);
 
 
void radDateTimePicker1_Validated(object sender, EventArgs e)
{
          if (this.radDateTimePicker1.Value.Year < 2000)
            {
                int lastDigits = int.Parse(this.radDateTimePicker1.Value.ToString("yy"));
                this.radDateTimePicker1.Value = new DateTime(lastDigits + 2000, this.radDateTimePicker1.Value.Month, this.radDateTimePicker1.Value.Day);           
            }
}

I hope this helps. Do not hesitate to contact us if you have other questions.

Greetings,
Peter
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Andrew Powrie
Top achievements
Rank 1
answered on 22 Feb 2012, 01:13 AM

I'm sorry but that is still not a solution.  It still doesn’t address the issue of the end user trying to enter a single digit day or month. Tab onto an empty date control and enter 2/2/76 for 02/02/1976 and you will get and invalid date or with your fix 12/12/2076. It also doesn't address editing of dates. When trying to change 01/01/1999 to 01/01/2001, previously you initially pressed 1 on the year section and it worked, now you get 01/01/9991. They only way to use this control when editing to to fully type out all 8 digits, which is not the natual way to do things when you only want to change a single date part.

Shouldn't the date control behave in the same way as Microsoft's date control? What has been your experience setting and editing dates with your control on a day to day basis?

The only way I can think of working around this is to handle the keypress event. If it is determined that this is the first keypress in a date part (either from giving the control focus or changing from another date part within the same control), then padleft the required number of 0's and then add the keypress (is there an easy way to determine which dart part is being changed?). On validation if the year is >= 50 and <= 99 then add 1900, else if the year is >= 500 and <= 999 then add 1000, else if the year is < 50 or if the year is > 99 and < 500 then add 2000.


0
Peter
Telerik team
answered on 24 Feb 2012, 03:23 PM
Hi Andrew,

Thank you for your suggestions.

We plan to implement such functionality in one of our future releases. Please refer to the code below which demonstrates how you can handle the key-press event and how to detect if the key-press is in the year part:

public Form1()
    {
        InitializeComponent();
 
        this.radDateTimePicker1.Value = DateTime.MinValue.AddDays(1);  
        this.radDateTimePicker1.KeyPress += new KeyPressEventHandler(radDateTimePicker1_KeyPress);
          
    }
 
    void radDateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
    {
        MaskDateTimeProvider provider = (MaskDateTimeProvider)this.radDateTimePicker1.DateTimePickerElement.TextBoxElement.Provider;
        if (provider.List[provider.SelectedItemIndex].type == PartTypes.Year)
        {
            MaskPart part = provider.List[provider.SelectedItemIndex];
            int len = part.value.ToString().Length;
            if (len >= 2)
            {
                part.value = int.Parse(part.value.ToString().Substring(len - 2, 2));
            }
            if (part.value >= 50 && part.value <= 99)
            {
                part.value += 1900;
            }
            else if (part.value >= 500 && part.value <= 999)
            {
                part.value += 1000;
            }
            else if (part.value < 50 || (part.value > 99 && part.value < 500))
            {
                part.value += 2000;
            }
 
            radDateTimePicker1.Value = new DateTime(part.value, radDateTimePicker1.Value.Month, radDateTimePicker1.Value.Day, radDateTimePicker1.Value.Hour, radDateTimePicker1.Value.Minute, radDateTimePicker1.Value.Second);
        }
    }

I hope you find this information helpful.

Greetings,
Peter
the Telerik team
RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
0
Andrew Powrie
Top achievements
Rank 1
answered on 06 Mar 2012, 03:15 AM
public class MyRadDateTimePicker : RadDateTimePicker
{
    private PartTypes lastPart = PartTypes.ReadOnly;
    public MyRadDateTimePicker()
        : base()
    {
        this.CustomFormat = "dd/MM/yyyy";
        this.Format = DateTimePickerFormat.Custom;
        this.NullText = "Select Date";
        this.KeyPress += new KeyPressEventHandler(_KeyPress);
    }
    public override string ThemeClassName
    {
        get
        {
            return typeof(RadDateTimePicker).FullName;
        }
    }
    private void _KeyPress(object sender, KeyPressEventArgs e)
    {
        MaskDateTimeProvider provider = (MaskDateTimeProvider)this.DateTimePickerElement.TextBoxElement.Provider;
        PartTypes currPart = provider.List[provider.SelectedItemIndex].type;
        if (Char.IsDigit(e.KeyChar) && currPart != this.lastPart && Int32.Parse("" + e.KeyChar) != 0 && (currPart == PartTypes.Year || currPart == PartTypes.Month || currPart == PartTypes.Day))
        {
            if (provider.List[provider.SelectedItemIndex].type == PartTypes.Year)
            {
                this.Value = new DateTime(2000 + Int32.Parse("" + e.KeyChar), this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
            }
            else if (provider.List[provider.SelectedItemIndex].type == PartTypes.Month)
            {
                this.Value = new DateTime(this.Value.Year, Int32.Parse("" + e.KeyChar), this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                if (this.Value == this.NullDate)
                {
                    this.Value = new DateTime(DateTime.Now.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
            }
            else if (provider.List[provider.SelectedItemIndex].type == PartTypes.Day)
            {
                this.Value = new DateTime(this.Value.Year, this.Value.Month, Int32.Parse("" + e.KeyChar), this.Value.Hour, this.Value.Minute, this.Value.Second);
                if (this.Value == this.NullDate)
                {
                    this.Value = new DateTime(DateTime.Now.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
            }
            this.lastPart = currPart;
        }
        else if (Char.IsDigit(e.KeyChar) && currPart == this.lastPart && currPart == PartTypes.Year && this.Value.Year < 1000)
        {
            if (this.Value.Year >= 50 && this.Value.Year <= 99)
            {
                this.Value = new DateTime(1900 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
            }
            else if (this.Value.Year >= 900 && this.Value.Year <= 999) // anything less than 1900 generates an invalid date
            {
                this.Value = new DateTime(1000 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
            }
            else
            {
                this.Value = new DateTime(2000 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
            }
        }
    }
}
This is what I have implemented so far to get the behaviour I am looking for.
0
Peter
Telerik team
answered on 08 Mar 2012, 04:14 PM
Hello Andrew,

Thank you for sharing your solution with the community. 

We plan to implement similar functionality in our next release.

I have updated your Telerik points accordingly. 

Greetings,
Peter
the Telerik team
RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
Tags
Calendar, DateTimePicker, TimePicker and Clock
Asked by
Andrew Powrie
Top achievements
Rank 1
Answers by
Peter
Telerik team
Andrew Powrie
Top achievements
Rank 1
Share this question
or