小虾虎鱼

小虾虎鱼

Knockout中使用MY97日历

作者 禾惠 发表于 2015/08/14,最后修改于 2015/08/14

MY97是一款功能非常强大的日历插件,仅仅官方给出的例子就基本上能够实现我们的开发需求。然而官方给出的例子都针对于DOM,那如何将Knockout与MY97结合在一起使用呢?

Knockout中使用MY97遇到的问题

在Knockout中使用MY97可能会遇到这样一个问题,在input标签上已经已经使用textinput绑定方法,同时也按照MY97官网提供的方法将日历帮在input上,虽然可以选择日期并且input上面能正常的显示所选的日期,但Knockout的textinput绑定的字段始终无法得到所选的日期的值。那么如何在Knockout中获取到MY97所选的日期呢?

Knockout与MY97的结合使用

MY97提供了一些自定义事件,如onpickingonpickedonclearingoncleared等,可以通过这些方法来改变Knockout的值。

同时,MY97也提供了许多内置方法,如:$dp.cal.getP$dp.cal.getNewDateStr等,可以通过$dp.cal.getNewDateStr()方法来获取到所选的日期。

通过上面的方法,我们可以将Knockout与MY97结合起来使用了:

<input type="text" data-bind="textinput:start,click:startPicker" />
<script>
var viewModel = {
    start : ko.observable(),
    startPicker : function () {
        WdatePicker({
            onpicked : function (e) {
                viewModel.start(e.cal.getNewDateStr());
            },
            oncleared : function () {
                viewModel.start("");
            }
        });
    },
};
</script>

日期范围的选择

日期范围的选择在应用中经常用到,如一些查询条件从什么时候到什么时候。

官方的例子通过分别给两个input加个id,然后在显示日历前去获取对方的日期从而来限制该input的选择范围。如开始日期是2015/08/14那么结束时间必须要大于等于开始日期,同理选择开始日期最大的日期不能超过结束日期。

<input type="text" data-bind="textinput:start,click:startPicker" />
<input type="text" data-bind="textinput:end,click:endPicker" />
var viewModel = {
    start : ko.observable(),
    end : ko.observable(),
    startPicker : function () {
        WdatePicker({
            maxDate : '#F{\'' + viewModel.end() + '\'}',
            onpicked : function (e) {
                viewModel.start(e.cal.getNewDateStr());
            },
            oncleared : function () {
                viewModel.start("");
            }
        });
    },
    endPicker : function () {
        WdatePicker({
            minDate : '#F{\'' + viewModel.start() + '\'}',
            onpicked : function (e) {
                viewModel.end(e.cal.getNewDateStr());
            },
            oncleared : function () {
                viewModel.end("");
            }
        });
    }
};

以上方法在4.72版本能正常使用,但在4.8beta版本中第一次选择日期可以约束选择范围,但再次改变日期,日期的约束范围仍然是第一次的约束范围。

经过查找,4.8beta版本在第一次执行WdatePicker后会自动在input上再绑定一次click事件,所以在点击input时MY97添加的事件会先于startPickerendPicker执行,所以在startPickerendPicker再次执行WdatePicker是不起作用的。所以为了能在4.8beta中能正常使用,我们必须要实时的改变maxDateminDate的值,将上面的JS代码稍微修改:

var viewModel = {
    start : ko.observable(),
    end : ko.observable(),
    startPicker : function () {
        WdatePicker({
            vm : viewModel,
            maxDate : '#F{$dp.vm.end()}',
            onpicked : function (e) {
                viewModel.start(e.cal.getNewDateStr());
            },
            oncleared : function () {
                viewModel.start("");
            }
        });
    },
    endPicker : function () {
        WdatePicker({
            vm : viewModel,
            minDate : '#F{$dp.vm.start()}',
            onpicked : function (e) {
                viewModel.end(e.cal.getNewDateStr());
            },
            oncleared : function () {
                viewModel.end("");
            }
        });
    }
};

viewModel对象一并传入给WdatePicker,通过MY97提供的动态变量#F{}执行里面的JS,从而可以实时的拿到另一个日期的变化值。