Search code examples
javascriptjqueryjquery-uijquery-ui-timepicker

How can I stop users from picking an end time that is before the start time


I am using datetimepicker to set values in a form. I have been trying to limit the user from picking an end time that is before the start time. I have tried setting the mindate, hourmin, a new date that is equal to start date, without success. According to what I believe, the following code should work, but it does not.

        <script src="../js/jquery-1.9.1.js"></script>
    <script src="../js/jquery-ui-1.10.3.custom.js"></script>
    <script src="../js/jquery-ui-timepicker-addon.js"></script>
    <script src="../js/jquery-ui-sliderAccess.js"></script>
    <script>

        $(function() 
            {

                var startDateTextBox = $('#startDate');
                var endDateTextBox = $('#endDate');
                var startTimeTextBox = $('#startTime');
                var endTimeTextBox = $('#endTime');
                startDateTextBox.datepicker(
                    {
                        minDate: ("setDate", '',new Date()),
                        hourGrid: 12,
                        minuteGrid: 15,
                        stepMinute: 15,

                        onClose: function(dateText, inst) {
                        if (endDateTextBox.val() != '') 
                        {

                            var testStartDate = startDateTextBox.datetimepicker('getDate');
                            var testEndDate = endDateTextBox.datetimepicker('getDate');
                            if (testStartDate > testEndDate)
                            endDateTextBox.datetimepicker('setDate', testStartDate);

                        }
                        else 
                        {
                            endDateTextBox.val(dateText);
                        }
                        },
                        onSelect: function (selectedDateTime){
                        endDateTextBox.datetimepicker('option', 'minDate', startDateTextBox.datetimepicker('getDate') );
                        }
                    }
                );
                startTimeTextBox.datetimepicker(
                {
                    timeOnly:true,
                    minuteGrid: 15,
                    stepMinute: 15,
                    minDate: ("setTime", '',new Date()),
                    timeFormat: 'hh:mm tt',
                    onClose: function(dateText, inst)
                    {
                        if (endTimeTextBox.val() != '') 
                        {
                        var testStartTime = startTimeTextBox.datetimepicker('getDate');
                        var testEndTime = endTimeTextBox.datetimepicker('getDate');
                        if(testStartTime > testEndTime)
                        endTimeTextBox.timepicker('setTime', testStartTime);
                        }
                        else
                        {
                            endTimeTextBox.val(dateText)
                        }
                    },
                    onSelect: function (selectedDateTime){
                    endTimeTextBox.datetimepicker('setDate', startTimeTextBox.datetimepicker('getDate') );
                    }
                }
                );
                endDateTextBox.datepicker(
                    {
                        hourGrid: 12,
                        minuteGrid: 15,
                        stepMinute: 15,

                        onClose: function(dateText, inst) 
                        {
                            if (startDateTextBox.val() != '') 
                            {
                                var testStartDate = startDateTextBox.datetimepicker('getDate');
                                var testEndDate = endDateTextBox.datetimepicker('getDate');
                                if (testStartDate > testEndDate)
                                startDateTextBox.datetimepicker('setDate', testEndDate);
                            }
                            else 
                            {
                                startDateTextBox.val(dateText);
                            }
                        },
                        onSelect: function (selectedDateTime){
                        startDateTextBox.datetimepicker('option', 'maxDate', endDateTextBox.datetimepicker('getDate') );
                        }
                    }
                );
                endTimeTextBox.datetimepicker(
                {
                    timeOnly:true,
                    minuteGrid: 15,
                    stepMinute: 15,
                    timeFormat: 'hh:mm tt',

                    onClose: function(dateText, inst) 
                    {
                        if (startTimeTextBox.val() != '') 
                        {
                            var testStartTime = startTimeTextBox.datetimepicker('getDate');
                            var testEndTime = endTimeTextBox.datetimepicker('getDate');
                            if (testStartTime > testEndTime)
                            endTimeTextBox.datetimepicker('setDate', testStartTime);
                        }
                        else 
                        {
                            startTimeTextBox.val(dateText);
                        }
                    },
                    onSelect: function (selectedDateTime){
                    startTimeTextBox.datetimepicker('option', 'maxDate', endTimeTextBox.datetimepicker('getDate') );
                    }
                }
                );
            }
        );
    </script>

The logic of the code seems right, so why is it not working? What I have come up with so far is the following:

            $(function() 
        {
            var startDateTextBox = $('#startDate');
            var endDateTextBox = $('#endDate');
            startDateTextBox.datetimepicker(
                {
                    altField:"#startTimeALT",
                    altFieldTimeOnly: true,
                    timeFormat: "h:mm tt",
                    minDate: ("setDate", '',new Date()),
                    hourGrid: 12,
                    minuteGrid: 15,
                    stepMinute: 15,

                    onClose: function(dateText, inst) 
                    {
                        if (endDateTextBox.val() != '') 
                        {
                            var testStartDate = startDateTextBox.datetimepicker('getDate');
                            var testEndDate = endDateTextBox.datetimepicker('getDate');
                            if (testStartDate > testEndDate)
                            endDateTextBox.datetimepicker('setDate', testStartDate);
                        }
                        else 
                        {
                            endDateTextBox.val(dateText);
                        }
                        },
                        onSelect: function (selectedDateTime){
                        endDateTextBox.datetimepicker('option', 'minDate', startDateTextBox.datetimepicker('getDate') );
                    }
                }
                );
                endDateTextBox.datetimepicker(
                    {
                        minDate: ("setDate", '',new Date()),
                        altField:"#endTimeALT",
                        altFieldTimeOnly: true,
                        timeFormat: "h:mm tt",
                        hourGrid: 12,
                        minuteGrid: 15,
                        stepMinute: 15,

                        onClose: function(dateText, inst) 
                        {
                            if (startDateTextBox.val() != '') 
                            {
                                var testStartDate = startDateTextBox.datetimepicker('getDate');
                                var testEndDate = endDateTextBox.datetimepicker('getDate');
                                if (testStartDate > testEndDate)
                                startDateTextBox.datetimepicker('setDate', testEndDate);
                            }
                            else 
                            {
                                startDateTextBox.val(dateText);
                            }
                        },
                        onSelect: function (selectedDateTime){
                        startDateTextBox.datetimepicker('option', 'maxDate', endDateTextBox.datetimepicker('getDate') );
                        }
                    }
                );
            }
        );

In the above code I have separated the date and time fields using the datetimepicker jquery addon. I did this in an attempt to gain better control over the input and how it is stored in the database. I am hoping the will help with my queries and allow easier search and update functions. This is part of a scheduling project written in php with jquery support for user interaction. Any help and suggestions in this endeavor are greatly appreciated!


Solution

  • the idea is right, the problem is how you compare your dates. I have tried calling datepicker("getDate"), which returns a String, I assume this is the same on your datetimepicker plugin.

    The strings you are comparing look like Wed Jun 12 2013 00:00:00 GMT+0200 (CEST) and here the equality is just based on the lexicographical order of the Weekdate.

    But if you use the JavaScript method Date.parse(), you can easily compare those:

    var testStartDate = startDateTextBox.datetimepicker('getDate');
    var testEndDate = endDateTextBox.datetimepicker('getDate');
    if (Date.parse(testStartDate) > Date.parse(testEndDate))
      endDateTextBox.datetimepicker('setDate', testStartDate);
    

    With this gist I have a toy website where you can try your validation, the first date already works: https://gist.github.com/contradictioned/5871967