所需js、css如下:
js:jquery.min.js、jquery-ui.min.js、datepicker-zh-CN.js实现具体到日期,再引入:monthpicker.js实现只能选择年月。使用angular.js实现text文本双向绑定.
css:jquery-ui.min.css、bootstrap.min.css、monthpicker.css。
<!DOCTYPE html>
<html ng-app="test">
<meta charset="UTF-8">
<title>日期插件</title>
<script src="js/jquery.min.js" charset="utf-8"></script>
<script src="jquery-ui/jquery-ui.min.js" charset="utf-8"></script>
<script src="js/datepicker-zh-CN.js" charset="utf-8"></script>
<script src="js/angular.js" charset="utf-8"></script>
<script src="js/monthpicker.js"></script>
<link href="jquery-ui/jquery-ui.min.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/monthpicker.css" rel="stylesheet">
<script type="text/javascript">
let mod = angular.module('test', []);
mod.controller('main', function ($scope) {
$scope.whereMap = {
time1: '',
time2: ''
$("#input1").datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true,
onSelect: function (dataText) {
$scope.whereMap.time1 = dataText;
$scope.timeFocus = function () {
if ($('.monthpicker')) {
$(".monthpicker").remove();
var y;
if ($scope.whereMap.time2) {
var _time = $scope.whereMap.time2.split('-');
y = _time[0];
$('#input2').monthpicker({
selectYears: y ? y : '',
onMonthSelect: function (m, y) {
m = (parseInt(m) + 1);
if (m.toString().length == 1) {
m = '0' + m;
$scope.whereMap.time2 = y + '-' + m;
$scope.$apply();
</script>
</head>
<body ng-controller="main">
<div class="form-horizontal" style="width: 800px;margin: 90px auto;">
<div class="form-group">
<label for="input1" class="col-sm-2 control-label">日期插件1</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="input1" placeholder="请选择时间" ng-model="whereMap.time1"
autocomplete="off">
</div>
</div>
<div class="form-group">
<label for="input2" class="col-sm-2 control-label">日期插件2</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="input2" placeholder="请选择时间" ng-model="whereMap.time2"
ng-focus="timeFocus();">
</div>
</div>
</div>
</body>
</html>
datepicker-zh-CN.js
/* Chinese initialisation for the jQuery UI date picker plugin. */
/* Written by Cloudream (cloudream@gmail.com). */
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "../widgets/datepicker" ], factory );
} else {
// Browser globals
factory( jQuery.datepicker );
}( function( datepicker ) {
datepicker.regional[ "zh-CN" ] = {
closeText: "确定",
prevText: "<上月",
nextText: "下月>",
currentText: "今天",
monthNames: [ "一月","二月","三月","四月","五月","六月",
"七月","八月","九月","十月","十一月","十二月" ],
monthNamesShort: [ "一月","二月","三月","四月","五月","六月",
"七月","八月","九月","十月","十一月","十二月" ],
dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ],
dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ],
dayNamesMin: [ "日","一","二","三","四","五","六" ],
weekHeader: "周",
dateFormat: "yy-mm-dd",
firstDay: 1,
isRTL: false,
showMonthAfterYear: true,
yearSuffix: "年" };
datepicker.setDefaults( datepicker.regional[ "zh-CN" ] );
return datepicker.regional[ "zh-CN" ];
} ) );
monthpicker.js
(function ($, undefined) {
$.fn.monthpicker = function (options) {
// 获取当前年份
var now = new Date().getFullYear(),
_whYears = [];
for (var i = now - 10; i < now + 10; i++) {
_whYears.push(i);
options.years = _whYears;
// 获取当前月份
var nowMonth = new Date().getMonth() + 1;
// 月份所有按钮
var allButtons = [];
var months = options.months || ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
Monthpicker = function (el) {
this._el = $(el);
this._init();
this._render();
this._renderYears();
this._renderMonths();
this._bind();
allButtons = $('.monthpicker table button');
Monthpicker.prototype = {
destroy: function () {
this._el.off('click');
this._yearsSelect.off('click');
this._container.off('click');
$(document).off('click', $.proxy(this._hide, this));
this._container.remove();
_init: function () {
this._el.html(options.years[0] + '-' + months[0]);
this._el.data('monthpicker', this);
_bind: function () {
this._el.on('click', $.proxy(this._show, this));
$(document).on('click', $.proxy(this._hide, this));
this._yearsSelect.on('click', function (e) {
e.stopPropagation();
$('#whSelect').change(function () {
var selectYear = $(this).children('option:selected').val();
$.each(allButtons, function (i, button) {
if (selectYear == now) {
if (nowMonth - 1 == i) {
button.setAttribute('class', 'nowMonth');
} else {
button.setAttribute('class', '');
} else {
button.setAttribute('class', '');
this._container.on('click', 'button', $.proxy(this._selectMonth, this));
_show: function (e) {
e.preventDefault();
e.stopPropagation();
this._container.css('display', 'inline-block');
var currMonth = this._el.attr("month");
if (currMonth) {
$.each(allButtons, function (i, button) {
if (button.innerHTML == currMonth) {
button.setAttribute('class', 'curr');
} else {
button.removeAttribute('class', 'curr');
var selectYear = $("#whSelect").children('option:selected').val();
$.each(allButtons, function (i, button) {
if (now == selectYear) {
if (nowMonth - 1 == i) {
button.classList.add("nowMonth");
} else {
button.classList.remove("nowMonth");
_hide: function () {
this._container.css('display', 'none');
_selectMonth: function (e) {
var monthIndex = $(e.target).data('value'),
month = months[monthIndex],
year = this._yearsSelect.val();
if (this._el.attr('type') == "text") {
this._el.attr("value", year + '-' + month);
} else {
this._el.html(year + '-' + month);
if (options.onMonthSelect) {
this._el.attr("month", month);
options.onMonthSelect(monthIndex, year);
_render: function () {
var boxOffset = this._el.offset(),
cssOptions = {
display: 'none',
position: 'absolute',
top: boxOffset.top + this._el.height() + 15,
left: boxOffset.left
var _dowHeight = $(document).height() - (cssOptions.top);
if (_dowHeight < 135) {
cssOptions.top = boxOffset.top - 135;
this._id = (new Date).valueOf();
this._container = $('<div class="monthpicker" id="monthpicker-' + this._id + '">')
.css(cssOptions)
.appendTo($('body'));
_renderYears: function () {
var markup = $.map(options.years, function (year) {
if (options.selectYears) {
if (options.selectYears == year) {
return '<option selected>' + options.selectYears + '</option>';
} else {
if (now == year) {
return '<option selected>' + year + '</option>';
return '<option>' + year + '</option>';
var yearsWrap = $('<div class="years">').appendTo(this._container);
this._yearsSelect = $('<select id="whSelect">').html(markup.join('')).appendTo(yearsWrap);
_renderMonths: function () {
var markup = ['<table>', '<tr>'];
$.each(months, function (i, month) {
if (i > 0 && i % 4 === 0) {
markup.push('</tr>');
markup.push('<tr>');
markup.push('<td><button data-value="' + i + '">' + month + '</button></td>');
markup.push('</tr>');
markup.push('</table>');
this._container.append(markup.join(''));
var methods = {
destroy: function () {
var monthpicker = this.data('monthpicker');
if (monthpicker) monthpicker.destroy();
return this;
if (methods[options]) {
return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof options === 'object' || !options) {
return this.each(function () {
return new Monthpicker(this);
} else {
$.error('Method ' + options + ' does not exist on monthpicker');
}(jQuery));
monthpicker.css
.monthpicker {
border: 1px solid #c5c5c5;
padding: .2em .2em 0;
z-index: 1000;
background: #fff;
.monthpicker .years {
background-color: #e9e9e9;
padding: .2em 0;
border: 1px solid #ddd;
text-align: center;
.monthpicker .years select {
font-size: 1em;
width: 70%;
.monthpicker .years select:focus {
outline: none;
.monthpicker table {
border-collapse: collapse;
table-layout: fixed;
margin: .4em 0;
.monthpicker td {
padding: .1em;
.monthpicker table button {
width: 100%;
font-size: .8em;
padding: .6em;
cursor: pointer;
transition: background .2s;
border: 1px solid #c5c5c5;
background: #f6f6f6;
font-weight: normal;
color: #454545;
.monthpicker table button:hover {
background: #ededed;
.monthpicker table button:focus {
outline: none;
.monthpicker table button.curr,
.monthpicker table button.curr:hover {
background: #007fff;
color: #fff;
.monthpicker table button.nowMonth,
.monthpicker table button.nowMonth:hover {
background: #fffa90;
git地址:地址
本博客文章大多为原创,转载请请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。