Add datetimepicker
This commit is contained in:
parent
0d6d531e8b
commit
4e57c4c28d
|
@ -0,0 +1,387 @@
|
||||||
|
/**
|
||||||
|
* @license angular-bootstrap-datetimepicker version: 0.3.8
|
||||||
|
* (c) 2013-2014 Knight Rider Consulting, Inc. http://www.knightrider.com
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
.datetimepicker {
|
||||||
|
padding: 4px;
|
||||||
|
margin-top: 1px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
direction: ltr;
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.datetimepicker-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.datetimepicker-rtl table tr td span {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown"]:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-bottom: 7px solid #ccc;
|
||||||
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown"]:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid #ffffff;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown-top"]:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-top: 7px solid #ccc;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.2);
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown-top"]:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid #ffffff;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-left:before {
|
||||||
|
top: -7px;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-left:after {
|
||||||
|
top: -6px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-right:before {
|
||||||
|
top: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-right:after {
|
||||||
|
top: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-left:before {
|
||||||
|
bottom: -7px;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-left:after {
|
||||||
|
bottom: -6px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-right:before {
|
||||||
|
bottom: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-right:after {
|
||||||
|
bottom: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker > div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.minutes div.datetimepicker-minutes {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.hours div.datetimepicker-hours {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.days div.datetimepicker-days {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.months div.datetimepicker-months {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.years div.datetimepicker-years {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker .table td,
|
||||||
|
.datetimepicker .table th {
|
||||||
|
text-align: center;
|
||||||
|
width: 14.6%;
|
||||||
|
height: 20px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.datetimepicker .table-striped > tbody > tr:nth-child(odd) > td, .datetimepicker .table-striped > tbody > tr:nth-child(odd) > td,
|
||||||
|
.datetimepicker .table-striped > tbody > tr:nth-child(odd) > td, .datetimepicker .table-striped > tbody > tr:nth-child(odd) > th,
|
||||||
|
.datetimepicker .table-striped > tbody > tr:nth-child(odd) {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.datetimepicker table tr td.minute:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.hour:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.day:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.past,
|
||||||
|
.datetimepicker table tr td.future {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.disabled,
|
||||||
|
.datetimepicker table tr td.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today,
|
||||||
|
.datetimepicker table tr td.today:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover {
|
||||||
|
background-color: #fde19a;
|
||||||
|
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||||
|
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||||
|
border-color: #fdf59a #fdf59a #fbed50;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today:hover,
|
||||||
|
.datetimepicker table tr td.today:hover:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td.today:active,
|
||||||
|
.datetimepicker table tr td.today:hover:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.today.active,
|
||||||
|
.datetimepicker table tr td.today:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled.active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled,
|
||||||
|
.datetimepicker table tr td.today:hover.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td.today[disabled],
|
||||||
|
.datetimepicker table tr td.today:hover[disabled],
|
||||||
|
.datetimepicker table tr td.today.disabled[disabled],
|
||||||
|
.datetimepicker table tr td.today.disabled:hover[disabled] {
|
||||||
|
background-color: #fdf59a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today:active,
|
||||||
|
.datetimepicker table tr td.today:hover:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.today.active,
|
||||||
|
.datetimepicker table tr td.today:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled.active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.active {
|
||||||
|
background-color: #fbf069 \9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active,
|
||||||
|
.datetimepicker table tr td.active:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active:hover,
|
||||||
|
.datetimepicker table tr td.active:hover:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td.active:active,
|
||||||
|
.datetimepicker table tr td.active:hover:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.active.active,
|
||||||
|
.datetimepicker table tr td.active:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled.active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled,
|
||||||
|
.datetimepicker table tr td.active:hover.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td.active[disabled],
|
||||||
|
.datetimepicker table tr td.active:hover[disabled],
|
||||||
|
.datetimepicker table tr td.active.disabled[disabled],
|
||||||
|
.datetimepicker table tr td.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active:active,
|
||||||
|
.datetimepicker table tr td.active:hover:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.active.active,
|
||||||
|
.datetimepicker table tr td.active:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled.active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.active {
|
||||||
|
background-color: #003399 \9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span {
|
||||||
|
display: block;
|
||||||
|
width: 23%;
|
||||||
|
height: 54px;
|
||||||
|
line-height: 54px;
|
||||||
|
float: left;
|
||||||
|
margin: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker span.hour {
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker span.minute {
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.disabled,
|
||||||
|
.datetimepicker table tr td span.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active,
|
||||||
|
.datetimepicker table tr td span.active:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active:hover,
|
||||||
|
.datetimepicker table tr td span.active:hover:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td span.active:active,
|
||||||
|
.datetimepicker table tr td span.active:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.active,
|
||||||
|
.datetimepicker table tr td span.active:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled,
|
||||||
|
.datetimepicker table tr td span.active:hover.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td span.active[disabled],
|
||||||
|
.datetimepicker table tr td span.active:hover[disabled],
|
||||||
|
.datetimepicker table tr td span.active.disabled[disabled],
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active:active,
|
||||||
|
.datetimepicker table tr td span.active:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.active,
|
||||||
|
.datetimepicker table tr td span.active:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.active {
|
||||||
|
background-color: #003399 \9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.past,
|
||||||
|
.datetimepicker table tr td span.future {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.datetimepicker thead tr:first-child th,
|
||||||
|
.datetimepicker tfoot tr:first-child th {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker thead tr:first-child th:hover,
|
||||||
|
.datetimepicker tfoot tr:first-child th:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
|
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
|
||||||
<link rel="shortcut icon" href="graphics/favicon.ico"/>
|
<link rel="shortcut icon" href="graphics/favicon.ico"/>
|
||||||
<link rel="stylesheet" href="skins/bootstrap/css/bootstrap.css" type="text/css" />
|
<link rel="stylesheet" href="skins/bootstrap/css/bootstrap.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="skins/bootstrap/css/datetimepicker.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="skins/bootstrap/css/skin.css" type="text/css" />
|
<link rel="stylesheet" href="skins/bootstrap/css/skin.css" type="text/css" />
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
|
||||||
<script src="skins/bootstrap/js/dirPagination.js"></script>
|
<script src="skins/bootstrap/js/dirPagination.js"></script>
|
||||||
|
@ -22,5 +23,6 @@
|
||||||
<script type="text/javascript" src="skins/bootstrap/js/ui-bootstrap-tpls-0.12.0.min.js"></script>
|
<script type="text/javascript" src="skins/bootstrap/js/ui-bootstrap-tpls-0.12.0.min.js"></script>
|
||||||
<script type="text/javascript" src="skins/bootstrap/js/jquery-2.1.1.min.js"></script>
|
<script type="text/javascript" src="skins/bootstrap/js/jquery-2.1.1.min.js"></script>
|
||||||
<script type="text/javascript" src="skins/bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="skins/bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
<script type="text/javascript" src="skins/bootstrap/js/datetimepicker.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
|
@ -0,0 +1,397 @@
|
||||||
|
/*globals define, jQuery */
|
||||||
|
/*jslint vars:true */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @license angular-bootstrap-datetimepicker version: 0.3.8
|
||||||
|
* (c) 2013-2014 Knight Rider Consulting, Inc. http://www.knightrider.com
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Dale "Ducky" Lotts
|
||||||
|
* @since 2013-Jul-8
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (factory) {
|
||||||
|
'use strict';
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (typeof define === 'function' && /* istanbul ignore next */ define.amd) {
|
||||||
|
define(['angular', 'moment'], factory); // AMD
|
||||||
|
} else {
|
||||||
|
factory(window.angular, window.moment); // Browser global
|
||||||
|
}
|
||||||
|
}(function (angular, moment) {
|
||||||
|
'use strict';
|
||||||
|
angular.module('ui.bootstrap.datetimepicker', [])
|
||||||
|
.constant('dateTimePickerConfig', {
|
||||||
|
dropdownSelector: null,
|
||||||
|
minuteStep: 5,
|
||||||
|
minView: 'minute',
|
||||||
|
startView: 'day'
|
||||||
|
})
|
||||||
|
.directive('datetimepicker', ['$log', 'dateTimePickerConfig', function datetimepickerDirective($log, defaultConfig) {
|
||||||
|
|
||||||
|
function DateObject() {
|
||||||
|
|
||||||
|
this.dateValue = new Date().getTime();
|
||||||
|
this.selectable = true;
|
||||||
|
|
||||||
|
var validProperties = ['dateValue', 'display', 'active', 'selectable', 'past', 'future'];
|
||||||
|
|
||||||
|
for (var prop in arguments[0]) {
|
||||||
|
/* istanbul ignore else */
|
||||||
|
//noinspection JSUnfilteredForInLoop
|
||||||
|
if (validProperties.indexOf(prop) >= 0) {
|
||||||
|
//noinspection JSUnfilteredForInLoop
|
||||||
|
this[prop] = arguments[0][prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var validateConfiguration = function validateConfiguration(configuration) {
|
||||||
|
var validOptions = ['startView', 'minView', 'minuteStep', 'dropdownSelector'];
|
||||||
|
|
||||||
|
for (var prop in configuration) {
|
||||||
|
//noinspection JSUnfilteredForInLoop
|
||||||
|
if (validOptions.indexOf(prop) < 0) {
|
||||||
|
throw ('invalid option: ' + prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order of the elements in the validViews array is significant.
|
||||||
|
var validViews = ['minute', 'hour', 'day', 'month', 'year'];
|
||||||
|
|
||||||
|
if (validViews.indexOf(configuration.startView) < 0) {
|
||||||
|
throw ('invalid startView value: ' + configuration.startView);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validViews.indexOf(configuration.minView) < 0) {
|
||||||
|
throw ('invalid minView value: ' + configuration.minView);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validViews.indexOf(configuration.minView) > validViews.indexOf(configuration.startView)) {
|
||||||
|
throw ('startView must be greater than minView');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!angular.isNumber(configuration.minuteStep)) {
|
||||||
|
throw ('minuteStep must be numeric');
|
||||||
|
}
|
||||||
|
if (configuration.minuteStep <= 0 || configuration.minuteStep >= 60) {
|
||||||
|
throw ('minuteStep must be greater than zero and less than 60');
|
||||||
|
}
|
||||||
|
if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
|
||||||
|
throw ('dropdownSelector must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (configuration.dropdownSelector !== null && ((typeof jQuery === 'undefined') || (typeof jQuery().dropdown !== 'function'))) {
|
||||||
|
$log.error('Please DO NOT specify the dropdownSelector option unless you are using jQuery AND Bootstrap.js. ' +
|
||||||
|
'Please include jQuery AND Bootstrap.js, or write code to close the dropdown in the on-set-time callback. \n\n' +
|
||||||
|
'The dropdownSelector configuration option is being removed because it will not function properly.');
|
||||||
|
delete configuration.dropdownSelector;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
require: 'ngModel',
|
||||||
|
template: '<div class="datetimepicker table-responsive">' +
|
||||||
|
'<table class="table table-striped">' +
|
||||||
|
' <thead>' +
|
||||||
|
' <tr>' +
|
||||||
|
' <th class="left" data-ng-click="changeView(data.currentView, data.leftDate, $event)" data-ng-show="data.leftDate.selectable"><i class="glyphicon glyphicon-arrow-left"/></th>' +
|
||||||
|
' <th class="switch" colspan="5" data-ng-show="data.previousViewDate.selectable" data-ng-click="changeView(data.previousView, data.previousViewDate, $event)">{{ data.previousViewDate.display }}</th>' +
|
||||||
|
' <th class="right" data-ng-click="changeView(data.currentView, data.rightDate, $event)" data-ng-show="data.rightDate.selectable"><i class="glyphicon glyphicon-arrow-right"/></th>' +
|
||||||
|
' </tr>' +
|
||||||
|
' <tr>' +
|
||||||
|
' <th class="dow" data-ng-repeat="day in data.dayNames" >{{ day }}</th>' +
|
||||||
|
' </tr>' +
|
||||||
|
' </thead>' +
|
||||||
|
' <tbody>' +
|
||||||
|
' <tr data-ng-if="data.currentView !== \'day\'" >' +
|
||||||
|
' <td colspan="7" >' +
|
||||||
|
' <span class="{{ data.currentView }}" ' +
|
||||||
|
' data-ng-repeat="dateObject in data.dates" ' +
|
||||||
|
' data-ng-class="{active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}" ' +
|
||||||
|
' data-ng-click="changeView(data.nextView, dateObject, $event)">{{ dateObject.display }}</span> ' +
|
||||||
|
' </td>' +
|
||||||
|
' </tr>' +
|
||||||
|
' <tr data-ng-if="data.currentView === \'day\'" data-ng-repeat="week in data.weeks">' +
|
||||||
|
' <td data-ng-repeat="dateObject in week.dates" ' +
|
||||||
|
' data-ng-click="changeView(data.nextView, dateObject, $event)"' +
|
||||||
|
' class="day" ' +
|
||||||
|
' data-ng-class="{active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}" >{{ dateObject.display }}</td>' +
|
||||||
|
' </tr>' +
|
||||||
|
' </tbody>' +
|
||||||
|
'</table></div>',
|
||||||
|
scope: {
|
||||||
|
onSetTime: '&',
|
||||||
|
beforeRender: '&'
|
||||||
|
},
|
||||||
|
replace: true,
|
||||||
|
link: function link(scope, element, attrs, ngModelController) {
|
||||||
|
|
||||||
|
var directiveConfig = {};
|
||||||
|
|
||||||
|
if (attrs.datetimepickerConfig) {
|
||||||
|
directiveConfig = scope.$parent.$eval(attrs.datetimepickerConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
var configuration = {};
|
||||||
|
|
||||||
|
angular.extend(configuration, defaultConfig, directiveConfig);
|
||||||
|
|
||||||
|
validateConfiguration(configuration);
|
||||||
|
|
||||||
|
var startOfDecade = function startOfDecade(unixDate) {
|
||||||
|
var startYear = (parseInt(moment.utc(unixDate).year() / 10, 10) * 10);
|
||||||
|
return moment.utc(unixDate).year(startYear).startOf('year');
|
||||||
|
};
|
||||||
|
|
||||||
|
var dataFactory = {
|
||||||
|
year: function year(unixDate) {
|
||||||
|
var selectedDate = moment.utc(unixDate).startOf('year');
|
||||||
|
// View starts one year before the decade starts and ends one year after the decade ends
|
||||||
|
// i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
|
||||||
|
// Truncate the last digit from the current year and subtract 1 to get the start of the decade
|
||||||
|
var startDecade = (parseInt(selectedDate.year() / 10, 10) * 10);
|
||||||
|
var startDate = moment.utc(startOfDecade(unixDate)).subtract(1, 'year').startOf('year');
|
||||||
|
|
||||||
|
var activeYear = ngModelController.$modelValue ? moment(ngModelController.$modelValue).year() : 0;
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'currentView': 'year',
|
||||||
|
'nextView': configuration.minView === 'year' ? 'setTime' : 'month',
|
||||||
|
'previousViewDate': new DateObject({dateValue: null, display: startDecade + '-' + (startDecade + 9)}),
|
||||||
|
'leftDate': new DateObject({dateValue: moment.utc(startDate).subtract(9, 'year').valueOf()}),
|
||||||
|
'rightDate': new DateObject({dateValue: moment.utc(startDate).add(11, 'year').valueOf()}),
|
||||||
|
'dates': []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < 12; i += 1) {
|
||||||
|
var yearMoment = moment.utc(startDate).add(i, 'years');
|
||||||
|
var dateValue = {
|
||||||
|
'dateValue': yearMoment.valueOf(),
|
||||||
|
'display': yearMoment.format('YYYY'),
|
||||||
|
'past': yearMoment.year() < startDecade,
|
||||||
|
'future': yearMoment.year() > startDecade + 9,
|
||||||
|
'active': yearMoment.year() === activeYear
|
||||||
|
};
|
||||||
|
|
||||||
|
result.dates.push(new DateObject(dateValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
month: function month(unixDate) {
|
||||||
|
|
||||||
|
var startDate = moment.utc(unixDate).startOf('year');
|
||||||
|
var previousViewDate = startOfDecade(unixDate);
|
||||||
|
var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM') : 0;
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'previousView': 'year',
|
||||||
|
'currentView': 'month',
|
||||||
|
'nextView': configuration.minView === 'month' ? 'setTime' : 'day',
|
||||||
|
'previousViewDate': new DateObject({
|
||||||
|
dateValue: previousViewDate.valueOf(),
|
||||||
|
display: startDate.format('YYYY')
|
||||||
|
}),
|
||||||
|
'leftDate': new DateObject({dateValue: moment.utc(startDate).subtract(1, 'year').valueOf()}),
|
||||||
|
'rightDate': new DateObject({dateValue: moment.utc(startDate).add(1, 'year').valueOf()}),
|
||||||
|
'dates': []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < 12; i += 1) {
|
||||||
|
var monthMoment = moment.utc(startDate).add(i, 'months');
|
||||||
|
var dateValue = {
|
||||||
|
'dateValue': monthMoment.valueOf(),
|
||||||
|
'display': monthMoment.format('MMM'),
|
||||||
|
'active': monthMoment.format('YYYY-MMM') === activeDate
|
||||||
|
};
|
||||||
|
|
||||||
|
result.dates.push(new DateObject(dateValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
day: function day(unixDate) {
|
||||||
|
|
||||||
|
var selectedDate = moment.utc(unixDate);
|
||||||
|
var startOfMonth = moment.utc(selectedDate).startOf('month');
|
||||||
|
var previousViewDate = moment.utc(selectedDate).startOf('year');
|
||||||
|
var endOfMonth = moment.utc(selectedDate).endOf('month');
|
||||||
|
|
||||||
|
var startDate = moment.utc(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days');
|
||||||
|
|
||||||
|
var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM-DD') : '';
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'previousView': 'month',
|
||||||
|
'currentView': 'day',
|
||||||
|
'nextView': configuration.minView === 'day' ? 'setTime' : 'hour',
|
||||||
|
'previousViewDate': new DateObject({
|
||||||
|
dateValue: previousViewDate.valueOf(),
|
||||||
|
display: startOfMonth.format('YYYY-MMM')
|
||||||
|
}),
|
||||||
|
'leftDate': new DateObject({dateValue: moment.utc(startOfMonth).subtract(1, 'months').valueOf()}),
|
||||||
|
'rightDate': new DateObject({dateValue: moment.utc(startOfMonth).add(1, 'months').valueOf()}),
|
||||||
|
'dayNames': [],
|
||||||
|
'weeks': []
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
for (var dayNumber = 0; dayNumber < 7; dayNumber += 1) {
|
||||||
|
result.dayNames.push(moment.utc().weekday(dayNumber).format('dd'));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i += 1) {
|
||||||
|
var week = {dates: []};
|
||||||
|
for (var j = 0; j < 7; j += 1) {
|
||||||
|
var monthMoment = moment.utc(startDate).add((i * 7) + j, 'days');
|
||||||
|
var dateValue = {
|
||||||
|
'dateValue': monthMoment.valueOf(),
|
||||||
|
'display': monthMoment.format('D'),
|
||||||
|
'active': monthMoment.format('YYYY-MMM-DD') === activeDate,
|
||||||
|
'past': monthMoment.isBefore(startOfMonth),
|
||||||
|
'future': monthMoment.isAfter(endOfMonth)
|
||||||
|
};
|
||||||
|
week.dates.push(new DateObject(dateValue));
|
||||||
|
}
|
||||||
|
result.weeks.push(week);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
hour: function hour(unixDate) {
|
||||||
|
var selectedDate = moment.utc(unixDate).startOf('day');
|
||||||
|
var previousViewDate = moment.utc(selectedDate).startOf('month');
|
||||||
|
|
||||||
|
var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H') : '';
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'previousView': 'day',
|
||||||
|
'currentView': 'hour',
|
||||||
|
'nextView': configuration.minView === 'hour' ? 'setTime' : 'minute',
|
||||||
|
'previousViewDate': new DateObject({
|
||||||
|
dateValue: previousViewDate.valueOf(),
|
||||||
|
display: selectedDate.format('ll')
|
||||||
|
}),
|
||||||
|
'leftDate': new DateObject({dateValue: moment.utc(selectedDate).subtract(1, 'days').valueOf()}),
|
||||||
|
'rightDate': new DateObject({dateValue: moment.utc(selectedDate).add(1, 'days').valueOf()}),
|
||||||
|
'dates': []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < 24; i += 1) {
|
||||||
|
var hourMoment = moment.utc(selectedDate).add(i, 'hours');
|
||||||
|
var dateValue = {
|
||||||
|
'dateValue': hourMoment.valueOf(),
|
||||||
|
'display': hourMoment.format('LT'),
|
||||||
|
'active': hourMoment.format('YYYY-MM-DD H') === activeFormat
|
||||||
|
};
|
||||||
|
|
||||||
|
result.dates.push(new DateObject(dateValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
minute: function minute(unixDate) {
|
||||||
|
var selectedDate = moment.utc(unixDate).startOf('hour');
|
||||||
|
var previousViewDate = moment.utc(selectedDate).startOf('day');
|
||||||
|
var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H:mm') : '';
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
'previousView': 'hour',
|
||||||
|
'currentView': 'minute',
|
||||||
|
'nextView': 'setTime',
|
||||||
|
'previousViewDate': new DateObject({
|
||||||
|
dateValue: previousViewDate.valueOf(),
|
||||||
|
display: selectedDate.format('lll')
|
||||||
|
}),
|
||||||
|
'leftDate': new DateObject({dateValue: moment.utc(selectedDate).subtract(1, 'hours').valueOf()}),
|
||||||
|
'rightDate': new DateObject({dateValue: moment.utc(selectedDate).add(1, 'hours').valueOf()}),
|
||||||
|
'dates': []
|
||||||
|
};
|
||||||
|
|
||||||
|
var limit = 60 / configuration.minuteStep;
|
||||||
|
|
||||||
|
for (var i = 0; i < limit; i += 1) {
|
||||||
|
var hourMoment = moment.utc(selectedDate).add(i * configuration.minuteStep, 'minute');
|
||||||
|
var dateValue = {
|
||||||
|
'dateValue': hourMoment.valueOf(),
|
||||||
|
'display': hourMoment.format('LT'),
|
||||||
|
'active': hourMoment.format('YYYY-MM-DD H:mm') === activeFormat
|
||||||
|
};
|
||||||
|
|
||||||
|
result.dates.push(new DateObject(dateValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
setTime: function setTime(unixDate) {
|
||||||
|
var tempDate = new Date(unixDate);
|
||||||
|
var newDate = new Date(tempDate.getTime() + (tempDate.getTimezoneOffset() * 60000));
|
||||||
|
|
||||||
|
var oldDate = ngModelController.$modelValue;
|
||||||
|
ngModelController.$setViewValue(newDate);
|
||||||
|
|
||||||
|
if (configuration.dropdownSelector) {
|
||||||
|
jQuery(configuration.dropdownSelector).dropdown('toggle');
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.onSetTime({newDate: newDate, oldDate: oldDate});
|
||||||
|
|
||||||
|
return dataFactory[configuration.startView](unixDate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var getUTCTime = function getUTCTime(modelValue) {
|
||||||
|
var tempDate = (modelValue ? moment(modelValue).toDate() : new Date());
|
||||||
|
return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000);
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.changeView = function changeView(viewName, dateObject, event) {
|
||||||
|
if (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewName && (dateObject.dateValue > -Infinity) && dateObject.selectable && dataFactory[viewName]) {
|
||||||
|
var result = dataFactory[viewName](dateObject.dateValue);
|
||||||
|
|
||||||
|
var weekDates = [];
|
||||||
|
if (result.weeks) {
|
||||||
|
for (var i = 0; i < result.weeks.length; i += 1) {
|
||||||
|
var week = result.weeks[i];
|
||||||
|
for (var j = 0; j < week.dates.length; j += 1) {
|
||||||
|
var weekDate = week.dates[j];
|
||||||
|
weekDates.push(weekDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.beforeRender({
|
||||||
|
$view: result.currentView,
|
||||||
|
$dates: result.dates || weekDates,
|
||||||
|
$leftDate: result.leftDate,
|
||||||
|
$upDate: result.previousViewDate,
|
||||||
|
$rightDate: result.rightDate
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.data = result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ngModelController.$render = function $render() {
|
||||||
|
scope.changeView(configuration.startView, new DateObject({dateValue: getUTCTime(ngModelController.$viewValue)}));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
}));
|
Loading…
Reference in New Issue