依赖日期选择器使用html选择和日期有意义

Ton*_*bet 9 html javascript usability jquery date

我正在尝试构建一个自定义的START和END日期选择器,但不幸的是因为我不能使用jquery UI Datepicker的设计,所以我被困在3 <select>秒中分割日期的旧时尚

为了保持此功能的可用性,我们发现这至少是复杂的部分:

  • 让每个月的日子都有意义(不要想要31个可选的,...)
  • 从START到END选择器设置下一个

所以我认为最好将日期计算委托给javascript Date()对象,所以至少我可以抽象那部分.

我快到了,

但是一些Date()对象如何告诉正确的日期,但两个选择器都显示前一个的每天天数(例如,前三十天发生在三月而不是FEB)

    $(function(){

months = ['jan','feb','mar','apr','may','jun','jul','ago','sep','oct','nov','dec'];
        /* Cachear selects */
        var $ld = $('select[name=llegada-dia]');
        var $lm = $('select[name=llegada-mes]');
        var $ly = $('select[name=llegada-ano]');
        var $sd = $('select[name=salida-dia]');
        var $sm = $('select[name=salida-mes]');
        var $sy = $('select[name=salida-ano]');
        var manyDays = function( month, year ){
            var fecha = new Date(year, (month) , 0);
            return fecha.getDate();
        }
        var paintCals = function( day, month , year ){
            if(day == '') day = 1;
            if(month == '') month = 0;
            if(year == '' ) year = 2013;
            //month = month -1;
            var fecha = new Date( year, month , day );          
            var dia = fecha.getDate();
            var mes = fecha.getMonth();
            var anyo = fecha.getFullYear();
            var dias_mes = manyDays( mes,anyo );
            /* Generate next date = fecha + 1 */
            var next_fecha = fecha;

            next_fecha.setDate(next_fecha.getDate() + 1); 
            next_fecha.setMonth(fecha.getMonth() + (dia == dias_mes ? 1 : 0)   ); 
            next_fecha.setFullYear(fecha.getFullYear() + (mes == 12 ? 1 : 0)  ); 

            var next_dia = next_fecha.getDate();
            var next_mes = next_fecha.getMonth();
            var next_anyo = next_fecha.getFullYear();
            var next_dias_mes = manyDays( next_mes, next_anyo ) ;
            $ld.empty();
            for(var tmpdia = 1; tmpdia <= dias_mes; tmpdia++){
                var doption = $('<option>').attr( 'value',tmpdia )
                                           .text( tmpdia );
                if(dia == tmpdia && dia != ''){
                    doption.attr('selected', 'selected');
                }
                $ld.append(doption);
            }
            /* Actualizar dias salida */
            $sd.empty();
            for(var tmpdia = next_dia; tmpdia <= next_dias_mes; tmpdia++){
                var doption = $('<option>').attr( 'value' , tmpdia )
                                           .text(tmpdia);
                if(next_dia == tmpdia && next_dia != ''){
                    doption.attr('selected', 'selected');
                }
                $sd.append(doption);
            }
            /* Actualizar meses salida */
            $sm.empty();
            for(var tmpmes = next_mes ; tmpmes < 12; tmpmes++){
                var doption = $('<option>').attr('value',tmpmes)
                                           .text(months[tmpmes]);
                if(dia == tmpdia && dia != ''){
                    doption.attr('selected', 'selected');
                }
                $sm.append(doption);
            }
            /* Actualizar anyos salida */
            $sy.empty();
            for(var tmpanyo = next_anyo; tmpanyo <= 2020; tmpanyo++){
                var doption = $('<option>').attr('value',tmpanyo)
                                           .text(tmpanyo);
                if(next_anyo == tmpanyo && next_anyo != ''){
                    doption.attr('selected', 'selected');
                }
                $sy.append(doption);
            }
        } 
        $('.arrival select').on('change',function(){
            var ldia = $ld.val();
            var lmes = $lm.val();
            var lano = $ly.val();
            var ldias = paintCals(ldia,lmes,lano);
        });
    })
Run Code Online (Sandbox Code Playgroud)

在这里它可以摆弄:

http://jsfiddle.net/96qyH/8/

知道我在这里缺少什么吗?

Sel*_*gam 1

编辑:重构一些代码以删除额外的逻辑

我使用了三个实用函数来更新开始和结束日期下拉列表。

  1. daysInMonth- 获取一年中指定月份的天数
  2. adjustDates- 根据所选月份更新下拉列表中的天数。注意:这只是添加/删除选项,而不是从头开始重建。
  3. resetDates- 重置开始月份和年份

我重写了您的代码并尝试实现与演示代码中相同的逻辑。查看我的演示,让我知道它是否适合您。

演示: http: //jsfiddle.net/ByWhz/1/

完整代码:

$(function () {
    months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dec'];

    /* Cachear selects */
    var $ld = $('select[name=llegada-dia]');
    var $lm = $('select[name=llegada-mes]');
    var $ly = $('select[name=llegada-ano]');
    var $sd = $('select[name=salida-dia]');
    var $sm = $('select[name=salida-mes]');
    var $sy = $('select[name=salida-ano]');

    //http://stackoverflow.com/a/1184359/297641
    function daysInMonth(month, year) {
        return new Date(year, month, 0).getDate();
    }

    function adjustDates(selMonthDates, $sel) {
        var $options = $sel.find('option');
        var dates = $options.length;
        //append/remove missing dates
        if (dates > selMonthDates) { //remove
            $options.slice(selMonthDates).remove();
        } else { //append
            var dateOptions = [];
            for (var date = dates + 1; date <= selMonthDates; date++) {
                dateOptions.push('<option value="' + date + '">' + date + '</option>');
            }
            $sel.append(dateOptions.join('')); //reduces DOM call
        }
    }

    function resetDates() {
        $lm.val(function (i, v) {
            return (v == '') ? '0' : v;
        });
        $ly.val(function (i, v) {
            return (v == '') ? '2013' : v;
        });
    }

    var paintCals = function (day, month, year) {

        resetDates();

        //adjust start date
        var selMonthDates = daysInMonth((parseInt($lm.val(), 10) + 1), $ly.val());
        adjustDates(selMonthDates, $ld);

        //If current day selection > number of days in selected month then set the day to max allowed day
        if (day > selMonthDates) {
            day = selMonthDates;
            $ld.val(day); //update selection
        }

        //selected start date
        var selectedDate = new Date(year, month, day);

        //next day from start date
        var nextDay = new Date(selectedDate.getTime() + 86400000);

        //lets build the end year drop down
        var tmpArr = [];
        for (var yrs = parseInt(nextDay.getFullYear(), 10); yrs <= 2020; yrs++) {
            tmpArr.push('<option value="' + yrs + '">' + yrs + '</option>');
        }
        $sy.empty().append(tmpArr.join('')); //set the YEARS
        //simply set the month
        $sm.val(nextDay.getMonth()); //set the month

        //adjust end date
        selMonthDates = daysInMonth(parseInt(nextDay.getMonth(), 10) + 1, nextDay.getFullYear());
        adjustDates(selMonthDates, $sd);

        $sd.val(nextDay.getDate()); //set the date

        $('#log').empty().append('Fecha: ' + selectedDate).append('<br>');
        $('#log').append('Siguiente: ' + nextDay);
    }

    $('.arrival select').on('change', function () {
        var ldia = $ld.val();
        var lmes = $lm.val();
        var lano = $ly.val();
        //console.log('lD/lM/lY:'+ldia,lmes,lano);

        var ldias = paintCals(ldia, lmes, lano);
    });
});
Run Code Online (Sandbox Code Playgroud)