Added new DateTime field

This commit is contained in:
Djamil Legato
2016-02-05 23:49:39 -08:00
parent 8b494f5842
commit 6271eeddff
12 changed files with 570 additions and 261 deletions

View File

@@ -895,20 +895,20 @@ class Admin
* @param string $php_format
* @return string
*/
function dateformat2Kendo($php_format)
function dateformatToMomentJS($php_format)
{
$SYMBOLS_MATCHING = array(
// Day
'd' => 'dd',
'd' => 'DD',
'D' => 'ddd',
'j' => 'd',
'j' => 'D',
'l' => 'dddd',
'N' => '',
'S' => '',
'w' => '',
'z' => '',
'N' => 'E',
'S' => 'Do',
'w' => 'd',
'z' => 'DDD',
// Week
'W' => '',
'W' => 'W',
// Month
'F' => 'MMMM',
'm' => 'MM',
@@ -917,20 +917,31 @@ class Admin
't' => '',
// Year
'L' => '',
'o' => '',
'Y' => 'yyyy',
'o' => 'GGGG',
'Y' => 'YYYY',
'y' => 'yy',
// Time
'a' => 'tt',
'A' => 'tt',
'B' => '',
'a' => 'a',
'A' => 'A',
'B' => 'SSS',
'g' => 'h',
'G' => 'H',
'h' => 'hh',
'H' => 'HH',
'i' => 'mm',
's' => 'ss',
'u' => ''
'u' => '',
// Timezone
'e' => '',
'I' => '',
'O' => 'ZZ',
'P' => 'Z',
'T' => 'z',
'Z' => '',
// Full Date/Time
'c' => '',
'r' => 'llll ZZ',
'U' => 'X'
);
$js_format = "";
$escaping = false;

View File

@@ -0,0 +1,62 @@
import $ from 'jquery';
import { config } from 'grav-config';
import 'eonasdan-bootstrap-datetimepicker';
export default class DateTimeField {
get defaults() {
return {
showTodayButton: true,
showClear: true,
locale: config.language || 'en',
icons: {
time: 'fa fa-clock-o',
date: 'fa fa-calendar-o',
up: 'fa fa-chevron-up',
down: 'fa fa-chevron-down',
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-bullseye',
clear: 'fa fa-trash-o',
close: 'fa fa-remove'
}
};
}
constructor(options) {
this.items = $();
this.options = Object.assign({}, this.defaults, options);
$('[data-grav-datetime]').each((index, field) => this.addItem(field));
$('body').on('mutation._grav', this._onAddedNodes.bind(this));
}
addItem(list) {
list = $(list);
this.items = this.items.add(list);
if (list.data('DateTimePicker')) { return; }
let options = Object.assign({}, this.options, list.data('grav-datetime') || {});
list.datetimepicker(options).on('dp.show dp.update', this._disableDecades);
}
_onAddedNodes(event, target/* , record, instance */) {
let fields = $(target).find('[data-grav-datetime]');
if (!fields.length) { return; }
fields.each((index, field) => {
field = $(field);
if (!~this.items.index(field)) {
this.addItem(field);
}
});
}
_disableDecades() {
$('.datepicker-years .picker-switch').removeAttr('title').on('click', (e) => e.stopPropagation());
}
}
export let Instance = new DateTimeField();

View File

@@ -1,6 +1,7 @@
import SelectizeField, { Instance as SelectizeFieldInstance } from './selectize';
import ArrayField, { Instance as ArrayFieldInstance } from './array';
import CollectionsField, { Instance as CollectionsFieldInstance } from './collections';
import DateTimeField, { Instance as DateTimeFieldInstance } from './datetime';
export default {
SelectizeField: {
@@ -14,5 +15,9 @@ export default {
CollectionsField: {
CollectionsField,
Instance: CollectionsFieldInstance
},
DateTimeField: {
DateTimeField,
Instance: DateTimeFieldInstance
}
};

View File

@@ -8,7 +8,9 @@ import './plugins';
import './themes';
// bootstrap jQuery extensions
import 'bootstrap/js/transition';
import 'bootstrap/js/dropdown';
import 'bootstrap/js/collapse';
// starts the keep alive, auto runs every X seconds
KeepAlive.start();

View File

@@ -180,205 +180,3 @@ export default class PageMedia {
export let Instance = new PageMedia();
// let container = $('[data-media-url]');
// if (container.length) {
/* let URI = container.data('media-url');
let dropzone = new Dropzone('#grav-dropzone', {
url: `${URI}/task${config.param_sep}addmedia`,
createImageThumbnails: { thumbnailWidth: 150 },
addRemoveLinks: false,
dictRemoveFileConfirmation: '[placeholder]',
acceptedFiles: container.data('media-types'),
previewTemplate: `
<div class="dz-preview dz-file-preview">
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size" data-dz-size></div>
<img data-dz-thumbnail />
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-success-mark"><span>✔</span></div>
<div class="dz-error-mark"><span>✘</span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<a class="dz-remove" href="javascript:undefined;" data-dz-remove>Delete</a>
<a class="dz-insert" href="javascript:undefined;" data-dz-insert>Insert</a>
</div>`
});*/
/* $.get(URI + '/task{{ config.system.param_sep }}listmedia/admin-nonce{{ config.system.param_sep }}' + GravAdmin.config.admin_nonce, function(data) {
$.proxy(modalError, this, {
data: data,
msg: '<p>An error occurred while trying to list files</p><pre>'+data.message+'</pre>'
})();
if (data.results) {
$.each(data.results, function(filename, data){
var mockFile = { name: filename, size: data.size, accepted: true, extras: data };
thisDropzone.files.push(mockFile);
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
if (filename.toLowerCase().match(/\.(jpg|jpeg|png|gif)$/)) {
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, data.url);
}
});
}
$('.dz-preview').prop('draggable', 'true');
});*/
// console.log(dropzone);
// }
/*
<script>
$(function(){
var URI = $('[data-media-url]').data('media-url'), thisDropzone,
modalError = function(args){
if (args.data.status == 'error' || args.data.status == 'unauthorized'){
if (args.mode == 'addBack'){
// let's add back the file
if (args.file instanceof File) this.addFile(args.file);
else {
this.files.push(args.file);
this.options.addedfile.call(this, args.file);
this.options.thumbnail.call(this, args.file, args.file.extras.url);
}
} else if (args.mode == 'removeFile') {
args.file.rejected = true;
this.removeFile(args.file);
}
// fire up the modal
var modalContainer = $('[data-remodal-id=generic]');
modalContainer.find('.error-content').html(args.msg);
$.remodal.lookup[modalContainer.data('remodal')].open();
}
};
Dropzone.autoDiscover = false;
Dropzone.confirm = function(question, accepted, rejected) {
var modalContainer = $('[data-remodal-id=delete-media]'),
acceptHandler = function () {
if (accepted) {
accepted();
}
$(document).off('confirm', '[data-remodal-id=delete-media]', acceptHandler);
$(document).off('cancel', '[data-remodal-id=delete-media]', rejectHandler);
},
rejectHandler = function () {
if (rejected) {
rejected();
}
$(document).off('confirm', '[data-remodal-id=delete-media]', acceptHandler);
$(document).off('cancel', '[data-remodal-id=delete-media]', rejectHandler);
};
$.remodal.lookup[modalContainer.data('remodal')].open();
$(document).on('confirm', '[data-remodal-id=delete-media]', acceptHandler);
$(document).on('cancel', '[data-remodal-id=delete-media]', rejectHandler);
};
Dropzone.options.gravDropzone = {
addRemoveLinks: false,
dictRemoveFileConfirmation: '[placeholder]',
acceptedFiles: $('[data-media-types]').data('media-types'),
previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n " +
"<div class=\"dz-filename\"><span data-dz-name></span></div>\n " +
"<div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n " +
"<div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n "+
"<div class=\"dz-success-mark\"><span>✔</span></div>\n <div class=\"dz-error-mark\"><span>✘</span></div>\n " +
"<div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n" +
"<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>Delete</a>\n" +
"<a class=\"dz-insert\" href=\"javascript:undefined;\" data-dz-insert>Insert</a>\n</div>",
init: function() {
thisDropzone = this;
$.get(URI + '/task{{ config.system.param_sep }}listmedia/admin-nonce{{ config.system.param_sep }}' + GravAdmin.config.admin_nonce, function(data) {
$.proxy(modalError, this, {
data: data,
msg: '<p>An error occurred while trying to list files</p><pre>'+data.message+'</pre>'
})();
if (data.results) {
$.each(data.results, function(filename, data){
var mockFile = { name: filename, size: data.size, accepted: true, extras: data };
thisDropzone.files.push(mockFile);
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
if (filename.toLowerCase().match(/\.(jpg|jpeg|png|gif)$/)) {
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, data.url);
}
});
}
$('.dz-preview').prop('draggable', 'true');
});
this.on("complete", function(file) {
if (file.accepted) {
$('.dz-preview').prop('draggable', 'true');
return;
}
var data = {status: 'error', message: 'Unsupported file type: ' + file.name.match(/\..+/).join('')};
$.proxy(modalError, this, {
file: file,
data: data,
mode: 'removeFile',
msg: '<p>An error occurred while trying to add the file <strong>'+file.name+'</strong></p><pre>'+data.message+'</pre>'
})();
});
this.on('success', function(file, response){
thisDropzone = this;
$.proxy(modalError, this, {
file: file,
data: response,
mode: 'removeFile',
msg: '<p>An error occurred while trying to upload the file <strong>'+file.name+'</strong></p><pre>'+response.message+'</pre>'
})();
});
this.on('removedfile', function(file) {
if (!file.accepted || file.rejected) return;
thisDropzone = this;
$.post(URI + '/task{{ config.system.param_sep }}delmedia', {filename: file.name, 'admin-nonce': GravAdmin.config.admin_nonce}, function(data){
$.proxy(modalError, thisDropzone, {
file: file,
data: data,
mode: 'addBack',
msg: '<p>An error occurred while trying to remove the file <strong>'+file.name+'</strong></p><pre>'+data.message+'</pre>'
})();
});
});
this.on('sending', function(file, xhr, formData){
formData.append('admin-nonce', GravAdmin.config.admin_nonce);
});
}
};
var dropzone = new Dropzone("#gravDropzone", { url: URI + '/task{{ config.system.param_sep }}addmedia', createImageThumbnails: { thumbnailWidth: 150} });
$("#gravDropzone").delegate('.dz-preview', 'dragstart', function(e){
var uri = encodeURI($(this).find('.dz-filename').text());
uri = uri.replace(/\(/g, '%28');
uri = uri.replace(/\)/g, '%29');
var shortcode = '![](' + uri + ')';
if (!uri.match(/\.(jpg|jpeg|png|gif)$/)) {
shortcode = '[' + decodeURI(uri) + '](' + uri + ')';
}
dropzone.disable();
$(this).addClass('hide-backface');
e.originalEvent.dataTransfer.effectAllowed = 'copy';
e.originalEvent.dataTransfer.setData('text', shortcode);
});
$("#gravDropzone").delegate('.dz-preview', 'dragend', function(e){
dropzone.enable();
$(this).removeClass('hide-backface');
});
});
</script>*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,28 +1,3 @@
// fieldset {
// border: 1px solid $core-border-color;
// }
// textarea, #{$all-text-inputs}, select[multiple=multiple] {
// background-color: white;
// border: 1px solid $core-border-color;
// box-shadow: $core-box-shadow;
// &:hover {
// border-color: $core-border-color-hover;
// }
// &:focus {
// border-color: $core-border-color-focus;
// box-shadow: $core-box-shadow-focus;
// }
// }
// label {
// @extend strong;
// }
// Forms
$form-label-width: 30%;
$form-border: darken($content-bg,10%);
@@ -34,6 +9,7 @@ $form-select-pad: 5px 30px 5px 10px;
// Load Third Party Libraries
@import "template/modules/toggle-switch";
@import "template/modules/datetimepicker";
form {

View File

@@ -0,0 +1,451 @@
.collapse {
display: none;
&.in {
display: block;
}
tr &.in {
display: table-row;
}
tbody &.in {
display: table-row-group;
}
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
@include transition(height .35s ease, visibility .35s ease);
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
/* Bootstrap variables styling */
.bootstrap-datetimepicker-widget {
&.dropdown-menu {
position: absolute;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}
.list-unstyled {
padding-left: 0;
list-style: none;
}
.collapse {
display: none;
visibility: hidden;
&.in {
display: block;
visibility: visible;
}
}
.datepicker-years .picker-switch {
cursor: default !important;
background: inherit !important;
}
.table-condensed > thead > tr > th {
padding: 5px;
}
table {
display: table;
thead {
display: table-header-group;
}
tbody {
display: table-row-group;
}
tr {
display: table-row;
&:hover {
background: inherit;
}
th, td {
border: 0;
display: table-cell;
&:first-child {
padding-left: inherit;
}
&:last-child {
padding-right: inherit;
}
}
}
}
}
/*!
* Datetimepicker for Bootstrap 3
* ! version : 4.7.14
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
$bs-datetimepicker-timepicker-font-size: 1.2em !default;
$bs-datetimepicker-active-bg: $accent-bg !default;
$bs-datetimepicker-active-color: $accent-fg !default;
$bs-datetimepicker-border-radius: 3px !default;
$bs-datetimepicker-btn-hover-bg: #ddd !default;
$bs-datetimepicker-disabled-color: #ccc !default;
$bs-datetimepicker-alternate-color: #ccc !default;
$bs-datetimepicker-secondary-border-color: #ccc !default;
$bs-datetimepicker-secondary-border-color-rgba: rgba(0, 0, 0, 0.2) !default;
$bs-datetimepicker-primary-border-color: white !default;
$bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25) !default;
.bootstrap-datetimepicker-widget {
list-style: none;
&.dropdown-menu {
margin: 2px 0;
padding: 4px;
width: 19em;
&.timepicker-sbs {
@media (min-width: 768px) {
width: 38em;
}
@media (min-width: 992px) {
width: 38em;
}
@media (min-width: 1200px) {
width: 38em;
}
}
&:before, &:after {
content: '';
display: inline-block;
position: absolute;
}
&.bottom {
&:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid $bs-datetimepicker-secondary-border-color;
border-bottom-color: $bs-datetimepicker-secondary-border-color-rgba;
top: -7px;
left: 7px;
}
&:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $bs-datetimepicker-primary-border-color;
top: -6px;
left: 8px;
}
}
&.top {
&:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid $bs-datetimepicker-secondary-border-color;
border-top-color: $bs-datetimepicker-secondary-border-color-rgba;
bottom: -7px;
left: 6px;
}
&:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid $bs-datetimepicker-primary-border-color;
bottom: -6px;
left: 7px;
}
}
&.pull-right {
&:before {
left: auto;
right: 6px;
}
&:after {
left: auto;
right: 7px;
}
}
}
.list-unstyled {
margin: 0;
}
a[data-action] {
padding: 6px 0;
}
a[data-action]:active {
box-shadow: none;
}
.timepicker-hour, .timepicker-minute, .timepicker-second {
width: 54px;
font-weight: bold;
font-size: $bs-datetimepicker-timepicker-font-size;
margin: 0;
}
button[data-action] {
padding: 6px;
}
.btn[data-action="incrementHours"]::after {
@extend .sr-only;
content: "Increment Hours";
}
.btn[data-action="incrementMinutes"]::after {
@extend .sr-only;
content: "Increment Minutes";
}
.btn[data-action="decrementHours"]::after {
@extend .sr-only;
content: "Decrement Hours";
}
.btn[data-action="decrementMinutes"]::after {
@extend .sr-only;
content: "Decrement Minutes";
}
.btn[data-action="showHours"]::after {
@extend .sr-only;
content: "Show Hours";
}
.btn[data-action="showMinutes"]::after {
@extend .sr-only;
content: "Show Minutes";
}
.btn[data-action="togglePeriod"]::after {
@extend .sr-only;
content: "Toggle AM/PM";
}
.btn[data-action="clear"]::after {
@extend .sr-only;
content: "Clear the picker";
}
.btn[data-action="today"]::after {
@extend .sr-only;
content: "Set the date to today";
}
.picker-switch {
text-align: center;
&::after {
@extend .sr-only;
content: "Toggle Date and Time Screens";
}
td {
padding: 0;
margin: 0;
height: auto;
width: auto;
line-height: inherit;
span {
line-height: 2.5;
height: 2.5em;
width: 100%;
}
}
}
table {
width: 100%;
margin: 0;
& td,
& th {
text-align: center;
border-radius: $bs-datetimepicker-border-radius;
}
& th {
height: 29px;
line-height: 29px;
width: 29px;
&.picker-switch {
width: 145px;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
&.prev::after {
@extend .sr-only;
content: "Previous Month";
}
&.next::after {
@extend .sr-only;
content: "Next Month";
}
}
& thead tr:first-child th {
cursor: pointer;
&:hover {
background: $bs-datetimepicker-btn-hover-bg;
}
}
& td {
height: 54px;
line-height: 54px;
width: 54px;
&.cw {
font-size: .8em;
height: 20px;
line-height: 20px;
color: $bs-datetimepicker-alternate-color;
}
&.day {
height: 29px;
line-height: 29px;
width: 29px;
}
&.day:hover,
&.hour:hover,
&.minute:hover,
&.second:hover {
background: $bs-datetimepicker-btn-hover-bg;
cursor: pointer;
}
&.old,
&.new {
color: $bs-datetimepicker-alternate-color;
}
&.today {
position: relative;
&:before {
content: '';
display: inline-block;
border: 0 0 7px 7px solid transparent;
border-bottom-color: $bs-datetimepicker-active-bg;
border-top-color: $bs-datetimepicker-secondary-border-color-rgba;
position: absolute;
bottom: 4px;
right: 4px;
}
}
&.active,
&.active:hover {
background-color: $bs-datetimepicker-active-bg;
color: $bs-datetimepicker-active-color;
text-shadow: $bs-datetimepicker-text-shadow;
}
&.active.today:before {
border-bottom-color: #fff;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
span {
display: inline-block;
width: 54px;
height: 54px;
line-height: 54px;
margin: 2px 1.5px;
cursor: pointer;
border-radius: $bs-datetimepicker-border-radius;
&:hover {
background: $bs-datetimepicker-btn-hover-bg;
}
&.active {
background-color: $bs-datetimepicker-active-bg;
color: $bs-datetimepicker-active-color;
text-shadow: $bs-datetimepicker-text-shadow;
}
&.old {
color: $bs-datetimepicker-alternate-color;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
}
}
}
&.usetwentyfour {
td.hour {
height: 27px;
line-height: 27px;
}
}
}
.input-group.date {
& .input-group-addon {
cursor: pointer;
}
}

View File

@@ -6,6 +6,7 @@
enable_auto_updates_check: '{{ config.plugins.admin.enable_auto_updates_check }}',
admin_timeout: '{{ config.plugins.admin.session.timeout ?: 1800 }}',
admin_nonce: '{{ admin.getNonce }}',
language: '{{ grav.user.language|default('en') }}',
pro_enabled: '{{ config.plugins["admin-pro"].enabled }}'
};
window.GravAdmin.uri_params = {};