跨日期选取器默认日期问题

Cross date picker default date issue

本文关键字:日期 问题 默认 选取      更新时间:2023-09-26

hello all我正在使用以下js代码将输入类型date转换为三个不同的文本框,分别为day、month和year。

js

(function () {
var sign = function(x) {
    return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
};
//  TODO Calcular año bisiesto
var bisiesto = function(year)
{
    return true;
//    return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 1 : 0;
};
$.fn.insertAt = $.fn.insertAt || function(index, $parent) {
    return this.each(function() {
        if (index === 0) {
            $parent.prepend(this);
        } else {
            $parent.children().eq(index - 1).after(this);
        }
    });
};
var Crossdp = function(e, o) {
    if (e.data("cross-datepicker")) {
        return this;
    }
    e.attr("type", "text");
    o = $.extend({}, $.fn.cdp.defaults, o);
    if(o.hideInput)
        e.hide();
    var cnt = $("<div>").addClass(o.classes.container || "").data("input", e).insertBefore(e);
    //  Data
    var days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    //  Read format        
    var d = $("<select>").addClass(o.classes.controls || "").addClass(o.classes.days || ""),
        m = $("<select>").addClass(o.classes.controls || "").addClass(o.classes.months || ""),
        y = $("<select>").addClass(o.classes.controls || "").addClass(o.classes.year || "");
    /**
     *  Gets the format metadata.
     */
    var getFormat = function(format) {
        var f = {},
            last = "",
            order = 0,
            elements = {
                "d": d,
                "m": m,
                "y": y
            };
        for(var i = 0, of=format; i < of.length; i++) {
            var c = of[i];
            if(last == c) {
                f[c].count ++;
            }
            else if(c == "d" || c == "y" || c == "m") {
                f[c] = {
                    "count": 1,
                    "order": order++,
                    "e": elements[c]
                };
                elements[c].data("order", f[c].order);
                last = c;
            }
            if(order > 3) {
                throw "Invalid date format";
            }
        }
        return f;
    };
    var iF = getFormat(o.inputFormat),
        f = getFormat(o.format);
    for(var i in f) {
        f[i].e.appendTo(cnt);
    }
    cnt.sort(function(a, b) {
        if(a.data("order") > b.data("order")) {
            return 1;
        }
        else if(a.data("order") < b.data("order")) {
            return -1;
        }
        else {
            return 0;
        }
    });
    //  Helpers
    /**
     *  Format a numeric day to string.
     */
    var formatDay = function(day, format) {
        var text = String(day),
            c = format || f.d.count;
        while(c > text.length) {
            text = "0" + text;
        }
        return text;
    };
    /**
     *  Format a numeric month to string.
     */
    var formatMonth = function(month, format) {
        if(month > 12) {
            throw "Invalid month: "+month;
        }
        var c = format || f.m.count,
            text = String(month);
        if(c == 2) {
            if(text.length == 1) {
                text = "0" + text;
            }
        }
        else if(c == 3) {
            text = o.months[i-1].substr(0, 3);
        }
        else if(c == 4) {
            text = o.months[i-1];
        }
        else {
            throw "Invalid month format";
        }
        return text;
    };
    /**
     *  Format a numeric month to string.
     */ 
    var formatYear = function(year, format) {
        var text = String(year),
            c = format || f.y.count;
        if(c == 2) {
            text = text.substr(text.length-2, 2);
        }
        else if(c != 4) {
            throw "Invalid year format";
        }
        return text;
    };
    var parseYear = function(date, format) {
        //  TODO
    };
    //  Update input function
    var formatDate = function(resultFormat, readFormat, years, months, days) {
        var a = ["d", "m", "y"],
            result = resultFormat;
        if(typeof days === 'string') 
            days = parseInt(days);
        if(typeof months === 'string') 
            months = parseInt(months);
        if(typeof years === 'string') 
            years = parseInt(years);
        for(var i = 0; i < a.length; i++) {
            var ch = a[i],                      /*  Example: a[0]='d'      */
                format = readFormat[ch],        /*  Example: uF['d']='dd'     */
                word = "",
                formatted = "";
            for(var j = 0; j < format.count; j++) {
                word += ch;
            }
            if(ch == "d") {
                formatted = formatDay(days, format.count);
            }
            else if(ch == "m") {
                formatted = formatMonth(months, format.count);
            }
            else {
                formatted = formatYear(years, format.count);
            }
            result = result.replace(word, formatted);                
        }
        return result;
    };
    var updateInput = function() {        
        e.val(formatDate(o.inputFormat, iF, y.val(), m.val(), d.val()));            
    };
    this.updateInput = function() {
        updateInput();
    };
    var updateFromInput = function() {        
        //  TODO
    };
    //  Generate 3 selects
    /*  Days    */
    d.data("days", 0);
    /**
     *  Days of determinated month.
     */
    var generateDays = function(month) {
        if(d.data("days") == days[month-1]) {
            return;
        }
        var selected = parseInt(d.val() || "1");
        d.html("");
        if(month == 0) {
            return;
        }
        if(o.addNullOption) {
            d.append("<option value=''>"+o.nullOptionText+"</option>");
        }
        for(var i = 1; i <= days[month-1]; i++) {
            $("<option>").attr("value", i).text(formatDay(i)).appendTo(d);
        }
        d.val(selected);
    };
    d.change(function() {
        updateInput();
    });
    generateDays(1);
    /*  Months  */
    m.change(function() {
        //  Regenerate days
        generateDays(parseInt($(this).val()));
        updateInput();
    });
    if(o.addNullOption) {
        m.append("<option value='0'>"+o.nullOptionText+"</option>");
    }
    for(var i = 1; i <= 12; i++) {
        m.append("<option value='"+i+"'>"+formatMonth(i)+"</option>");
    }
    /*  Years   */
    var from,
        to;
    if(typeof o.years[0] == 'string') {
        var current = new Date().getFullYear(),
            count;
        if(o.years.length == 3) {
            current += o.years[1];
            count = o.years[2];
        }
        else {
            count = o.years[1];
        }
        for(var i = current; i != current + count; i += sign(count)) {
            y.append("<option value='"+i+"'>"+formatYear(i)+"</option>");
        }
    }
    else {
        for(var i = o.years[0]; i != o.years[1]; i += sign(o.years[1]-o.years[0])) {
            y.append("<option value='"+i+"'>"+formatYear(i)+"</option>");
        }
    }
    y.change(function() {
        updateInput();
    });
    //  Save
    this.inputs = {
        d: d,
        y: y,
        m: m
    };
    //  Finish
    if(e.data("initial-day")) {
        $(function() {
            $.fn.cdp.statics.fns.set(e, [
                e.data("initial-year"), 
                e.data("initial-month"), 
                e.data("initial-day")]);
        });
    }
    updateInput();
    e.data("cross-datepicker", this);
};
$.fn.cdp = function (o, arg) {
    var e = $(this);
    if (e.length == 0) {
        return this;
    }
    else if (e.length > 1) {
        e.each(function () {
            $(this).cdp(o);
        });
        return this;
    }
    if(!e.is("input")) {
        throw "You can apply Cross-DatePicker only on an 'input' element";
    }
    if(typeof o === 'string') {
        var st = $.fn.cdp.statics;
        if(!st.fns[o]) {
            console.error("Unknown function "+o);
        }
        st.fns[o](e, arg);
        return this;
    }
    var cdp = new Crossdp(e, o);
    return this;
}
$.fn.cdp.defaults = {
    hideInput: true,
    format: "d/mmm/yyyy",
    inputFormat: "yyyy-mm-dd",
    years: ["now", -100],    //  [initial year, final year] or ["now", relative years count] or ["now", relative years from, relative years count]
    months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
    addNullOption: false,
    nullOptionText: "Select",
    classes: {
        container: "cdp-container",
        controls: "cdp-select",
        days: "cdp-d",
        months: "cdp-m",
        years: "cdp-y"
    }
};
$.fn.cdp.statics = {
    fns: {
        set: function(e, arg) {
            var st = $.fn.cdp.statics,
                obj = e.data("cross-datepicker"),
                y,m,d;
            if($.isArray(arg)) {
                y = arg[0];
                m = arg[1];
                d = arg[2];
            }
            else if(typeof arg === 'string') {
                var array = arg.split("-");
                y = parseInt(array[0]);
                m = parseInt(array[1]);
                d = parseInt(array[2]);
            }
            else {
                y = arg.year || arg.y;
                m = arg.month || arg.m;
                d = arg.day || arg.d;
            }
            obj.inputs.y.val(String(y));
            obj.inputs.m.val(String(m));
            obj.inputs.d.val(String(d));
            obj.updateInput();                
        }
    }
};
})();

