commit 12/02/2026

This commit is contained in:
2026-02-12 17:08:20 +07:00
parent 546f2e27af
commit c797c6e7fe
47 changed files with 89103 additions and 214 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,253 @@
/* !
* ClockPicker v0.2.2 for Bootstrap (https://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
* Bootstrap 4 compatibility by djibe (https://github.com/djibe/clockpicker) */
:root {
--primary-color: 0, 123, 255;
}
.clockpicker .input-group-addon {
cursor: pointer;
}
.clockpicker-moving {
cursor: move;
}
.clockpicker-align-left.popover > .arrow {
left: 25px;
}
.clockpicker-align-top.popover > .arrow {
top: 17px;
}
.clockpicker-align-right.popover > .arrow {
left: auto;
right: 25px;
}
.clockpicker-align-bottom.popover > .arrow {
top: auto;
bottom: 6px;
}
.clockpicker-popover {
-webkit-animation: pickerFadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);
animation: pickerFadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);
border-radius: 4px;
border: 0;
-webkit-transform: scale(1);
transform: scale(1);
-webkit-transform-origin: center top 0px;
transform-origin: center top 0px;
-webkit-box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px 0 rgba(0, 0, 0, 0.2);
box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px 0 rgba(0, 0, 0, 0.2);
}
.clockpicker-popover.top {
-webkit-transform-origin: center bottom 0px;
transform-origin: center bottom 0px;
}
.clockpicker-popover * {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.clockpicker-popover .popover-header {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
background-color: var(--primary, #007bff);
color: #fff;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 3rem;
font-weight: normal;
letter-spacing: normal;
text-align: center;
padding: 0.5rem;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.clockpicker-popover .popover-header span {
cursor: pointer;
}
.clockpicker-popover .popover-body {
background-color: #fff;
padding: 1rem 0.75rem 0.75rem;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
.clockpicker-popover .btn {
border: 0 !important;
border-radius: 4px;
-webkit-box-shadow: none;
box-shadow: none;
font-size: 0.8125rem;
font-weight: 500;
padding: 0.59375rem 1rem;
min-width: 0;
margin: 0;
margin-left: 0.25rem;
text-transform: uppercase;
}
.clockpicker-popover .btn:focus, .clockpicker-popover .btn:hover, .clockpicker-popover .btn:active {
outline: none !important;
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.12)), to(rgba(0, 0, 0, 0.12)));
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12));
-webkit-box-shadow: none;
box-shadow: none;
}
.clockpicker-span-hours {
margin-right: 0.25rem;
}
.clockpicker-span-minutes {
margin-left: 0.25rem;
}
.clockpicker-close-block {
margin-top: 0.75rem;
}
.clockpicker-plate {
background-color: #ededee;
border-radius: 50%;
width: 200px;
height: 200px;
overflow: visible;
position: relative;
}
.clockpicker-canvas, .clockpicker-dial {
width: 200px;
height: 200px;
position: absolute;
left: -1px;
top: -1px;
}
.clockpicker-minutes {
visibility: hidden;
}
.clockpicker-tick {
border-radius: 50%;
line-height: 26px;
text-align: center;
width: 26px;
height: 26px;
position: absolute;
cursor: pointer;
}
.clockpicker-tick.active, .clockpicker-tick:not(.disabled):hover {
background-color: rgba(var(--primary-color, 0, 123, 255), 0.25);
}
.clockpicker-tick.disabled {
color: #eee;
cursor: default;
}
.clockpicker-dial {
-webkit-transition: opacity 350ms, -webkit-transform 350ms;
transition: opacity 350ms, -webkit-transform 350ms;
transition: transform 350ms, opacity 350ms;
transition: transform 350ms, opacity 350ms, -webkit-transform 350ms;
}
.clockpicker-dial-out {
opacity: 0;
}
.clockpicker-hours.clockpicker-dial-out {
-webkit-transform: scale(1.2, 1.2);
transform: scale(1.2, 1.2);
}
.clockpicker-minutes.clockpicker-dial-out {
-webkit-transform: scale(0.8, 0.8);
transform: scale(0.8, 0.8);
}
.clockpicker-canvas {
-webkit-transition: opacity 175ms;
transition: opacity 175ms;
}
.clockpicker-canvas-out {
opacity: 0.25;
}
.clockpicker-canvas line {
stroke: var(--primary, #007bff);
stroke-width: 2;
stroke-linecap: round;
}
.clockpicker-canvas-bearing {
stroke: none;
fill: var(--primary, #007bff);
}
.clockpicker-canvas-fg {
stroke: none;
fill: rgba(var(--primary-color, 0, 123, 255), 0.5);
}
.clockpicker-canvas-bg {
stroke: none;
fill: rgba(var(--primary-color, 0, 123, 255), 0.25);
}
.clockpicker-canvas-bg-trans {
fill: rgba(var(--primary-color, 0, 123, 255), 0.25);
}
.clockpicker-buttons-am-pm {
color: white;
display: none;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-ms-flex-pack: distribute;
justify-content: space-around;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 1rem;
margin-left: 0.75rem;
}
@keyframes pickerFadeIn {
from {
opacity: 0;
-webkit-transform: scale(0.8);
transform: scale(0.8);
}
to {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
}

View File

@@ -0,0 +1,252 @@
/* !
* ClockPicker v0.2.2 for Bootstrap (https://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
* Bootstrap 4 compatibility by djibe (https://github.com/djibe/clockpicker) */
:root {
--primary-color: 0,123,255;
}
.clockpicker .input-group-addon {
cursor: pointer;
}
.clockpicker-moving {
cursor: move;
}
.clockpicker-align-left.popover > .arrow {
left: 25px;
}
.clockpicker-align-top.popover > .arrow {
top: 17px;
}
.clockpicker-align-right.popover > .arrow {
left: auto;
right: 25px;
}
.clockpicker-align-bottom.popover > .arrow {
top: auto;
bottom: 6px;
}
.clockpicker-popover {
-webkit-animation: pickerFadeIn .2s cubic-bezier(.4,0,.2,1);
animation: pickerFadeIn .2s cubic-bezier(.4,0,.2,1);
border-radius: 4px;
border: 0;
-webkit-transform: scale(1);
transform: scale(1);
-webkit-transform-origin: center top 0;
transform-origin: center top 0;
-webkit-box-shadow: 0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12),0 11px 15px 0 rgba(0,0,0,.2);
box-shadow: 0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12),0 11px 15px 0 rgba(0,0,0,.2);
}
.clockpicker-popover.top {
-webkit-transform-origin: center bottom 0;
transform-origin: center bottom 0;
}
.clockpicker-popover * {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.clockpicker-popover .popover-header {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
background-color: var(--primary,#007bff);
color: #fff;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 3rem;
font-weight: 400;
letter-spacing: normal;
text-align: center;
padding: .5rem;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.clockpicker-popover .popover-header span {
cursor: pointer;
}
.clockpicker-popover .popover-body {
background-color: #fff;
padding: 1rem .75rem .75rem;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
.clockpicker-popover .btn {
border: 0!important;
border-radius: 4px;
-webkit-box-shadow: none;
box-shadow: none;
font-size: .8125rem;
font-weight: 500;
padding: .59375rem 1rem;
min-width: 0;
margin: 0 0 0 .25rem;
text-transform: uppercase;
}
.clockpicker-popover .btn:active, .clockpicker-popover .btn:focus, .clockpicker-popover .btn:hover {
outline: 0!important;
background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.12)),to(rgba(0,0,0,.12)));
background-image: linear-gradient(180deg,rgba(0,0,0,.12),rgba(0,0,0,.12));
-webkit-box-shadow: none;
box-shadow: none;
}
.clockpicker-span-hours {
margin-right: .25rem;
}
.clockpicker-span-minutes {
margin-left: .25rem;
}
.clockpicker-close-block {
margin-top: .75rem;
}
.clockpicker-plate {
background-color: #ededee;
border-radius: 50%;
width: 200px;
height: 200px;
overflow: visible;
position: relative;
}
.clockpicker-canvas, .clockpicker-dial {
width: 200px;
height: 200px;
position: absolute;
left: -1px;
top: -1px;
}
.clockpicker-minutes {
visibility: hidden;
}
.clockpicker-tick {
border-radius: 50%;
line-height: 26px;
text-align: center;
width: 26px;
height: 26px;
position: absolute;
cursor: pointer;
}
.clockpicker-tick.active, .clockpicker-tick:not(.disabled):hover {
background-color: rgba(var(--primary-color,0,123,255),.25);
}
.clockpicker-tick.disabled {
color: #eee;
cursor: default;
}
.clockpicker-dial {
-webkit-transition: opacity 350ms,-webkit-transform 350ms;
transition: opacity 350ms,-webkit-transform 350ms;
transition: transform 350ms,opacity 350ms;
transition: transform 350ms,opacity 350ms,-webkit-transform 350ms;
}
.clockpicker-dial-out {
opacity: 0;
}
.clockpicker-hours.clockpicker-dial-out {
-webkit-transform: scale(1.2,1.2);
transform: scale(1.2,1.2);
}
.clockpicker-minutes.clockpicker-dial-out {
-webkit-transform: scale(.8,.8);
transform: scale(.8,.8);
}
.clockpicker-canvas {
-webkit-transition: opacity 175ms;
transition: opacity 175ms;
}
.clockpicker-canvas-out {
opacity: .25;
}
.clockpicker-canvas line {
stroke: var(--primary,#007bff);
stroke-width: 2;
stroke-linecap: round;
}
.clockpicker-canvas-bearing {
stroke: none;
fill: var(--primary,#007bff);
}
.clockpicker-canvas-fg {
stroke: none;
fill: rgba(var(--primary-color,0,123,255),.5);
}
.clockpicker-canvas-bg {
stroke: none;
fill: rgba(var(--primary-color,0,123,255),.25);
}
.clockpicker-canvas-bg-trans {
fill: rgba(var(--primary-color,0,123,255),.25);
}
.clockpicker-buttons-am-pm {
color: #fff;
display: none;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-ms-flex-pack: distribute;
justify-content: space-around;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 1rem;
margin-left: .75rem;
}
@keyframes pickerFadeIn {
from {
opacity: 0;
-webkit-transform: scale(.8);
transform: scale(.8);
}
to {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
}

View File

@@ -0,0 +1,806 @@
.flatpickr-calendar {
background: transparent;
opacity: 0;
display: none;
text-align: center;
visibility: hidden;
padding: 0;
-webkit-animation: none;
animation: none;
direction: ltr;
border: 0;
font-size: 14px;
line-height: 24px;
border-radius: 5px;
position: absolute;
width: 307.875px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-ms-touch-action: manipulation;
touch-action: manipulation;
background: #fff;
-webkit-box-shadow: 1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);
box-shadow: 1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);
}
.flatpickr-calendar.open, .flatpickr-calendar.inline {
opacity: 1;
max-height: 640px;
visibility: visible;
}
.flatpickr-calendar.open {
display: inline-block;
z-index: 99999;
}
.flatpickr-calendar.animate.open {
-webkit-animation: fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);
animation: fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);
}
.flatpickr-calendar.inline {
display: block;
position: relative;
top: 2px;
}
.flatpickr-calendar.static {
position: absolute;
top: calc(100% + 2px);
}
.flatpickr-calendar.static.open {
z-index: 999;
display: block;
}
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 1) .flatpickr-day.inRange:nth-child(7n + 7) {
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 2) .flatpickr-day.inRange:nth-child(7n + 1) {
-webkit-box-shadow: -2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;
box-shadow: -2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;
}
.flatpickr-calendar .hasWeeks .dayContainer, .flatpickr-calendar .hasTime .dayContainer {
border-bottom: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.flatpickr-calendar .hasWeeks .dayContainer {
border-left: 0;
}
.flatpickr-calendar.hasTime .flatpickr-time {
height: 40px;
border-top: 1px solid #e6e6e6;
}
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {
height: auto;
}
.flatpickr-calendar:before, .flatpickr-calendar:after {
position: absolute;
display: block;
pointer-events: none;
border: solid transparent;
content: '';
height: 0;
width: 0;
left: 22px;
}
.flatpickr-calendar.rightMost:before, .flatpickr-calendar.arrowRight:before, .flatpickr-calendar.rightMost:after, .flatpickr-calendar.arrowRight:after {
left: auto;
right: 22px;
}
.flatpickr-calendar.arrowCenter:before, .flatpickr-calendar.arrowCenter:after {
left: 50%;
right: 50%;
}
.flatpickr-calendar:before {
border-width: 5px;
margin: 0 -5px;
}
.flatpickr-calendar:after {
border-width: 4px;
margin: 0 -4px;
}
.flatpickr-calendar.arrowTop:before, .flatpickr-calendar.arrowTop:after {
bottom: 100%;
}
.flatpickr-calendar.arrowTop:before {
border-bottom-color: #e6e6e6;
}
.flatpickr-calendar.arrowTop:after {
border-bottom-color: #fff;
}
.flatpickr-calendar.arrowBottom:before, .flatpickr-calendar.arrowBottom:after {
top: 100%;
}
.flatpickr-calendar.arrowBottom:before {
border-top-color: #e6e6e6;
}
.flatpickr-calendar.arrowBottom:after {
border-top-color: #fff;
}
.flatpickr-calendar:focus {
outline: 0;
}
.flatpickr-wrapper {
position: relative;
display: inline-block;
}
.flatpickr-months {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.flatpickr-months .flatpickr-month {
background: transparent;
color: rgba(0,0,0,0.9);
fill: rgba(0,0,0,0.9);
height: 34px;
line-height: 1;
text-align: center;
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow: hidden;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.flatpickr-months .flatpickr-prev-month, .flatpickr-months .flatpickr-next-month {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
text-decoration: none;
cursor: pointer;
position: absolute;
top: 0;
height: 34px;
padding: 10px;
z-index: 3;
color: rgba(0,0,0,0.9);
fill: rgba(0,0,0,0.9);
}
.flatpickr-months .flatpickr-prev-month.flatpickr-disabled, .flatpickr-months .flatpickr-next-month.flatpickr-disabled {
display: none;
}
.flatpickr-months .flatpickr-prev-month i, .flatpickr-months .flatpickr-next-month i {
position: relative;
}
.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month, .flatpickr-months .flatpickr-next-month.flatpickr-prev-month {
left: 0;
}
/* /*rtl:begin:ignore */
/* /*rtl:end:ignore */
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month, .flatpickr-months .flatpickr-next-month.flatpickr-next-month {
right: 0;
}
/* /*rtl:begin:ignore */
/* /*rtl:end:ignore */
.flatpickr-months .flatpickr-prev-month:hover, .flatpickr-months .flatpickr-next-month:hover {
color: #959ea9;
}
.flatpickr-months .flatpickr-prev-month:hover svg, .flatpickr-months .flatpickr-next-month:hover svg {
fill: #f64747;
}
.flatpickr-months .flatpickr-prev-month svg, .flatpickr-months .flatpickr-next-month svg {
width: 14px;
height: 14px;
}
.flatpickr-months .flatpickr-prev-month svg path, .flatpickr-months .flatpickr-next-month svg path {
-webkit-transition: fill .1s;
transition: fill .1s;
fill: inherit;
}
.numInputWrapper {
position: relative;
height: auto;
}
.numInputWrapper input, .numInputWrapper span {
display: inline-block;
}
.numInputWrapper input {
width: 100%;
}
.numInputWrapper input::-ms-clear {
display: none;
}
.numInputWrapper input::-webkit-outer-spin-button, .numInputWrapper input::-webkit-inner-spin-button {
margin: 0;
-webkit-appearance: none;
}
.numInputWrapper span {
position: absolute;
right: 0;
width: 14px;
padding: 0 4px 0 2px;
height: 50%;
line-height: 50%;
opacity: 0;
cursor: pointer;
border: 1px solid rgba(57,57,57,0.15);
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.numInputWrapper span:hover {
background: rgba(0,0,0,0.1);
}
.numInputWrapper span:active {
background: rgba(0,0,0,0.2);
}
.numInputWrapper span:after {
display: block;
content: "";
position: absolute;
}
.numInputWrapper span.arrowUp {
top: 0;
border-bottom: 0;
}
.numInputWrapper span.arrowUp:after {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid rgba(57,57,57,0.6);
top: 26%;
}
.numInputWrapper span.arrowDown {
top: 50%;
}
.numInputWrapper span.arrowDown:after {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid rgba(57,57,57,0.6);
top: 40%;
}
.numInputWrapper span svg {
width: inherit;
height: auto;
}
.numInputWrapper span svg path {
fill: rgba(0,0,0,0.5);
}
.numInputWrapper:hover {
background: rgba(0,0,0,0.05);
}
.numInputWrapper:hover span {
opacity: 1;
}
.flatpickr-current-month {
font-size: 135%;
line-height: inherit;
font-weight: 300;
color: inherit;
position: absolute;
width: 75%;
left: 12.5%;
padding: 7.48px 0 0 0;
line-height: 1;
height: 34px;
display: inline-block;
text-align: center;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
.flatpickr-current-month span.cur-month {
font-family: inherit;
font-weight: 700;
color: inherit;
display: inline-block;
margin-left: .5ch;
padding: 0;
}
.flatpickr-current-month span.cur-month:hover {
background: rgba(0,0,0,0.05);
}
.flatpickr-current-month .numInputWrapper {
width: 6ch;
width: 7ch\0;
display: inline-block;
}
.flatpickr-current-month .numInputWrapper span.arrowUp:after {
border-bottom-color: rgba(0,0,0,0.9);
}
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
border-top-color: rgba(0,0,0,0.9);
}
.flatpickr-current-month input.cur-year {
background: transparent;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
cursor: text;
padding: 0 0 0 .5ch;
margin: 0;
display: inline-block;
font-size: inherit;
font-family: inherit;
font-weight: 300;
line-height: inherit;
height: auto;
border: 0;
border-radius: 0;
vertical-align: initial;
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
.flatpickr-current-month input.cur-year:focus {
outline: 0;
}
.flatpickr-current-month input.cur-year[disabled], .flatpickr-current-month input.cur-year[disabled]:hover {
font-size: 100%;
color: rgba(0,0,0,0.5);
background: transparent;
pointer-events: none;
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
appearance: menulist;
background: transparent;
border: none;
border-radius: 0;
box-sizing: border-box;
color: inherit;
cursor: pointer;
font-size: inherit;
font-family: inherit;
font-weight: 300;
height: auto;
line-height: inherit;
margin: -1px 0 0 0;
outline: none;
padding: 0 0 0 .5ch;
position: relative;
vertical-align: initial;
-webkit-box-sizing: border-box;
-webkit-appearance: menulist;
-moz-appearance: menulist;
width: auto;
}
.flatpickr-current-month .flatpickr-monthDropdown-months:focus, .flatpickr-current-month .flatpickr-monthDropdown-months:active {
outline: none;
}
.flatpickr-current-month .flatpickr-monthDropdown-months:hover {
background: rgba(0,0,0,0.05);
}
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {
background-color: transparent;
outline: none;
padding: 0;
}
.flatpickr-weekdays {
background: transparent;
text-align: center;
overflow: hidden;
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 28px;
}
.flatpickr-weekdays .flatpickr-weekdaycontainer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
span.flatpickr-weekday {
cursor: default;
font-size: 90%;
background: transparent;
color: rgba(0,0,0,0.54);
line-height: 1;
margin: 0;
text-align: center;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
font-weight: bolder;
}
.dayContainer, .flatpickr-weeks {
padding: 1px 0 0 0;
}
.flatpickr-days {
position: relative;
overflow: hidden;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: start;
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
width: 307.875px;
}
.flatpickr-days:focus {
outline: 0;
}
.dayContainer {
padding: 0;
outline: 0;
text-align: left;
width: 307.875px;
min-width: 307.875px;
max-width: 307.875px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
display: -ms-flexbox;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-wrap: wrap;
-ms-flex-pack: justify;
-webkit-justify-content: space-around;
justify-content: space-around;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
opacity: 1;
}
.dayContainer + .dayContainer {
-webkit-box-shadow: -1px 0 0 #e6e6e6;
box-shadow: -1px 0 0 #e6e6e6;
}
.flatpickr-day {
background: none;
border: 1px solid transparent;
border-radius: 150px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #393939;
cursor: pointer;
font-weight: 400;
width: 14.2857143%;
-webkit-flex-basis: 14.2857143%;
-ms-flex-preferred-size: 14.2857143%;
flex-basis: 14.2857143%;
max-width: 39px;
height: 39px;
line-height: 39px;
margin: 0;
display: inline-block;
position: relative;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
}
.flatpickr-day.inRange, .flatpickr-day.prevMonthDay.inRange, .flatpickr-day.nextMonthDay.inRange, .flatpickr-day.today.inRange, .flatpickr-day.prevMonthDay.today.inRange, .flatpickr-day.nextMonthDay.today.inRange, .flatpickr-day:hover, .flatpickr-day.prevMonthDay:hover, .flatpickr-day.nextMonthDay:hover, .flatpickr-day:focus, .flatpickr-day.prevMonthDay:focus, .flatpickr-day.nextMonthDay:focus {
cursor: pointer;
outline: 0;
background: #e6e6e6;
border-color: #e6e6e6;
}
.flatpickr-day.today {
border-color: #959ea9;
}
.flatpickr-day.today:hover, .flatpickr-day.today:focus {
border-color: #959ea9;
background: #959ea9;
color: #fff;
}
.flatpickr-day.selected, .flatpickr-day.startRange, .flatpickr-day.endRange, .flatpickr-day.selected.inRange, .flatpickr-day.startRange.inRange, .flatpickr-day.endRange.inRange, .flatpickr-day.selected:focus, .flatpickr-day.startRange:focus, .flatpickr-day.endRange:focus, .flatpickr-day.selected:hover, .flatpickr-day.startRange:hover, .flatpickr-day.endRange:hover, .flatpickr-day.selected.prevMonthDay, .flatpickr-day.startRange.prevMonthDay, .flatpickr-day.endRange.prevMonthDay, .flatpickr-day.selected.nextMonthDay, .flatpickr-day.startRange.nextMonthDay, .flatpickr-day.endRange.nextMonthDay {
background: #569ff7;
-webkit-box-shadow: none;
box-shadow: none;
color: #fff;
border-color: #569ff7;
}
.flatpickr-day.selected.startRange, .flatpickr-day.startRange.startRange, .flatpickr-day.endRange.startRange {
border-radius: 50px 0 0 50px;
}
.flatpickr-day.selected.endRange, .flatpickr-day.startRange.endRange, .flatpickr-day.endRange.endRange {
border-radius: 0 50px 50px 0;
}
.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n + 1)), .flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n + 1)), .flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n + 1)) {
-webkit-box-shadow: -10px 0 0 #569ff7;
box-shadow: -10px 0 0 #569ff7;
}
.flatpickr-day.selected.startRange.endRange, .flatpickr-day.startRange.startRange.endRange, .flatpickr-day.endRange.startRange.endRange {
border-radius: 50px;
}
.flatpickr-day.inRange {
border-radius: 0;
-webkit-box-shadow: -5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;
box-shadow: -5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;
}
.flatpickr-day.flatpickr-disabled, .flatpickr-day.flatpickr-disabled:hover, .flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay, .flatpickr-day.notAllowed, .flatpickr-day.notAllowed.prevMonthDay, .flatpickr-day.notAllowed.nextMonthDay {
color: rgba(57,57,57,0.3);
background: transparent;
border-color: transparent;
cursor: default;
}
.flatpickr-day.flatpickr-disabled, .flatpickr-day.flatpickr-disabled:hover {
cursor: not-allowed;
color: rgba(57,57,57,0.1);
}
.flatpickr-day.week.selected {
border-radius: 0;
-webkit-box-shadow: -5px 0 0 #569ff7,5px 0 0 #569ff7;
box-shadow: -5px 0 0 #569ff7,5px 0 0 #569ff7;
}
.flatpickr-day.hidden {
visibility: hidden;
}
.rangeMode .flatpickr-day {
margin-top: 1px;
}
.flatpickr-weekwrapper {
float: left;
}
.flatpickr-weekwrapper .flatpickr-weeks {
padding: 0 12px;
-webkit-box-shadow: 1px 0 0 #e6e6e6;
box-shadow: 1px 0 0 #e6e6e6;
}
.flatpickr-weekwrapper .flatpickr-weekday {
float: none;
width: 100%;
line-height: 28px;
}
.flatpickr-weekwrapper span.flatpickr-day, .flatpickr-weekwrapper span.flatpickr-day:hover {
display: block;
width: 100%;
max-width: none;
color: rgba(57,57,57,0.3);
background: transparent;
cursor: default;
border: none;
}
.flatpickr-innerContainer {
display: block;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
}
.flatpickr-rContainer {
display: inline-block;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.flatpickr-time {
text-align: center;
outline: 0;
display: block;
height: 0;
line-height: 40px;
max-height: 40px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.flatpickr-time:after {
content: "";
display: table;
clear: both;
}
.flatpickr-time .numInputWrapper {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
width: 40%;
height: 40px;
float: left;
}
.flatpickr-time .numInputWrapper span.arrowUp:after {
border-bottom-color: #393939;
}
.flatpickr-time .numInputWrapper span.arrowDown:after {
border-top-color: #393939;
}
.flatpickr-time.hasSeconds .numInputWrapper {
width: 26%;
}
.flatpickr-time.time24hr .numInputWrapper {
width: 49%;
}
.flatpickr-time input {
background: transparent;
-webkit-box-shadow: none;
box-shadow: none;
border: 0;
border-radius: 0;
text-align: center;
margin: 0;
padding: 0;
height: inherit;
line-height: inherit;
color: #393939;
font-size: 14px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
.flatpickr-time input.flatpickr-hour {
font-weight: bold;
}
.flatpickr-time input.flatpickr-minute, .flatpickr-time input.flatpickr-second {
font-weight: 400;
}
.flatpickr-time input:focus {
outline: 0;
border: 0;
}
.flatpickr-time .flatpickr-time-separator, .flatpickr-time .flatpickr-am-pm {
height: inherit;
float: left;
line-height: inherit;
color: #393939;
font-weight: bold;
width: 2%;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center;
}
.flatpickr-time .flatpickr-am-pm {
outline: 0;
width: 18%;
cursor: pointer;
text-align: center;
font-weight: 400;
}
.flatpickr-time input:hover, .flatpickr-time .flatpickr-am-pm:hover, .flatpickr-time input:focus, .flatpickr-time .flatpickr-am-pm:focus {
background: #eee;
}
.flatpickr-input[readonly] {
cursor: pointer;
}
@keyframes fpFadeInDown {
from {
opacity: 0;
-webkit-transform: translate3d(0,-20px,0);
transform: translate3d(0,-20px,0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
}

View File

@@ -0,0 +1,406 @@
/* !
* ClockPicker v0.0.7 for jQuery (http://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei.
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
*
* Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */
/* Picked from bootstrap: .popover, .btn, .text-primary */
.popover {
position: absolute;
top: 0;
left: 0;
z-index: 1010;
display: none;
max-width: 276px;
padding: 1px;
text-align: left;
white-space: normal;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
.popover.top {
margin-top: -10px;
}
.popover.right {
margin-left: 10px;
}
.popover.bottom {
margin-top: 10px;
}
.popover.left {
margin-left: -10px;
}
.popover-title {
padding: 8px 14px;
margin: 0;
font-size: 14px;
font-weight: normal;
line-height: 18px;
background-color: #f7f7f7;
border-bottom: 1px solid #ebebeb;
border-radius: 5px 5px 0 0;
}
.popover-content {
padding: 9px 14px;
}
.popover > .arrow, .popover > .arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
overflow: visible;
margin: 0;
padding: 0;
z-index: auto;
background-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
bottom: auto;
left: auto;
right: auto;
top: auto;
-webkit-transform: none;
-ms-transform: none;
transform: none;
}
.popover > .arrow {
border-width: 11px;
}
.popover > .arrow:after {
content: "";
border-width: 10px;
}
.popover.top > .arrow {
bottom: -11px;
left: 50%;
margin-left: -11px;
border-top-color: #999;
border-top-color: rgba(0, 0, 0, .25);
border-bottom-width: 0;
}
.popover.top > .arrow:after {
bottom: 1px;
margin-left: -10px;
content: " ";
border-top-color: #fff;
border-bottom-width: 0;
}
.popover.right > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
border-right-color: #999;
border-right-color: rgba(0, 0, 0, .25);
border-left-width: 0;
}
.popover.right > .arrow:after {
bottom: -10px;
left: 1px;
content: " ";
border-right-color: #fff;
border-left-width: 0;
}
.popover.bottom > .arrow {
top: -11px;
left: 50%;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999;
border-bottom-color: rgba(0, 0, 0, .25);
}
.popover.bottom > .arrow:after {
top: 1px;
margin-left: -10px;
content: " ";
border-top-width: 0;
border-bottom-color: #fff;
}
.popover.left > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
border-right-width: 0;
border-left-color: #999;
border-left-color: rgba(0, 0, 0, .25);
}
.popover.left > .arrow:after {
right: 1px;
bottom: -10px;
content: " ";
border-right-width: 0;
border-left-color: #fff;
}
.btn {
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
}
.btn:focus, .btn:active:focus, .btn.active:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn:hover, .btn:focus {
color: #333;
text-decoration: none;
}
.btn:active, .btn.active {
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default {
color: #333;
background-color: #ebebeb;
border-color: #adadad;
}
.btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default {
background-image: none;
}
.btn-block {
display: block;
width: 100%;
}
.text-primary {
color: #428bca;
}
/* !
* ClockPicker v{package.version} for Bootstrap (http://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei.
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE) */
.clockpicker .input-group-addon {
cursor: pointer;
}
.clockpicker-moving {
cursor: move;
}
.clockpicker-align-left.popover > .arrow {
left: 25px;
}
.clockpicker-align-top.popover > .arrow {
top: 17px;
}
.clockpicker-align-right.popover > .arrow {
left: auto;
right: 25px;
}
.clockpicker-align-bottom.popover > .arrow {
top: auto;
bottom: 6px;
}
.clockpicker-popover .popover-title {
background-color: #fff;
color: #999;
font-size: 24px;
font-weight: bold;
line-height: 30px;
text-align: center;
}
.clockpicker-popover .popover-title span {
cursor: pointer;
}
.clockpicker-popover .popover-content {
background-color: #f8f8f8;
padding: 12px;
}
.popover-content:last-child {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.clockpicker-plate {
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
width: 200px;
height: 200px;
overflow: visible;
position: relative;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.clockpicker-canvas, .clockpicker-dial {
width: 200px;
height: 200px;
position: absolute;
left: -1px;
top: -1px;
}
.clockpicker-minutes {
visibility: hidden;
}
.clockpicker-tick {
border-radius: 50%;
color: #666;
line-height: 26px;
text-align: center;
width: 26px;
height: 26px;
position: absolute;
cursor: pointer;
}
.clockpicker-tick.active, .clockpicker-tick:hover {
background-color: rgb(192, 229, 247);
background-color: rgba(0, 149, 221, .25);
}
.clockpicker-button {
background-image: none;
background-color: #fff;
border-width: 1px 0 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
margin: 0;
padding: 10px 0;
}
.clockpicker-button:hover {
background-image: none;
background-color: #ebebeb;
}
.clockpicker-button:focus {
outline: none!important;
}
.clockpicker-dial {
-webkit-transition: -webkit-transform 350ms, opacity 350ms;
-moz-transition: -moz-transform 350ms, opacity 350ms;
-ms-transition: -ms-transform 350ms, opacity 350ms;
-o-transition: -o-transform 350ms, opacity 350ms;
transition: transform 350ms, opacity 350ms;
}
.clockpicker-dial-out {
opacity: 0;
}
.clockpicker-hours.clockpicker-dial-out {
-webkit-transform: scale(1.2, 1.2);
-moz-transform: scale(1.2, 1.2);
-ms-transform: scale(1.2, 1.2);
-o-transform: scale(1.2, 1.2);
transform: scale(1.2, 1.2);
}
.clockpicker-minutes.clockpicker-dial-out {
-webkit-transform: scale(.8, .8);
-moz-transform: scale(.8, .8);
-ms-transform: scale(.8, .8);
-o-transform: scale(.8, .8);
transform: scale(.8, .8);
}
.clockpicker-canvas {
-webkit-transition: opacity 175ms;
-moz-transition: opacity 175ms;
-ms-transition: opacity 175ms;
-o-transition: opacity 175ms;
transition: opacity 175ms;
}
.clockpicker-canvas-out {
opacity: 0.25;
}
.clockpicker-canvas-bearing, .clockpicker-canvas-fg {
stroke: none;
fill: rgb(0, 149, 221);
}
.clockpicker-canvas-bg {
stroke: none;
fill: rgb(192, 229, 247);
}
.clockpicker-canvas-bg-trans {
fill: rgba(0, 149, 221, .25);
}
.clockpicker-canvas line {
stroke: rgb(0, 149, 221);
stroke-width: 1;
stroke-linecap: round;
/*shape-rendering: crispEdges;*/
}
.clockpicker-button.am-button {
margin: 1px;
padding: 5px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 4px;
}
.clockpicker-button.pm-button {
margin: 1px 1px 1px 136px;
padding: 5px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 4px;
}

View File

@@ -0,0 +1,978 @@
/*!
* ClockPicker v0.2.3 original by (http://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei.
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
* Bootstrap 4 support by djibe
*/
(function($) {
var $win = $(window),
$doc = $(document),
$body;
// Can I use inline svg ?
var svgNS = "http://www.w3.org/2000/svg",
svgSupported =
"SVGAngle" in window &&
(function() {
var supported,
el = document.createElement("div");
el.innerHTML = "<svg/>";
supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS;
el.innerHTML = "";
return supported;
})();
// Can I use transition ?
var transitionSupported = (function() {
var style = document.createElement("div").style;
return (
"transition" in style ||
"WebkitTransition" in style ||
"MozTransition" in style ||
"msTransition" in style ||
"OTransition" in style
);
})();
// Listen touch events in touch screen device, instead of mouse events in desktop.
var touchSupported = "ontouchstart" in window,
mousedownEvent = "mousedown" + (touchSupported ? " touchstart" : ""),
mousemoveEvent =
"mousemove.clockpicker" +
(touchSupported ? " touchmove.clockpicker" : ""),
mouseupEvent =
"mouseup.clockpicker" + (touchSupported ? " touchend.clockpicker" : "");
// Vibrate the device if supported
var vibrate = navigator.vibrate
? "vibrate"
: navigator.webkitVibrate
? "webkitVibrate"
: null;
function createSvgElement(name) {
return document.createElementNS(svgNS, name);
}
function leadingZero(num) {
return (num < 10 ? "0" : "") + num;
}
// Get a unique id
var idCounter = 0;
function uniqueId(prefix) {
var id = ++idCounter + "";
return prefix ? prefix + id : id;
}
// Clock size
var dialRadius = 100,
outerRadius = 80,
// innerRadius = 80 on 12 hour clock
innerRadius = 54,
tickRadius = 13;
(diameter = dialRadius * 2), (duration = transitionSupported ? 350 : 1);
// Popover template
var tpl = [
'<div class="popover clockpicker-popover">',
'<div class="arrow"></div>',
'<div class="popover-header">',
'<span class="clockpicker-span-hours"></span>',
":",
'<span class="clockpicker-span-minutes text-white-50"></span>',
'<span class="clockpicker-buttons-am-pm"></span>',
"</div>",
'<div class="popover-body">',
'<div class="clockpicker-plate">',
'<div class="clockpicker-canvas"></div>',
'<div class="clockpicker-dial clockpicker-hours"></div>',
'<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',
"</div>",
'<div class="clockpicker-close-block justify-content-end"></div>',
"</div>",
"</div>"
].join("");
// ClockPicker
function ClockPicker(element, options) {
var popover = $(tpl),
plate = popover.find(".clockpicker-plate"),
hoursView = popover.find(".clockpicker-hours"),
minutesView = popover.find(".clockpicker-minutes"),
isInput = element.prop("tagName") === "INPUT",
input = isInput ? element : element.find("input"),
isHTML5 = input.prop("type") === "time",
addon = element.find(".input-group-addon"),
popoverBody = popover.find(".popover-body"),
closeBlock = popoverBody.find(".clockpicker-close-block"),
self = this,
timer;
this.id = uniqueId("cp");
this.element = element;
this.options = options;
this.options.hourstep = this.parseStep(this.options.hourstep, 12);
this.options.minutestep = this.parseStep(this.options.minutestep, 60);
this.isAppended = false;
this.isShown = false;
this.currentView = "hours";
this.isInput = isInput;
this.isHTML5 = isHTML5;
this.input = input;
this.addon = addon;
this.popover = popover;
this.plate = plate;
this.hoursView = hoursView;
this.minutesView = minutesView;
this.spanHours = popover.find(".clockpicker-span-hours");
this.spanMinutes = popover.find(".clockpicker-span-minutes");
this.buttonsAmPm = popover.find(".clockpicker-buttons-am-pm");
this.currentPlacementClass = options.placement;
this.raiseCallback = function() {
raiseCallback.apply(self, arguments);
};
// Setup for for 12 hour clock if option is selected
if (options.twelvehour) {
$(this.buttonsAmPm).css("display", "flex");
$('<a class="btn-am">AM</a>')
.on("click", function() {
self.amOrPm = "AM";
$(this).removeClass("text-white-50");
$(".btn-pm").addClass("text-white-50");
if (options.ampmSubmit) {
setTimeout(function() {
self.done();
}, duration / 2);
}
})
.appendTo(this.buttonsAmPm);
$('<a class="btn-pm text-white-50">PM</a>')
.on("click", function() {
self.amOrPm = "PM";
$(this).removeClass("text-white-50");
$(".btn-am").addClass("text-white-50");
if (options.ampmSubmit) {
setTimeout(function() {
self.done();
}, duration / 2);
}
})
.appendTo(this.buttonsAmPm);
}
if (!options.autoclose) {
// If autoclose is not setted, append a button
closeBlock
.append(
'<button type="button" class="btn btn-sm btn-outline-primary cancel">' +
options.canceltext +
"</button>"
)
.on("click", ".cancel", function () {
self.hide();
});
closeBlock
.css("display", "flex")
.append(
'<button type="button" class="btn btn-sm btn-outline-primary done">' +
options.donetext +
"</button>"
)
.on("click", ".done", $.proxy(this.done, this));
}
// Placement and arrow align - make sure they make sense.
if (
/^(top|bottom)/.test(options.placement) &&
(options.align === "top" || options.align === "bottom")
)
options.align = "left";
if (
(options.placement === "left" || options.placement === "right") &&
(options.align === "left" || options.align === "right")
)
options.align = "top";
popover.addClass(options.placement);
popover.addClass("clockpicker-align-" + options.align);
this.spanHours.click($.proxy(this.toggleView, this, "hours"));
this.spanMinutes.click($.proxy(this.toggleView, this, "minutes"));
// Show or toggle
if (!options.addonOnly) {
input.on("focus.clockpicker click.clockpicker", $.proxy(this.show, this));
}
addon.on("click.clockpicker", $.proxy(this.toggle, this));
// Build ticks
var tickTpl = $('<div class="clockpicker-tick"></div>'),
i,
tick,
radian,
radius;
// Hours view
if (options.twelvehour) {
for (i = 0; i < 12; i += options.hourstep) {
tick = tickTpl.clone();
radian = (i / 6) * Math.PI;
radius = outerRadius;
tick.css("font-size", "120%");
tick.css({
left: dialRadius + Math.sin(radian) * radius - tickRadius,
top: dialRadius - Math.cos(radian) * radius - tickRadius
});
tick.html(i === 0 ? 12 : i);
hoursView.append(tick);
tick.on(mousedownEvent, mousedown);
}
} else {
for (i = 0; i < 24; i += options.hourstep) {
var isDisabled = false;
if (
options.disabledhours &&
$.inArray(i, options.disabledhours) != -1
) {
var isDisabled = true;
}
tick = tickTpl.clone();
radian = (i / 6) * Math.PI;
var inner = i > 0 && i < 13;
radius = inner ? innerRadius : outerRadius;
tick.css({
left: dialRadius + Math.sin(radian) * radius - tickRadius,
top: dialRadius - Math.cos(radian) * radius - tickRadius
});
if (inner) {
tick.css("font-size", "120%");
}
if (isDisabled) {
tick.addClass("disabled");
}
tick.html(i === 0 ? "00" : i);
hoursView.append(tick);
if (!isDisabled) {
tick.on(mousedownEvent, mousedown);
}
}
}
// Minutes view
var incrementValue = Math.max(options.minutestep, 5);
for (i = 0; i < 60; i += incrementValue) {
tick = tickTpl.clone();
radian = (i / 30) * Math.PI;
tick.css({
left: dialRadius + Math.sin(radian) * outerRadius - tickRadius,
top: dialRadius - Math.cos(radian) * outerRadius - tickRadius
});
tick.css("font-size", "120%");
tick.html(leadingZero(i));
minutesView.append(tick);
tick.on(mousedownEvent, mousedown);
}
// Clicking on minutes view space
plate.on(mousedownEvent, function(e) {
if ($(e.target).closest(".clockpicker-tick").length === 0) {
mousedown(e, true);
}
});
// Mousedown or touchstart
function mousedown(e, space) {
var offset = plate.offset(),
isTouch = /^touch/.test(e.type),
x0 = offset.left + dialRadius,
y0 = offset.top + dialRadius,
dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0,
z = Math.sqrt(dx * dx + dy * dy),
moved = false;
// When clicking on minutes view space, check the mouse position
if (
space &&
(z < outerRadius - tickRadius || z > outerRadius + tickRadius)
) {
return;
}
e.preventDefault();
// Set cursor style of body after 200ms
var movingTimer = setTimeout(function() {
$body.addClass("clockpicker-moving");
}, 200);
// Place the canvas to top
if (svgSupported) {
plate.append(self.canvas);
}
// Clock
self.setHand(dx, dy, true);
// Mousemove on document
$doc.off(mousemoveEvent).on(mousemoveEvent, function(e) {
e.preventDefault();
var isTouch = /^touch/.test(e.type),
x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0;
if (!moved && x === dx && y === dy) {
// Clicking in chrome on windows will trigger a mousemove event
return;
}
moved = true;
self.setHand(x, y, true);
});
// Mouseup on document
$doc.off(mouseupEvent).on(mouseupEvent, function(e) {
$doc.off(mouseupEvent);
e.preventDefault();
var isTouch = /^touch/.test(e.type),
x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0,
y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0;
if ((space || moved) && x === dx && y === dy) {
self.setHand(x, y);
}
if (self.currentView === "hours") {
self.toggleView("minutes", duration / 2);
} else {
if (options.autoclose) {
if (!options.ampmSubmit) {
self.minutesView.addClass("clockpicker-dial-out");
setTimeout(function() {
self.done();
}, duration / 2);
}
}
}
plate.prepend(canvas);
// Reset cursor style of body
clearTimeout(movingTimer);
$body.removeClass("clockpicker-moving");
// Unbind mousemove event
$doc.off(mousemoveEvent);
});
}
if (svgSupported) {
// Draw clock hands and others
var canvas = popover.find(".clockpicker-canvas"),
svg = createSvgElement("svg");
svg.setAttribute("class", "clockpicker-svg");
svg.setAttribute("width", diameter);
svg.setAttribute("height", diameter);
var g = createSvgElement("g");
g.setAttribute(
"transform",
"translate(" + dialRadius + "," + dialRadius + ")"
);
var bearing = createSvgElement("circle");
bearing.setAttribute("class", "clockpicker-canvas-bearing");
bearing.setAttribute("cx", 0);
bearing.setAttribute("cy", 0);
bearing.setAttribute("r", 3);
var hand = createSvgElement("line");
hand.setAttribute("x1", 0);
hand.setAttribute("y1", 0);
var bg = createSvgElement("circle");
bg.setAttribute("class", "clockpicker-canvas-bg");
bg.setAttribute("r", tickRadius);
var fg = createSvgElement("circle");
fg.setAttribute("class", "clockpicker-canvas-fg");
fg.setAttribute("r", 3.5);
g.appendChild(hand);
g.appendChild(bg);
g.appendChild(fg);
g.appendChild(bearing);
svg.appendChild(g);
canvas.append(svg);
this.hand = hand;
this.bg = bg;
this.fg = fg;
this.bearing = bearing;
this.g = g;
this.canvas = canvas;
}
this.raiseCallback(this.options.init, "init");
}
function raiseCallback(callbackFunction, triggerName) {
if (
callbackFunction &&
typeof callbackFunction === "function" &&
this.element
) {
var time = this.getTime() || null;
callbackFunction.call(this.element, time);
}
if (triggerName) {
this.element.trigger("clockpicker." + triggerName || "NoName");
}
}
/**
* Find most suitable vertical placement, doing our best to ensure it is inside of the viewport.
*
* First try to place the element according with preferredPlacement, then try the opposite
* placement and as a last resort, popover will be placed on the very top of the viewport.
*
* @param {jQuery} element
* @param {jQuery} popover
* @param preferredPlacement Preferred placement, if there is enough room for it.
* @returns {string} One of: 'top', 'bottom' or 'viewport-top'.
*/
function resolveAdaptiveVerticalPlacement(
element,
popover,
preferredPlacement
) {
var popoverHeight = popover.outerHeight(),
elementHeight = element.outerHeight(),
elementTopOffset = element.offset().top,
elementBottomOffset = element.offset().top + elementHeight,
minVisibleY = elementTopOffset - element[0].getBoundingClientRect().top,
maxVisibleY = minVisibleY + document.documentElement.clientHeight,
isEnoughRoomAbove = elementTopOffset - popoverHeight >= minVisibleY,
isEnoughRoomBelow = elementBottomOffset + popoverHeight <= maxVisibleY;
if (preferredPlacement === "top") {
if (isEnoughRoomAbove) {
return "top";
} else if (isEnoughRoomBelow) {
return "bottom";
}
} else {
if (isEnoughRoomBelow) {
return "bottom";
} else if (isEnoughRoomAbove) {
return "top";
}
}
return "viewport-top";
}
ClockPicker.prototype.parseStep = function(givenStepSize, wholeSize) {
return wholeSize % givenStepSize === 0 ? givenStepSize : 1;
};
// Default options
ClockPicker.DEFAULTS = {
default: "", // default time, 'now' or '13:14' e.g.
fromnow: 0, // set default time to * milliseconds from now (using with default = 'now')
placement: "bottom", // clock popover placement
align: "left", // popover arrow align
donetext: "OK", // done button text
canceltext: "Cancel", // cancel button text
autoclose: false, // auto close when minute is selected
twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
vibrate: true, // vibrate the device when dragging clock hand
hourstep: 1, // allow to multi increment the hour
minutestep: 1, // allow to multi increment the minute
ampmSubmit: false, // allow submit with AM and PM buttons instead of the minute selection/picker
addonOnly: false, // only open on clicking on the input-addon
disabledhours: null // disabled hours (only 24 hour mode)
};
// Show or hide popover
ClockPicker.prototype.toggle = function() {
this[this.isShown ? "hide" : "show"]();
};
// Set new placement class for popover and remove the old one, if any.
ClockPicker.prototype.updatePlacementClass = function(newClass) {
if (this.currentPlacementClass) {
this.popover.removeClass(this.currentPlacementClass);
}
if (newClass) {
this.popover.addClass(newClass);
}
this.currentPlacementClass = newClass;
};
// Set popover position and update placement class, if needed
ClockPicker.prototype.locate = function() {
var element = this.element,
popover = this.popover,
offset = element.offset(),
width = element.outerWidth(),
height = element.outerHeight(),
placement = this.options.placement,
align = this.options.align,
windowHeight = $win.height(),
windowWidth = $win.width(),
popoverHeight = popover.height(),
popoverWidth = popover.width(),
styles = {},
self = this;
if (placement === "top-adaptive" || placement === "bottom-adaptive") {
var preferredPlacement = placement.substr(0, placement.indexOf("-"));
// Adaptive placement should be resolved into one of the "static" placement
// options, that is best suitable for the current window scroll position.
placement = resolveAdaptiveVerticalPlacement(
element,
popover,
preferredPlacement
);
this.updatePlacementClass(placement !== "viewport-top" ? placement : "");
}
popover.show();
// Place the popover
switch (placement) {
case "bottom":
styles.top = offset.top + height;
break;
case "right":
styles.left = offset.left + width;
break;
case "top":
styles.top = offset.top - popover.outerHeight();
break;
case "left":
styles.left = offset.left - popover.outerWidth();
break;
case "viewport-top":
styles.top = offset.top - element[0].getBoundingClientRect().top;
break;
}
// Align the popover arrow
switch (align) {
case "left":
styles.left = offset.left;
break;
case "right":
styles.left = offset.left + width - popover.outerWidth();
break;
case "top":
styles.top = offset.top;
break;
case "bottom":
styles.top = offset.top + height - popover.outerHeight();
break;
}
// Correct the popover position outside the window
if (popoverHeight + styles.top > windowHeight) {
styles.top = windowHeight - popoverHeight;
}
if (popoverWidth + styles.left > windowWidth) {
styles.left = windowWidth - popoverWidth;
}
popover.css(styles);
};
// The input can be changed by the user
// So before we can use this.hours/this.minutes we must update it
ClockPicker.prototype.parseInputValue = function() {
var value = this.input.prop("value") || this.options["default"] || "";
if (value === "now") {
value = new Date(+new Date() + this.options.fromnow);
}
if (value instanceof Date) {
value = value.getHours() + ":" + value.getMinutes();
}
value = value.split(":");
// Minutes can have AM/PM that needs to be removed
this.hours = +value[0] || 0;
this.minutes = +(value[1] + "").replace(/\D/g, "") || 0;
this.hours =
Math.round(this.hours / this.options.hourstep) * this.options.hourstep;
this.minutes =
Math.round(this.minutes / this.options.minutestep) *
this.options.minutestep;
if (this.options.twelvehour) {
var period = (value[1] + "").replace(/\d+/g, "").toLowerCase();
//this.amOrPm = this.hours > 12 || period === "pm" ? "PM" : "AM";
this.amOrPm = this.hours < 12 || period === "am" ? "AM" : "PM";
}
};
// Show popover
ClockPicker.prototype.show = function(e) {
// Not show again
if (this.isShown) {
return;
}
this.raiseCallback(this.options.beforeShow, "beforeShow");
var self = this;
// Initialize
if (!this.isAppended) {
// Append popover to body
$body = $(document.body).append(this.popover);
// Reset position when resize
$win.on("resize.clockpicker" + this.id, function() {
if (self.isShown) {
self.locate();
}
});
this.isAppended = true;
}
// Get the time from the input field
this.parseInputValue();
this.spanHours.html(leadingZero(this.hours));
this.spanMinutes.html(leadingZero(this.minutes));
// Toggle to hours view
this.toggleView("hours");
// Set position
this.locate();
this.isShown = true;
// Hide when clicking or tabbing on any element except the clock, input and addon
$doc.on(
"click.clockpicker." + this.id + " focusin.clockpicker." + this.id,
function(e) {
var target = $(e.target);
if (
target.closest(self.popover).length === 0 &&
target.closest(self.addon).length === 0 &&
target.closest(self.input).length === 0
) {
self.hide();
}
}
);
// Hide when ESC is pressed
$doc.on("keyup.clockpicker." + this.id, function(e) {
if (e.keyCode === 27) {
self.hide();
}
});
this.raiseCallback(this.options.afterShow, "afterShow");
};
// Hide popover
ClockPicker.prototype.hide = function() {
this.raiseCallback(this.options.beforeHide, "beforeHide");
this.isShown = false;
// Unbinding events on document
$doc.off(
"click.clockpicker." + this.id + " focusin.clockpicker." + this.id
);
$doc.off("keyup.clockpicker." + this.id);
this.popover.hide();
this.raiseCallback(this.options.afterHide, "afterHide");
};
// Toggle to hours or minutes view
ClockPicker.prototype.toggleView = function(view, delay) {
var raiseAfterHourSelect = false;
if (
view === "minutes" &&
$(this.hoursView).css("visibility") === "visible"
) {
this.raiseCallback(this.options.beforeHourSelect, "beforeHourSelect");
raiseAfterHourSelect = true;
}
var isHours = view === "hours",
nextView = isHours ? this.hoursView : this.minutesView,
hideView = isHours ? this.minutesView : this.hoursView;
this.currentView = view;
this.spanHours.toggleClass("text-white-50", !isHours);
this.spanMinutes.toggleClass("text-white-50", isHours);
// Let's make transitions
hideView.addClass("clockpicker-dial-out");
nextView.css("visibility", "visible").removeClass("clockpicker-dial-out");
// Reset clock hand
this.resetClock(delay);
// After transitions ended
clearTimeout(this.toggleViewTimer);
this.toggleViewTimer = setTimeout(function() {
hideView.css("visibility", "hidden");
}, duration);
if (raiseAfterHourSelect) {
this.raiseCallback(this.options.afterHourSelect, "afterHourSelect");
}
};
// Reset clock hand
ClockPicker.prototype.resetClock = function(delay) {
var view = this.currentView,
value = this[view],
isHours = view === "hours",
unit = Math.PI / (isHours ? 6 : 30),
radian = value * unit,
radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius,
x = Math.sin(radian) * radius,
y = -Math.cos(radian) * radius,
self = this;
if (svgSupported && delay) {
self.canvas.addClass("clockpicker-canvas-out");
setTimeout(function() {
self.canvas.removeClass("clockpicker-canvas-out");
self.setHand(x, y);
}, delay);
} else {
this.setHand(x, y);
}
};
// Set clock hand to (x, y)
ClockPicker.prototype.setHand = function(x, y, dragging) {
var radian = Math.atan2(x, -y),
isHours = this.currentView === "hours",
z = Math.sqrt(x * x + y * y),
options = this.options,
inner = isHours && z < (outerRadius + innerRadius) / 2,
radius = inner ? innerRadius : outerRadius,
unit,
value;
// Calculate the unit
if (isHours) {
unit = (options.hourstep / 6) * Math.PI;
} else {
unit = (options.minutestep / 30) * Math.PI;
}
if (options.twelvehour) {
radius = outerRadius;
}
// Radian should in range [0, 2PI]
if (radian < 0) {
radian = Math.PI * 2 + radian;
}
// Get the round value
value = Math.round(radian / unit);
// Get the round radian
radian = value * unit;
// Correct the hours or minutes
if (isHours) {
value *= options.hourstep;
if (!options.twelvehour && !inner == value > 0) {
value += 12;
}
if (options.twelvehour && value === 0) {
value = 12;
}
if (value === 24) {
value = 0;
}
if (
dragging &&
!options.twelvehour &&
options.disabledhours &&
$.inArray(value, options.disabledhours) != -1
) {
return;
}
} else {
value *= options.minutestep;
if (value === 60) {
value = 0;
}
}
// Once hours or minutes changed, vibrate the device
if (this[this.currentView] !== value) {
if (vibrate && this.options.vibrate) {
// Do not vibrate too frequently
if (!this.vibrateTimer) {
navigator[vibrate](10);
this.vibrateTimer = setTimeout(
$.proxy(function() {
this.vibrateTimer = null;
}, this),
100
);
}
}
}
this[this.currentView] = value;
this[isHours ? "spanHours" : "spanMinutes"].html(leadingZero(value));
// If svg is not supported, just add an active class to the tick
if (!svgSupported) {
this[isHours ? "hoursView" : "minutesView"]
.find(".clockpicker-tick")
.each(function() {
var tick = $(this);
tick.toggleClass("active", value === +tick.html());
});
return;
}
// Place clock hand at the top when dragging
if (dragging || (!isHours && value % 5)) {
this.g.insertBefore(this.hand, this.bearing);
this.g.insertBefore(this.bg, this.fg);
this.bg.setAttribute(
"class",
"clockpicker-canvas-bg clockpicker-canvas-bg-trans"
);
} else {
// Or place it at the bottom
this.g.insertBefore(this.hand, this.bg);
this.g.insertBefore(this.fg, this.bg);
this.bg.setAttribute("class", "clockpicker-canvas-bg");
}
// Set clock hand and others' position
var cx = Math.sin(radian) * radius,
cy = -Math.cos(radian) * radius;
this.hand.setAttribute("x2", cx);
this.hand.setAttribute("y2", cy);
this.bg.setAttribute("cx", cx);
this.bg.setAttribute("cy", cy);
this.fg.setAttribute("cx", cx);
this.fg.setAttribute("cy", cy);
};
// Allow user to get time time as Date object
ClockPicker.prototype.getTime = function(callback) {
var hours = this.hours;
if (this.options.twelvehour && hours < 12 && this.amOrPm === "PM") {
hours += 12;
}
var selectedTime = new Date();
selectedTime.setMinutes(this.minutes);
selectedTime.setHours(hours);
selectedTime.setSeconds(0);
return (
(callback && callback.apply(this.element, selectedTime)) || selectedTime
);
};
// Hours and minutes are selected
ClockPicker.prototype.done = function() {
this.raiseCallback(this.options.beforeDone, "beforeDone");
this.hide();
var last = this.input.prop("value"),
outHours = this.hours,
value = ":" + leadingZero(this.minutes);
if (this.isHTML5 && this.options.twelvehour) {
if (this.hours < 12 && this.amOrPm === "PM") {
outHours += 12;
}
if (this.hours === 12 && this.amOrPm === "AM") {
outHours = 0;
}
}
value = leadingZero(outHours) + value;
if (!this.isHTML5 && this.options.twelvehour) {
value = value + this.amOrPm;
}
this.input.prop("value", value);
if (value !== last) {
this.input.trigger("change");
if (!this.isInput) {
this.element.trigger("change");
}
}
if (this.options.autoclose) {
this.input.trigger("blur");
}
this.raiseCallback(this.options.afterDone, "afterDone");
};
// Remove clockpicker from input
ClockPicker.prototype.remove = function() {
this.element.removeData("clockpicker");
this.input.off("focus.clockpicker click.clockpicker");
this.addon.off("click.clockpicker");
if (this.isShown) {
this.hide();
}
if (this.isAppended) {
$win.off("resize.clockpicker" + this.id);
this.popover.remove();
}
};
// Extends $.fn.clockpicker
$.fn.clockpicker = function(option) {
var args = Array.prototype.slice.call(arguments, 1);
function handleClockPickerRequest() {
var $this = $(this),
data = $this.data("clockpicker");
if (!data) {
var options = $.extend(
{},
ClockPicker.DEFAULTS,
$this.data(),
typeof option == "object" && option
);
$this.data("clockpicker", new ClockPicker($this, options));
} else {
// Manual operations. show, hide, remove, getTime, e.g.
if (typeof data[option] === "function") {
return data[option].apply(data, args);
}
}
}
// If we explicitly do a call on a single element then we can return the value (if needed)
// This allows us, for example, to return the value of getTime
if (this.length == 1) {
var returnValue = handleClockPickerRequest.apply(this[0]);
// If we do not have any return value then return the object itself so you can chain
return returnValue !== undefined ? returnValue : this;
}
// If we do have a list then we do not care about return values
return this.each(handleClockPickerRequest);
};
})(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,729 @@
/*!
* ClockPicker v0.0.7 (http://weareoutman.github.io/clockpicker/)
* Copyright 2014 Wang Shenwei.
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
*/
;(function(){
var $ = window.jQuery,
$win = $(window),
$doc = $(document),
$body;
// Can I use inline svg ?
var svgNS = 'http://www.w3.org/2000/svg',
svgSupported = 'SVGAngle' in window && (function(){
var supported,
el = document.createElement('div');
el.innerHTML = '<svg/>';
supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS;
el.innerHTML = '';
return supported;
})();
// Can I use transition ?
var transitionSupported = (function(){
var style = document.createElement('div').style;
return 'transition' in style ||
'WebkitTransition' in style ||
'MozTransition' in style ||
'msTransition' in style ||
'OTransition' in style;
})();
// Listen touch events in touch screen device, instead of mouse events in desktop.
var touchSupported = 'ontouchstart' in window,
mousedownEvent = 'mousedown' + ( touchSupported ? ' touchstart' : ''),
mousemoveEvent = 'mousemove.clockpicker' + ( touchSupported ? ' touchmove.clockpicker' : ''),
mouseupEvent = 'mouseup.clockpicker' + ( touchSupported ? ' touchend.clockpicker' : '');
// Vibrate the device if supported
var vibrate = navigator.vibrate ? 'vibrate' : navigator.webkitVibrate ? 'webkitVibrate' : null;
function createSvgElement(name) {
return document.createElementNS(svgNS, name);
}
function leadingZero(num) {
return (num < 10 ? '0' : '') + num;
}
// Get a unique id
var idCounter = 0;
function uniqueId(prefix) {
var id = ++idCounter + '';
return prefix ? prefix + id : id;
}
// Clock size
var dialRadius = 100,
outerRadius = 80,
// innerRadius = 80 on 12 hour clock
innerRadius = 54,
tickRadius = 13,
diameter = dialRadius * 2,
duration = transitionSupported ? 350 : 1;
// Popover template
var tpl = [
'<div class="popover clockpicker-popover">',
'<div class="arrow"></div>',
'<div class="popover-title">',
'<span class="clockpicker-span-hours text-primary"></span>',
' : ',
'<span class="clockpicker-span-minutes"></span>',
'<span class="clockpicker-span-am-pm"></span>',
'</div>',
'<div class="popover-content">',
'<div class="clockpicker-plate">',
'<div class="clockpicker-canvas"></div>',
'<div class="clockpicker-dial clockpicker-hours"></div>',
'<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',
'</div>',
'<span class="clockpicker-am-pm-block">',
'</span>',
'</div>',
'</div>'
].join('');
// ClockPicker
function ClockPicker(element, options) {
var popover = $(tpl),
plate = popover.find('.clockpicker-plate'),
hoursView = popover.find('.clockpicker-hours'),
minutesView = popover.find('.clockpicker-minutes'),
amPmBlock = popover.find('.clockpicker-am-pm-block'),
isInput = element.prop('tagName') === 'INPUT',
input = isInput ? element : element.find('input'),
addon = element.find('.input-group-addon'),
self = this,
timer;
this.id = uniqueId('cp');
this.element = element;
this.options = options;
this.isAppended = false;
this.isShown = false;
this.currentView = 'hours';
this.isInput = isInput;
this.input = input;
this.addon = addon;
this.popover = popover;
this.plate = plate;
this.hoursView = hoursView;
this.minutesView = minutesView;
this.amPmBlock = amPmBlock;
this.spanHours = popover.find('.clockpicker-span-hours');
this.spanMinutes = popover.find('.clockpicker-span-minutes');
this.spanAmPm = popover.find('.clockpicker-span-am-pm');
this.amOrPm = "PM";
// Setup for for 12 hour clock if option is selected
if (options.twelvehour) {
var amPmButtonsTemplate = ['<div class="clockpicker-am-pm-block">',
'<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-am-button">',
'AM</button>',
'<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-pm-button">',
'PM</button>',
'</div>'].join('');
var amPmButtons = $(amPmButtonsTemplate);
//amPmButtons.appendTo(plate);
////Not working b/c they are not shown when this runs
//$('clockpicker-am-button')
// .on("click", function() {
// self.amOrPm = "AM";
// $('.clockpicker-span-am-pm').empty().append('AM');
// });
//
//$('clockpicker-pm-button')
// .on("click", function() {
// self.amOrPm = "PM";
// $('.clockpicker-span-am-pm').empty().append('PM');
// });
$('<button type="button" class="btn btn-sm btn-default clockpicker-button am-button">' + "AM" + '</button>')
.on("click", function() {
self.amOrPm = "AM";
$('.clockpicker-span-am-pm').empty().append('AM');
}).appendTo(this.amPmBlock);
$('<button type="button" class="btn btn-sm btn-default clockpicker-button pm-button">' + "PM" + '</button>')
.on("click", function() {
self.amOrPm = 'PM';
$('.clockpicker-span-am-pm').empty().append('PM');
}).appendTo(this.amPmBlock);
}
if (! options.autoclose) {
// If autoclose is not setted, append a button
$('<button type="button" class="btn btn-sm btn-default btn-block clockpicker-button">' + options.donetext + '</button>')
.click($.proxy(this.done, this))
.appendTo(popover);
}
// Placement and arrow align - make sure they make sense.
if ((options.placement === 'top' || options.placement === 'bottom') && (options.align === 'top' || options.align === 'bottom')) options.align = 'left';
if ((options.placement === 'left' || options.placement === 'right') && (options.align === 'left' || options.align === 'right')) options.align = 'top';
popover.addClass(options.placement);
popover.addClass('clockpicker-align-' + options.align);
this.spanHours.click($.proxy(this.toggleView, this, 'hours'));
this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes'));
// Show or toggle
input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this));
addon.on('click.clockpicker', $.proxy(this.toggle, this));
// Build ticks
var tickTpl = $('<div class="clockpicker-tick"></div>'),
i, tick, radian, radius;
// Hours view
if (options.twelvehour) {
for (i = 1; i < 13; i += 1) {
tick = tickTpl.clone();
radian = i / 6 * Math.PI;
radius = outerRadius;
tick.css('font-size', '120%');
tick.css({
left: dialRadius + Math.sin(radian) * radius - tickRadius,
top: dialRadius - Math.cos(radian) * radius - tickRadius
});
tick.html(i === 0 ? '00' : i);
hoursView.append(tick);
tick.on(mousedownEvent, mousedown);
}
} else {
for (i = 0; i < 24; i += 1) {
tick = tickTpl.clone();
radian = i / 6 * Math.PI;
var inner = i > 0 && i < 13;
radius = inner ? innerRadius : outerRadius;
tick.css({
left: dialRadius + Math.sin(radian) * radius - tickRadius,
top: dialRadius - Math.cos(radian) * radius - tickRadius
});
if (inner) {
tick.css('font-size', '120%');
}
tick.html(i === 0 ? '00' : i);
hoursView.append(tick);
tick.on(mousedownEvent, mousedown);
}
}
// Minutes view
for (i = 0; i < 60; i += 5) {
tick = tickTpl.clone();
radian = i / 30 * Math.PI;
tick.css({
left: dialRadius + Math.sin(radian) * outerRadius - tickRadius,
top: dialRadius - Math.cos(radian) * outerRadius - tickRadius
});
tick.css('font-size', '120%');
tick.html(leadingZero(i));
minutesView.append(tick);
tick.on(mousedownEvent, mousedown);
}
// Clicking on minutes view space
plate.on(mousedownEvent, function(e){
if ($(e.target).closest('.clockpicker-tick').length === 0) {
mousedown(e, true);
}
});
// Mousedown or touchstart
function mousedown(e, space) {
var offset = plate.offset(),
isTouch = /^touch/.test(e.type),
x0 = offset.left + dialRadius,
y0 = offset.top + dialRadius,
dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0,
z = Math.sqrt(dx * dx + dy * dy),
moved = false;
// When clicking on minutes view space, check the mouse position
if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius)) {
return;
}
e.preventDefault();
// Set cursor style of body after 200ms
var movingTimer = setTimeout(function(){
$body.addClass('clockpicker-moving');
}, 200);
// Place the canvas to top
if (svgSupported) {
plate.append(self.canvas);
}
// Clock
self.setHand(dx, dy, ! space, true);
// Mousemove on document
$doc.off(mousemoveEvent).on(mousemoveEvent, function(e){
e.preventDefault();
var isTouch = /^touch/.test(e.type),
x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0;
if (! moved && x === dx && y === dy) {
// Clicking in chrome on windows will trigger a mousemove event
return;
}
moved = true;
self.setHand(x, y, false, true);
});
// Mouseup on document
$doc.off(mouseupEvent).on(mouseupEvent, function(e){
$doc.off(mouseupEvent);
e.preventDefault();
var isTouch = /^touch/.test(e.type),
x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0,
y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0;
if ((space || moved) && x === dx && y === dy) {
self.setHand(x, y);
}
if (self.currentView === 'hours') {
self.toggleView('minutes', duration / 2);
} else {
if (options.autoclose) {
self.minutesView.addClass('clockpicker-dial-out');
setTimeout(function(){
self.done();
}, duration / 2);
}
}
plate.prepend(canvas);
// Reset cursor style of body
clearTimeout(movingTimer);
$body.removeClass('clockpicker-moving');
// Unbind mousemove event
$doc.off(mousemoveEvent);
});
}
if (svgSupported) {
// Draw clock hands and others
var canvas = popover.find('.clockpicker-canvas'),
svg = createSvgElement('svg');
svg.setAttribute('class', 'clockpicker-svg');
svg.setAttribute('width', diameter);
svg.setAttribute('height', diameter);
var g = createSvgElement('g');
g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')');
var bearing = createSvgElement('circle');
bearing.setAttribute('class', 'clockpicker-canvas-bearing');
bearing.setAttribute('cx', 0);
bearing.setAttribute('cy', 0);
bearing.setAttribute('r', 2);
var hand = createSvgElement('line');
hand.setAttribute('x1', 0);
hand.setAttribute('y1', 0);
var bg = createSvgElement('circle');
bg.setAttribute('class', 'clockpicker-canvas-bg');
bg.setAttribute('r', tickRadius);
var fg = createSvgElement('circle');
fg.setAttribute('class', 'clockpicker-canvas-fg');
fg.setAttribute('r', 3.5);
g.appendChild(hand);
g.appendChild(bg);
g.appendChild(fg);
g.appendChild(bearing);
svg.appendChild(g);
canvas.append(svg);
this.hand = hand;
this.bg = bg;
this.fg = fg;
this.bearing = bearing;
this.g = g;
this.canvas = canvas;
}
raiseCallback(this.options.init);
}
function raiseCallback(callbackFunction) {
if (callbackFunction && typeof callbackFunction === "function") {
callbackFunction();
}
}
// Default options
ClockPicker.DEFAULTS = {
'default': '', // default time, 'now' or '13:14' e.g.
fromnow: 0, // set default time to * milliseconds from now (using with default = 'now')
placement: 'bottom', // clock popover placement
align: 'left', // popover arrow align
donetext: '完成', // done button text
autoclose: false, // auto close when minute is selected
twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
vibrate: true // vibrate the device when dragging clock hand
};
// Show or hide popover
ClockPicker.prototype.toggle = function(){
this[this.isShown ? 'hide' : 'show']();
};
// Set popover position
ClockPicker.prototype.locate = function(){
var element = this.element,
popover = this.popover,
offset = element.offset(),
width = element.outerWidth(),
height = element.outerHeight(),
placement = this.options.placement,
align = this.options.align,
styles = {},
self = this;
popover.show();
// Place the popover
switch (placement) {
case 'bottom':
styles.top = offset.top + height;
break;
case 'right':
styles.left = offset.left + width;
break;
case 'top':
styles.top = offset.top - popover.outerHeight();
break;
case 'left':
styles.left = offset.left - popover.outerWidth();
break;
}
// Align the popover arrow
switch (align) {
case 'left':
styles.left = offset.left;
break;
case 'right':
styles.left = offset.left + width - popover.outerWidth();
break;
case 'top':
styles.top = offset.top;
break;
case 'bottom':
styles.top = offset.top + height - popover.outerHeight();
break;
}
popover.css(styles);
};
// Show popover
ClockPicker.prototype.show = function(e){
// Not show again
if (this.isShown) {
return;
}
raiseCallback(this.options.beforeShow);
var self = this;
// Initialize
if (! this.isAppended) {
// Append popover to body
$body = $(document.body).append(this.popover);
// Reset position when resize
$win.on('resize.clockpicker' + this.id, function(){
if (self.isShown) {
self.locate();
}
});
this.isAppended = true;
}
// Get the time
var value = ((this.input.prop('value') || this.options['default'] || '') + '').split(':');
if (value[0] === 'now') {
var now = new Date(+ new Date() + this.options.fromnow);
value = [
now.getHours(),
now.getMinutes()
];
}
this.hours = + value[0] || 0;
this.minutes = + value[1] || 0;
this.spanHours.html(leadingZero(this.hours));
this.spanMinutes.html(leadingZero(this.minutes));
// Toggle to hours view
this.toggleView('hours');
// Set position
this.locate();
this.isShown = true;
// Hide when clicking or tabbing on any element except the clock, input and addon
$doc.on('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id, function(e){
var target = $(e.target);
if (target.closest(self.popover).length === 0 &&
target.closest(self.addon).length === 0 &&
target.closest(self.input).length === 0) {
self.hide();
}
});
// Hide when ESC is pressed
$doc.on('keyup.clockpicker.' + this.id, function(e){
if (e.keyCode === 27) {
self.hide();
}
});
raiseCallback(this.options.afterShow);
};
// Hide popover
ClockPicker.prototype.hide = function(){
raiseCallback(this.options.beforeHide);
this.isShown = false;
// Unbinding events on document
$doc.off('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id);
$doc.off('keyup.clockpicker.' + this.id);
this.popover.hide();
raiseCallback(this.options.afterHide);
};
// Toggle to hours or minutes view
ClockPicker.prototype.toggleView = function(view, delay){
var raiseAfterHourSelect = false;
if (view === 'minutes' && $(this.hoursView).css("visibility") === "visible") {
raiseCallback(this.options.beforeHourSelect);
raiseAfterHourSelect = true;
}
var isHours = view === 'hours',
nextView = isHours ? this.hoursView : this.minutesView,
hideView = isHours ? this.minutesView : this.hoursView;
this.currentView = view;
this.spanHours.toggleClass('text-primary', isHours);
this.spanMinutes.toggleClass('text-primary', ! isHours);
// Let's make transitions
hideView.addClass('clockpicker-dial-out');
nextView.css('visibility', 'visible').removeClass('clockpicker-dial-out');
// Reset clock hand
this.resetClock(delay);
// After transitions ended
clearTimeout(this.toggleViewTimer);
this.toggleViewTimer = setTimeout(function(){
hideView.css('visibility', 'hidden');
}, duration);
if (raiseAfterHourSelect) {
raiseCallback(this.options.afterHourSelect);
}
};
// Reset clock hand
ClockPicker.prototype.resetClock = function(delay){
var view = this.currentView,
value = this[view],
isHours = view === 'hours',
unit = Math.PI / (isHours ? 6 : 30),
radian = value * unit,
radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius,
x = Math.sin(radian) * radius,
y = - Math.cos(radian) * radius,
self = this;
if (svgSupported && delay) {
self.canvas.addClass('clockpicker-canvas-out');
setTimeout(function(){
self.canvas.removeClass('clockpicker-canvas-out');
self.setHand(x, y);
}, delay);
} else {
this.setHand(x, y);
}
};
// Set clock hand to (x, y)
ClockPicker.prototype.setHand = function(x, y, roundBy5, dragging){
var radian = Math.atan2(x, - y),
isHours = this.currentView === 'hours',
unit = Math.PI / (isHours || roundBy5 ? 6 : 30),
z = Math.sqrt(x * x + y * y),
options = this.options,
inner = isHours && z < (outerRadius + innerRadius) / 2,
radius = inner ? innerRadius : outerRadius,
value;
if (options.twelvehour) {
radius = outerRadius;
}
// Radian should in range [0, 2PI]
if (radian < 0) {
radian = Math.PI * 2 + radian;
}
// Get the round value
value = Math.round(radian / unit);
// Get the round radian
radian = value * unit;
// Correct the hours or minutes
if (options.twelvehour) {
if (isHours) {
if (value === 0) {
value = 12;
}
} else {
if (roundBy5) {
value *= 5;
}
if (value === 60) {
value = 0;
}
}
} else {
if (isHours) {
if (value === 12) {
value = 0;
}
value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12;
} else {
if (roundBy5) {
value *= 5;
}
if (value === 60) {
value = 0;
}
}
}
// Once hours or minutes changed, vibrate the device
if (this[this.currentView] !== value) {
if (vibrate && this.options.vibrate) {
// Do not vibrate too frequently
if (! this.vibrateTimer) {
navigator[vibrate](10);
this.vibrateTimer = setTimeout($.proxy(function(){
this.vibrateTimer = null;
}, this), 100);
}
}
}
this[this.currentView] = value;
this[isHours ? 'spanHours' : 'spanMinutes'].html(leadingZero(value));
// If svg is not supported, just add an active class to the tick
if (! svgSupported) {
this[isHours ? 'hoursView' : 'minutesView'].find('.clockpicker-tick').each(function(){
var tick = $(this);
tick.toggleClass('active', value === + tick.html());
});
return;
}
// Place clock hand at the top when dragging
if (dragging || (! isHours && value % 5)) {
this.g.insertBefore(this.hand, this.bearing);
this.g.insertBefore(this.bg, this.fg);
this.bg.setAttribute('class', 'clockpicker-canvas-bg clockpicker-canvas-bg-trans');
} else {
// Or place it at the bottom
this.g.insertBefore(this.hand, this.bg);
this.g.insertBefore(this.fg, this.bg);
this.bg.setAttribute('class', 'clockpicker-canvas-bg');
}
// Set clock hand and others' position
var cx = Math.sin(radian) * radius,
cy = - Math.cos(radian) * radius;
this.hand.setAttribute('x2', cx);
this.hand.setAttribute('y2', cy);
this.bg.setAttribute('cx', cx);
this.bg.setAttribute('cy', cy);
this.fg.setAttribute('cx', cx);
this.fg.setAttribute('cy', cy);
};
// Hours and minutes are selected
ClockPicker.prototype.done = function() {
raiseCallback(this.options.beforeDone);
this.hide();
var last = this.input.prop('value'),
value = leadingZero(this.hours) + ':' + leadingZero(this.minutes);
if (this.options.twelvehour) {
value = value + this.amOrPm;
}
this.input.prop('value', value);
if (value !== last) {
this.input.triggerHandler('change');
if (! this.isInput) {
this.element.trigger('change');
}
}
if (this.options.autoclose) {
this.input.trigger('blur');
}
raiseCallback(this.options.afterDone);
};
// Remove clockpicker from input
ClockPicker.prototype.remove = function() {
this.element.removeData('clockpicker');
this.input.off('focus.clockpicker click.clockpicker');
this.addon.off('click.clockpicker');
if (this.isShown) {
this.hide();
}
if (this.isAppended) {
$win.off('resize.clockpicker' + this.id);
this.popover.remove();
}
};
// Extends $.fn.clockpicker
$.fn.clockpicker = function(option){
var args = Array.prototype.slice.call(arguments, 1);
return this.each(function(){
var $this = $(this),
data = $this.data('clockpicker');
if (! data) {
var options = $.extend({}, ClockPicker.DEFAULTS, $this.data(), typeof option == 'object' && option);
$this.data('clockpicker', new ClockPicker($this, options));
} else {
// Manual operatsions. show, hide, remove, e.g.
if (typeof data[option] === 'function') {
data[option].apply(data, args);
}
}
});
};
}());

View File

@@ -139,6 +139,8 @@ function reloadTodaySchedule(APIURL = "ScheduleBank/") {
dayViewMode = 'all'; // all, everyday, monday, tuesday, wednesday, thursday, friday, saturday, sunday
scheduledate = null; // Litepicker instance for schedule date selection
scheduletime = null; // time picker instance for schedule time selection
$schedulemodal = null; // schedule modal jQuery object
$(document).ready(function () {
console.log("schedulebank.js loaded successfully");
@@ -153,6 +155,8 @@ $(document).ready(function () {
$btnEdit.prop('disabled', true);
$btnRemove.prop('disabled', true);
let APIURL = "ScheduleBank/";
if (dtScheduleBank === null) {
dtScheduleBank = new DataTable('#schedulebanktable', {
@@ -239,15 +243,24 @@ $(document).ready(function () {
})
let $schedulemodal = $('#schedulemodal');
$schedulemodal = $('#schedulemodal');
// text input
let $scheduleid = $schedulemodal.find('#scheduleid');
// text input
let $scheduledescription = $schedulemodal.find('#scheduledescription');
// number input 0-23
let $schedulehour = $schedulemodal.find('#schedulehour');
//let $schedulehour = $schedulemodal.find('#schedulehour');
// number input 0-59
let $scheduleminute = $schedulemodal.find('#scheduleminute');
//let $scheduleminute = $schedulemodal.find('#scheduleminute');
scheduletime = flatpickr("#scheduletime",{
enableTime: true,
noCalendar: true, // time only
dateFormat: "H:i", // HH:mm format
time_24hr: true, // firce 24-hour format
minuteIncrement: 1,
defaultDate: new Date()
});
// select2 for message
let $schedulemessage = $schedulemodal.find('#schedulemessage');
// number input 0-5
@@ -264,6 +277,7 @@ $(document).ready(function () {
let $weeklyselect = $schedulemodal.find('#weeklyselect');
// radio button for specific date
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
scheduledate = new Litepicker({
element: document.getElementById('scheduledate'),
@@ -276,6 +290,8 @@ $(document).ready(function () {
console.log("Selected special date: " + date.format('DD/MM/YYYY'));
}
})
// date input
//let $scheduledate = $schedulemodal.find('#scheduledate');
// select2 for language
@@ -294,8 +310,8 @@ $(document).ready(function () {
function clearScheduleModal() {
$scheduleid.prop('disabled', true).val('');
$scheduledescription.val('');
$schedulehour.val('0');
$scheduleminute.val('0');
//$schedulehour.val('0');
//$scheduleminute.val('0');
$schedulerepeat.val('1');
$scheduleenable.prop('checked', true);
$scheduleeveryday.prop('checked', false);
@@ -403,9 +419,9 @@ $(document).ready(function () {
const Language = $languageselect.val().join(';');
const broadcastZones = $schedulezones.val().join(';');
// Format time as HH:mm
const hour = parseInt($schedulehour.val(), 10);
const minute = parseInt($scheduleminute.val(), 10);
const _Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
//const hour = parseInt($schedulehour.val(), 10);
//const minute = parseInt($scheduleminute.val(), 10);
const _Time = $('#scheduletime').val();
if (Description.length > 0) {
if (_Day.length > 0) {
if (Message.length > 0) {
@@ -488,8 +504,9 @@ $(document).ready(function () {
$scheduleid.val(sr.index);
$scheduledescription.val(sr.Description);
let [hour, minute] = sr.Time.split(':').map(num => parseInt(num, 10));
$schedulehour.val(hour.toString());
$scheduleminute.val(minute.toString());
//$schedulehour.val(hour.toString());
//$scheduleminute.val(minute.toString());
scheduletime.setDate(sr.Time,true, "H:i");
$schedulemessage.val(sr.Soundpath).trigger('change');
$schedulerepeat.val(sr.Repeat);
$scheduleenable.prop('checked', sr.Enable);
@@ -562,9 +579,9 @@ $(document).ready(function () {
const BroadcastZones = $schedulezones.val().join(';');
const Language = $languageselect.val().join(';');
// Format time as HH:mm
const hour = parseInt($schedulehour.val(), 10);
const minute = parseInt($scheduleminute.val(), 10);
const Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
// const hour = parseInt($schedulehour.val(), 10);
//const minute = parseInt($scheduleminute.val(), 10);
const Time = $('#scheduletime').val();
if (Description && Description.length > 0) {
if (Day && Day.length > 0) {
if (Soundpath && Soundpath.length > 0) {

View File

@@ -67,6 +67,275 @@ function load_default_voice(){
});
}
function ValidLatitude(lat){
const num = parseFloat(lat);
return !isNaN(num) && num >= -90 && num <= 90;
}
function ValidLongitude(lon){
const num = parseFloat(lon);
return !isNaN(num) && num >= -180 && num <= 180;
}
function ValidTimezone(tz){
try{
Intl.DateTimeFormat(undefined, { timeZone: tz });
return true;
} catch(e){
return false;
}
}
function ValidHHMM(time){
const regex = /^([01]\d|2[0-3]):([0-5]\d)$/;
return regex.test(time);
}
/**
* Check if a date string is valid in DD/MM/YYYY format
* @param {string} dateStr date to check in DD/MM/YYYY format
* @returns {boolean} true if valid date in DD/MM/YYYY format, false otherwise
*/
function ValidDateDDMMYYYY(dateStr){
const regex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
if (!regex.test(dateStr)) return false;
const [day, month, year] = dateStr.split('/').map(Number);
const date = new Date(year, month - 1, day);
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
}
function ValidFilePath(path){
if (typeof path !== 'string' || path.trim() === '') return false;
// test if ends with .wav or .mp3
const regex = /\.(wav|mp3)$/i;
return regex.test(path);
}
function IsEnabled(value){
// accept "true", "false", true, false, 1, 0
// detect if value is null or undefined
if (value === null || value === undefined) return false;
if (typeof value === 'boolean') return value;
if (typeof value === 'number') return value === 1;
if (typeof value === 'string') return value.toLowerCase() === "true" || value === "1";
return false;
}
/**
* @typedef {Object} AdzanSetting
* @property {string} latitude
* @property {string} longitude
* @property {string} timezone
* @property {string} fajar_sound
* @property {string} dzuhur_sound
* @property {string} ashar_sound
* @property {string} maghrib_sound
* @property {string} isya_sound
* @property {string} fajar_time
* @property {string} dzuhur_time
* @property {string} ashar_time
* @property {string} maghrib_time
* @property {string} isya_time
* @property {boolean} fajar_enable
* @property {boolean} dzuhur_enable
* @property {boolean} ashar_enable
* @property {boolean} maghrib_enable
* @property {boolean} isya_enable
*/
function Get_AdzanSetting(){
fetchAPI("Settings/AdzanSetting", "GET", {}, null,
/**
* returned AdzanSetting data
* @param {AdzanSetting} okdata
*/
(okdata) => {
// text input for latitude, longitude, timezone
if (ValidLatitude(okdata.latitude)) {
$('#adzanlatitude').val(okdata.latitude);
} else {
$('#adzanlatitude').val("N/A");
}
if (ValidLongitude(okdata.longitude)) {
$('#adzanlongitude').val(okdata.longitude);
} else {
$('#adzanlongitude').val("N/A");
}
if (ValidTimezone(okdata.timezone)) {
$('#adzantimezone').val(okdata.timezone);
} else {
$('#adzantimezone').val("N/A");
}
// text input for adzan sound file for each prayer time
if (ValidFilePath(okdata.fajar_sound)) {
$('#fajar .adzanfile').val(okdata.fajar_sound);
} else {
$('#fajar .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.dzuhur_sound)) {
$('#dzuhur .adzanfile').val(okdata.dzuhur_sound);
} else {
$('#dzuhur .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.ashar_sound)) {
$('#ashar .adzanfile').val(okdata.ashar_sound);
} else {
$('#ashar .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.maghrib_sound)) {
$('#maghrib .adzanfile').val(okdata.maghrib_sound);
} else {
$('#maghrib .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.isya_sound)) {
$('#isya .adzanfile').val(okdata.isya_sound);
} else {
$('#isya .adzanfile').val("N/A");
}
// checkbox adzanenable for each prayer time
$('#fajar .adzanenable').prop('checked', IsEnabled(okdata.fajar_enable));
$('#dzuhur .adzanenable').prop('checked', IsEnabled(okdata.dzuhur_enable));
$('#ashar .adzanenable').prop('checked', IsEnabled(okdata.ashar_enable));
$('#maghrib .adzanenable').prop('checked', IsEnabled(okdata.maghrib_enable));
$('#isya .adzanenable').prop('checked', IsEnabled(okdata.isya_enable));
// adzantime for each prayer time
// if valid HH:MM will set <input type="time"> value, else set to undefined
if (ValidHHMM(okdata.fajar_time)) {
$('#fajar .adzantime').val(okdata.fajar_time);
} else {
$('#fajar .adzantime').val("");
}
if (ValidHHMM(okdata.dzuhur_time)) {
$('#dzuhur .adzantime').val(okdata.dzuhur_time);
} else {
$('#dzuhur .adzantime').val("");
}
if (ValidHHMM(okdata.ashar_time)) {
$('#ashar .adzantime').val(okdata.ashar_time);
} else {
$('#ashar .adzantime').val("");
}
if (ValidHHMM(okdata.maghrib_time)) {
$('#maghrib .adzantime').val(okdata.maghrib_time);
} else {
$('#maghrib .adzantime').val("");
}
if (ValidHHMM(okdata.isya_time)) {
$('#isya .adzantime').val(okdata.isya_time);
} else {
$('#isya .adzantime').val("");
}
}, (errdata) => {
alert("Error getting Adzan settings : " + errdata.message);
});
}
function Set_AdzanSetting(){
let latitude = $('#adzanlatitude').val();
if (!ValidLatitude(latitude)){
alert("Please enter a valid latitude between -90 and 90.");
return;
}
let longitude = $('#adzanlongitude').val();
if (!ValidLongitude(longitude)){
alert("Please enter a valid longitude between -180 and 180.");
return;
}
let timezone = $('#adzantimezone').val();
if (!ValidTimezone(timezone)){
alert("Please enter a valid timezone.");
return;
}
let fajar_sound = $('#fajar .adzanfile').val();
if (!ValidFilePath(fajar_sound)){
alert("Please enter a valid file path for Fajar adzan sound (must end with .wav or .mp3).");
return;
}
let dzuhur_sound = $('#dzuhur .adzanfile').val();
if (!ValidFilePath(dzuhur_sound)){
alert("Please enter a valid file path for Dzuhur adzan sound (must end with .wav or .mp3).");
return;
}
let ashar_sound = $('#ashar .adzanfile').val();
if (!ValidFilePath(ashar_sound)){
alert("Please enter a valid file path for Ashar adzan sound (must end with .wav or .mp3).");
return;
}
let maghrib_sound = $('#maghrib .adzanfile').val();
if (!ValidFilePath(maghrib_sound)){
alert("Please enter a valid file path for Maghrib adzan sound (must end with .wav or .mp3).");
return;
}
let isya_sound = $('#isya .adzanfile').val();
if (!ValidFilePath(isya_sound)){
alert("Please enter a valid file path for Isya adzan sound (must end with .wav or .mp3).");
return;
}
let fajar_enable = $('#fajar .adzanenable').prop('checked');
let dzuhur_enable = $('#dzuhur .adzanenable').prop('checked');
let ashar_enable = $('#ashar .adzanenable').prop('checked');
let maghrib_enable = $('#maghrib .adzanenable').prop('checked');
let isya_enable = $('#isya .adzanenable').prop('checked');
let fajar_time = $('#fajar .adzantime').val();
if (!ValidHHMM(fajar_time)){
alert("Please enter a valid time for Fajar adzan (HH:MM).");
return;
}
let dzuhur_time = $('#dzuhur .adzantime').val();
if (!ValidHHMM(dzuhur_time)){
alert("Please enter a valid time for Dzuhur adzan (HH:MM).");
return;
}
let ashar_time = $('#ashar .adzantime').val();
if (!ValidHHMM(ashar_time)){
alert("Please enter a valid time for Ashar adzan (HH:MM).");
return;
}
let maghrib_time = $('#maghrib .adzantime').val();
if (!ValidHHMM(maghrib_time)){
alert("Please enter a valid time for Maghrib adzan (HH:MM).");
return;
}
let isya_time = $('#isya .adzantime').val();
if (!ValidHHMM(isya_time)){
alert("Please enter a valid time for Isya adzan (HH:MM).");
return;
}
/**
* @type {AdzanSetting}
*/
let data = {
latitude: latitude,
longitude: longitude,
timezone: timezone,
fajar_sound: fajar_sound,
dzuhur_sound: dzuhur_sound,
ashar_sound: ashar_sound,
maghrib_sound: maghrib_sound,
isya_sound: isya_sound,
fajar_enable: fajar_enable,
dzuhur_enable: dzuhur_enable,
ashar_enable: ashar_enable,
maghrib_enable: maghrib_enable,
isya_enable: isya_enable,
fajar_time: fajar_time,
dzuhur_time: dzuhur_time,
ashar_time: ashar_time,
maghrib_time: maghrib_time,
isya_time: isya_time
};
fetchAPI("Settings/AdzanSetting", "POST", {}, data, (okdata) => {
alert("Adzan settings updated successfully.");
}, (errdata) => {
alert("Error updating Adzan settings : " + errdata.message);
});
}
function Get_WebAccessSetting(){
fetchAPI("Settings/WebAccess", "GET", {}, null, (okdata) => {
let adminpass = okdata.adminpass || "password";
@@ -109,8 +378,10 @@ $(document).ready(function () {
load_default_voice();
Get_OldResultDays();
Get_WebAccessSetting();
Get_AdzanSetting();
load_messagebank(() => load_remark_selection());
$("#fiscodesave").off('click').on('click', function () {
$('#fiscodesave').click(function () {
Set_OldResultDays();
let gop = $("#input_GOP").val();
let gbd = $("#input_GBD").val();
@@ -133,10 +404,13 @@ $(document).ready(function () {
} else {
alert("Please select all FIS codes (GOP, GBD, GFC, FLD) and Default Voice before saving.");
}
});
$("#webaccesssave").off('click').on('click', function () {
Set_WebAccessSetting();
$('#webaccesssave').click(function () {
Set_WebAccessSetting();
});
$('#adzansave').click(function () {
Set_AdzanSetting();
});

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -292,7 +291,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/soundchannel.js"></script>
<script src="assets/js/broadcastzones.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -156,7 +155,6 @@
<div><audio class="invisible" id="audioplayer" controls=""></audio></div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/filemanagement.js"></script>
</body>

View File

@@ -16,6 +16,8 @@
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/all.min.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/flatpickr.min.css">
<link rel="stylesheet" href="assets/css/litepicker.css">
<link rel="stylesheet" href="assets/css/select2.min.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
@@ -40,26 +42,26 @@
<div>
<hr class="mt-0">
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item"><a class="nav-link active link-light text-menu" id="homelink" href="#" aria-current="page"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-house-door me-2" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link active link-light text-menu" id="homelink" href="#" aria-current="page"><svg class="bi bi-house-door me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 20px;">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4z"></path>
</svg>&nbsp;Overview</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="soundbanklink" href="#"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-soundwave me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="soundbanklink" href="#"><svg class="bi bi-soundwave me-2 icon-menu pad-icon-menu" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 20px;">
<path fill-rule="evenodd" d="M8.5 2a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-1 0v-11a.5.5 0 0 1 .5-.5m-2 2a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5m4 0a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5m-6 1.5A.5.5 0 0 1 5 6v4a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m8 0a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m-10 1A.5.5 0 0 1 3 7v2a.5.5 0 0 1-1 0V7a.5.5 0 0 1 .5-.5m12 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0V7a.5.5 0 0 1 .5-.5"></path>
</svg>&nbsp;Sound Bank</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="messagebanklink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="messagebanklink" href="#"><svg class="me-2 icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path>
</svg>&nbsp;Message Bank</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="languagelink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="languagelink" href="#"><svg class="me-2 icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path>
</svg>&nbsp;Language Link</a></li>
<li class="nav-item .icon-menu"><a class="nav-link link-body-emphasis text-menu" id="timerlink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
<li class="nav-item .icon-menu"><a class="nav-link link-body-emphasis text-menu" id="timerlink" href="#"><svg class="me-2 icon-menu pad-icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
<path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path>
</svg>&nbsp;Timer</a></li>
<li class="nav-item .icon-menu"><a class="nav-link link-body-emphasis text-menu" id="broadcastzonelink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
<li class="nav-item .icon-menu"><a class="nav-link link-body-emphasis text-menu" id="broadcastzonelink" href="#"><svg class="me-2 icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M18.2 1H9.8C8.81 1 8 1.81 8 2.8v14.4c0 .99.81 1.79 1.8 1.79l8.4.01c.99 0 1.8-.81 1.8-1.8V2.8c0-.99-.81-1.8-1.8-1.8zM14 3c1.1 0 2 .89 2 2s-.9 2-2 2-2-.89-2-2 .9-2 2-2zm0 13.5c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"></path>
<circle cx="14" cy="12.5" r="2.5"></circle>
@@ -71,11 +73,11 @@
<path d="M19,7H9C7.9,7,7,7.9,7,9v10c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V9C21,7.9,20.1,7,19,7z M19,9v2H9V9H19z M13,15v-2h2v2H13z M15,17v2h-2v-2H15z M11,15H9v-2h2V15z M17,13h2v2h-2V13z M9,17h2v2H9V17z M17,19v-2h2v2H17z M6,17H5c-1.1,0-2-0.9-2-2V5 c0-1.1,0.9-2,2-2h10c1.1,0,2,0.9,2,2v1h-2V5H5v10h1V17z"></path>
</g>
</svg>&nbsp; &nbsp;Log</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="usermanagement" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="usermanagement" href="#"><svg class="me-2 icon-menu pad-icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"></path>
</svg>&nbsp;User Management</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="filemanagement" href="#"><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="filemanagement" href="#"><svg class="me-2 icon-menu pad-icon-menu" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<g>
<rect fill="none" height="24" width="24"></rect>
</g>
@@ -83,13 +85,13 @@
<path d="M14,2H6C4.9,2,4.01,2.9,4.01,4L4,20c0,1.1,0.89,2,1.99,2H18c1.1,0,2-0.9,2-2V8L14,2z M16,13h-3v3.75 c0,1.24-1.01,2.25-2.25,2.25S8.5,17.99,8.5,16.75c0-1.24,1.01-2.25,2.25-2.25c0.46,0,0.89,0.14,1.25,0.38V11h4V13z M13,9V3.5 L18.5,9H13z"></path>
</g>
</svg>&nbsp;File Management</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="settinglink" href="#"><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="settinglink" href="#"><svg class="me-2 icon-menu pad-icon-menu" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<g>
<path d="M0,0h24v24H0V0z" fill="none"></path>
<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"></path>
</g>
</svg>&nbsp;Setting</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="logoutlink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="logoutlink" href="#"><svg class="me-2 icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"></path>
</svg>&nbsp;Logout</a></li>
@@ -160,9 +162,11 @@
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/jquery-3.7.1.min.js"></script>
<script src="assets/js/select2.min.js"></script>
<script src="assets/js/litepicker.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/all.min.js"></script>
<script src="assets/js/script.js"></script>
<script src="assets/js/flatpickr.js"></script>
</body>
</html>

View File

@@ -16,6 +16,8 @@
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/all.min.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/flatpickr.min.css">
<link rel="stylesheet" href="assets/css/litepicker.css">
<link rel="stylesheet" href="assets/css/select2.min.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
@@ -40,7 +42,7 @@
<div>
<hr class="mt-0">
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item"><a class="nav-link active link-light text-menu" id="homelink" href="#" aria-current="page"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-house-door me-2" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link active link-light text-menu" id="homelink" href="#" aria-current="page"><svg class="bi bi-house-door me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 20px;">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4z"></path>
</svg>&nbsp;Overview</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="loglink" href="#"><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="icon-menu pad-icon-menu" style="font-size: 20px;">
@@ -49,7 +51,7 @@
<path d="M19,7H9C7.9,7,7,7.9,7,9v10c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V9C21,7.9,20.1,7,19,7z M19,9v2H9V9H19z M13,15v-2h2v2H13z M15,17v2h-2v-2H15z M11,15H9v-2h2V15z M17,13h2v2h-2V13z M9,17h2v2H9V17z M17,19v-2h2v2H17z M6,17H5c-1.1,0-2-0.9-2-2V5 c0-1.1,0.9-2,2-2h10c1.1,0,2,0.9,2,2v1h-2V5H5v10h1V17z"></path>
</g>
</svg>&nbsp; &nbsp;Log</a></li>
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="logoutlink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="logoutlink" href="#"><svg class="me-2 icon-menu" xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" style="font-size: 20px;">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"></path>
</svg>&nbsp;Logout</a></li>
@@ -120,9 +122,11 @@
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/jquery-3.7.1.min.js"></script>
<script src="assets/js/select2.min.js"></script>
<script src="assets/js/litepicker.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/all.min.js"></script>
<script src="assets/js/script.js"></script>
<script src="assets/js/flatpickr.js"></script>
</body>
</html>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -99,7 +98,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/languagelink.js"></script>
</body>

View File

@@ -14,8 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/litepicker.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -71,8 +69,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/litepicker.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/log.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -27,7 +26,7 @@
<div class="col-md-6 col-xl-4">
<div class="card mb-5 card-login">
<div class="card-body d-flex flex-column align-items-center">
<div class="bs-icon-xl bs-icon-circle bs-icon-primary my-4 bs-icon bg-icon-login"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-person bg-icon-login">
<div class="bs-icon-xl bs-icon-circle bs-icon-primary my-4 bs-icon bg-icon-login"><svg class="bi bi-person bg-icon-login" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664z"></path>
</svg></div>
<h2 class="mb-3 h-login">Login</h2>
@@ -46,8 +45,6 @@
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/jquery-3.7.1.min.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/login.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -114,16 +113,13 @@
<div class="row">
<div class="col bg-light"><select class="w-100 h-100 overflow-scroll" id="messageavailablevariables" size="10"></select></div>
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2">
<div class="row pad-row-btn"><button class="btn btn-round-basic color-remove" data-bs-toggle="tooltip" data-bss-tooltip="" id="btnclearlist" type="button" title="Clear List"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;">
<!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<div class="row pad-row-btn"><button class="btn btn-round-basic color-remove" data-bs-toggle="tooltip" data-bss-tooltip="" id="btnclearlist" type="button" title="Clear List"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<path d="M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z"></path>
</svg></button></div>
<div class="row pad-row-btn"><button class="btn btn-round-basic color-edit" data-bs-toggle="tooltip" data-bss-tooltip="" data-bs-placement="right" id="btnremovefromlist" type="button" title="Remove"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;">
<!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<div class="row pad-row-btn"><button class="btn btn-round-basic color-edit" data-bs-toggle="tooltip" data-bss-tooltip="" data-bs-placement="right" id="btnremovefromlist" type="button" title="Remove"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<path d="M48 256a208 208 0 1 1 416 0A208 208 0 1 1 48 256zm464 0A256 256 0 1 0 0 256a256 256 0 1 0 512 0zM217.4 376.9c4.2 4.5 10.1 7.1 16.3 7.1c12.3 0 22.3-10 22.3-22.3V304h96c17.7 0 32-14.3 32-32V240c0-17.7-14.3-32-32-32H256V150.3c0-12.3-10-22.3-22.3-22.3c-6.2 0-12.1 2.6-16.3 7.1L117.5 242.2c-3.5 3.8-5.5 8.7-5.5 13.8s2 10.1 5.5 13.8l99.9 107.1z"></path>
</svg></button></div>
<div class="row pad-row-btn"><button class="btn btn-round-basic color-import" data-bs-toggle="tooltip" data-bss-tooltip="" data-bs-placement="right" id="btnaddtolist" type="button" title="Add"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;">
<!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<div class="row pad-row-btn"><button class="btn btn-round-basic color-import" data-bs-toggle="tooltip" data-bss-tooltip="" data-bs-placement="right" id="btnaddtolist" type="button" title="Add"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em" height="1em" fill="currentColor" style="font-size: 32;"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<path d="M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM294.6 135.1c-4.2-4.5-10.1-7.1-16.3-7.1C266 128 256 138 256 150.3V208H160c-17.7 0-32 14.3-32 32v32c0 17.7 14.3 32 32 32h96v57.7c0 12.3 10 22.3 22.3 22.3c6.2 0 12.1-2.6 16.3-7.1l99.9-107.1c3.5-3.8 5.5-8.7 5.5-13.8s-2-10.1-5.5-13.8L294.6 135.1z"></path>
</svg></button></div>
</div>
@@ -136,7 +132,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/messagebank.js"></script>
</body>

View File

@@ -15,7 +15,6 @@
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/fonts/font-awesome.min.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -4684,7 +4683,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/overview.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -123,9 +122,76 @@
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="card">
<div class="card-body">
<h4 class="card-title">Adzan Setting</h4>
<hr>
<div class="row">
<div class="col">
<div class="container">
<div class="row py-1">
<div class="col-auto"><label class="col-form-label">Latitude</label></div>
<div class="col-2"><input class="w-100 h-100" type="text" id="adzanlatitude"></div>
<div class="col-auto"><label class="col-form-label">Longitude</label></div>
<div class="col-2"><input class="w-100 h-100" type="text" id="adzanlongitude"></div>
<div class="col-auto"><label class="col-form-label">TimeZone</label></div>
<div class="col"><input class="w-100 h-100" type="text" id="adzantimezone"></div>
</div>
<div class="row">
<p class="py-1" id="adzantoday">Today's Adzan</p>
</div>
<div class="row py-1" id="fajar">
<div class="col-2"><label class="col-form-label w-100 h-100 align-content-center">Fajar</label></div>
<div class="col-2"><input class="w-100 h-100 align-content-center adzantime" id="fajar_time" type="time"></div>
<div class="col d-flex"><input class="flex-grow-1 me-1 adzanfile" type="text"><button class="btn btn-primary col-auto adzanbrowse" type="button">Browse</button></div>
<div class="col-2">
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input adzanenable" type="checkbox" id="enable_fajr"><label class="form-check-label" for="enable_fajr">Enable</label></div>
</div>
</div>
<div class="row py-1" id="dzuhur">
<div class="col-2"><label class="col-form-label w-100 h-100 align-content-center">Dzuhur</label></div>
<div class="col-2"><input class="w-100 h-100 align-content-center adzantime" id="fajar_time-4" type="time"></div>
<div class="col d-flex"><input class="flex-grow-1 me-1 adzanfile" type="text"><button class="btn btn-primary col-auto adzanbrowse" type="button">Browse</button></div>
<div class="col-2">
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input adzanenable" type="checkbox" id="enable_fajr-4"><label class="form-check-label" for="enable_fajr-4">Enable</label></div>
</div>
</div>
<div class="row py-1" id="ashar">
<div class="col-2"><label class="col-form-label w-100 h-100 align-content-center">Ashar</label></div>
<div class="col-2"><input class="w-100 h-100 align-content-center adzantime" id="fajar_time-3" type="time"></div>
<div class="col d-flex"><input class="flex-grow-1 me-1 adzanfile" type="text"><button class="btn btn-primary col-auto adzanbrowse" type="button">Browse</button></div>
<div class="col-2">
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input adzanenable" type="checkbox" id="enable_fajr-3"><label class="form-check-label" for="enable_fajr-3">Enable</label></div>
</div>
</div>
<div class="row py-1" id="magrib">
<div class="col-2"><label class="col-form-label w-100 h-100 align-content-center">Magrib</label></div>
<div class="col-2"><input class="w-100 h-100 align-content-center adzantime" id="fajar_time-2" type="time"></div>
<div class="col d-flex"><input class="flex-grow-1 me-1 adzanfile" type="text"><button class="btn btn-primary col-auto adzanbrowse" type="button">Browse</button></div>
<div class="col-2">
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input adzanenable" type="checkbox" id="enable_fajr-2"><label class="form-check-label" for="enable_fajr-2">Enable</label></div>
</div>
</div>
<div class="row py-1" id="isya">
<div class="col-2"><label class="col-form-label w-100 h-100 align-content-center">Isya</label></div>
<div class="col-2"><input class="w-100 h-100 align-content-center adzantime" id="fajar_time-1" type="time"></div>
<div class="col d-flex"><input class="flex-grow-1 me-1 adzanfile" type="text"><button class="btn btn-primary col-auto adzanbrowse" type="button">Browse</button></div>
<div class="col-2">
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input adzanenable" type="checkbox" id="enable_fajr-1"><label class="form-check-label" for="enable_fajr-1">Enable</label></div>
</div>
</div>
</div>
</div>
<div class="col-4 col-sm-3 col-md-2 col-lg-2 col-xl-2"><button class="btn w-100 h-100 pad-button btn-round-basic color-add" id="adzansave" type="button">Save</button></div>
</div>
</div>
</div>
</div>
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/setting.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -120,7 +119,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/soundbank.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -91,7 +90,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
</body>
</html>

View File

@@ -14,8 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/litepicker.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -80,13 +78,8 @@
</div>
<div class="col">
<div class="row w-100 h-100">
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4"><input type="number" id="schedulehour" class="input-add form-control class100" value="0" min="0" max="23" step="1"></div>
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2">
<p class="pad-time">(H)</p>
</div>
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4"><input class="w-100 input-add form-control" type="number" id="scheduleminute" value="0" min="0" max="59" step="1"></div>
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2">
<p class="pad-time">(M)</p>
<div class="row w-100 pad-day">
<div class="col w-100"><input type="text" id="scheduletime" placeholder="HH:mm"></div>
</div>
</div>
</div>
@@ -213,8 +206,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/litepicker.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/schedulebank.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -124,7 +123,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/tts.js"></script>
</body>

View File

@@ -14,7 +14,6 @@
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/bss-overrides.css">
<link rel="stylesheet" href="assets/css/datatables.css">
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
@@ -238,7 +237,6 @@
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script>
<script src="assets/js/datatables.js"></script>
<script src="assets/js/usermanagement.js"></script>
</body>