如何实现

html

<input type="date" data-initial-day="20" data-initial-year="2010" data-initial-month="64" />
<!-- Required scripts -->
<script src='https://code.jquery.com/jquery-2.1.0.min.js'></script>
<script src='../src/cross-datepicker.js'></script>
<script>
$(function() {
    $("input[type='date']").cdp();
});
</script>

问题是,当为月份和日期定义数据初始年份时,代码也能很好地工作,但当我想显示默认的无选择日期,如选择日期选择月份和选择年份时,它显示为空白或0。

我不知道如何解决这个问题。我试图通过在js文件中添加一些文本来解决这个问题,但没有帮助。

如果你能给我一些建议,那就太好了。

插件代码需要在设置条目之前检查条目是否有效。

首先,将addNullOption设置为true,以使"选择"文本可见。

$(function() {
    $("input[type='date']").cdp({
        addNullOption : true,
        nullOptionText: "Select"
    });
});

然后用下面包含的"检查有效"代码修改最后一个函数$.fn.cdp.statics(演示):

$.fn.cdp.statics = {
    fns: {
        set: function(e, arg) {
            var st = $.fn.cdp.statics,
                obj = e.data("cross-datepicker"),
                y,m,d;
            if($.isArray(arg)) {
                y = arg[0];
                m = arg[1];
                d = arg[2];
            }
            else if(typeof arg === 'string') {
                var array = arg.split("-");
                y = parseInt(array[0]);
                m = parseInt(array[1]);
                d = parseInt(array[2]);
            }
            else {
                y = arg.year || arg.y;
                m = arg.month || arg.m;
                d = arg.day || arg.d;
            }
            // check valid
            if ( obj.inputs.y.find('option[value="' + y + '"]').length ) {
                obj.inputs.y.val(String(y));
            }
            if ( obj.inputs.m.find('option[value="' + m + '"]').length ) {
                obj.inputs.m.val(String(m));
            }
            if ( obj.inputs.d.find('option[value="' + d + '"]').length ) {
                obj.inputs.d.val(String(d));
            }
            obj.updateInput();
        }
    }
};

为了在其他选择中显示"选择",我添加了以下代码,因为年份选择没有空选项:

if (o.addNullOption) {
    y.append("<option value='0'>"+o.nullOptionText+"</option>");
}

并将"检查有效"代码更改为:

// check valid
y = obj.inputs.y.find('option[value="' + y + '"]').length ? y : 0;
obj.inputs.y.val(String(y));
m = obj.inputs.m.find('option[value="' + m + '"]').length ? m : 0;
obj.inputs.m.val(String(m));
d = obj.inputs.d.find('option[value="' + d + '"]').length ? d : 0;
obj.inputs.d.val(String(d));

从这个更新的演示中获取完整的代码。