Added new datetime form field

This commit is contained in:
Lucas Bartholemy 2014-07-03 09:49:50 +02:00
parent e59b46b3a2
commit eff3b7125a
7 changed files with 4029 additions and 3 deletions

204
css/bootstrap-datetimepicker.css vendored Normal file
View File

@ -0,0 +1,204 @@
/*!
* Datetimepicker for Bootstrap v3
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
.bootstrap-datetimepicker-widget {
top: 0;
left: 0;
width: 250px;
padding: 4px;
margin-top: 1px;
z-index: 99999 !important;
border-radius: 4px;
}
.bootstrap-datetimepicker-widget.timepicker-sbs {
width: 600px;
}
.bootstrap-datetimepicker-widget.bottom:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 7px;
}
.bootstrap-datetimepicker-widget.bottom:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid white;
position: absolute;
top: -6px;
left: 8px;
}
.bootstrap-datetimepicker-widget.top:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #ccc;
border-top-color: rgba(0, 0, 0, 0.2);
position: absolute;
bottom: -7px;
left: 6px;
}
.bootstrap-datetimepicker-widget.top:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid white;
position: absolute;
bottom: -6px;
left: 7px;
}
.bootstrap-datetimepicker-widget .dow {
width: 14.2857%;
}
.bootstrap-datetimepicker-widget.pull-right:before {
left: auto;
right: 6px;
}
.bootstrap-datetimepicker-widget.pull-right:after {
left: auto;
right: 7px;
}
.bootstrap-datetimepicker-widget > ul {
list-style-type: none;
margin: 0;
}
.bootstrap-datetimepicker-widget .timepicker-hour,
.bootstrap-datetimepicker-widget .timepicker-minute,
.bootstrap-datetimepicker-widget .timepicker-second {
width: 100%;
font-weight: bold;
font-size: 1.2em;
}
.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator {
width: 4px;
padding: 0;
margin: 0;
}
.bootstrap-datetimepicker-widget .datepicker > div {
display: none;
}
.bootstrap-datetimepicker-widget .picker-switch {
text-align: center;
}
.bootstrap-datetimepicker-widget table {
width: 100%;
margin: 0;
}
.bootstrap-datetimepicker-widget td,
.bootstrap-datetimepicker-widget th {
text-align: center;
width: 20px;
height: 20px;
border-radius: 4px;
}
.bootstrap-datetimepicker-widget td.day:hover,
.bootstrap-datetimepicker-widget td.hour:hover,
.bootstrap-datetimepicker-widget td.minute:hover,
.bootstrap-datetimepicker-widget td.second:hover {
background: #eeeeee;
cursor: pointer;
}
.bootstrap-datetimepicker-widget td.old,
.bootstrap-datetimepicker-widget td.new {
color: #999999;
}
.bootstrap-datetimepicker-widget td.today {
position: relative;
}
.bootstrap-datetimepicker-widget td.today:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-bottom: 7px solid #428bca;
border-top-color: rgba(0, 0, 0, 0.2);
position: absolute;
bottom: 4px;
right: 4px;
}
.bootstrap-datetimepicker-widget td.active,
.bootstrap-datetimepicker-widget td.active:hover {
background-color: #428bca;
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.bootstrap-datetimepicker-widget td.active.today:before {
border-bottom-color: #fff;
}
.bootstrap-datetimepicker-widget td.disabled,
.bootstrap-datetimepicker-widget td.disabled:hover {
background: none;
color: #999999;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget td span {
display: block;
width: 47px;
height: 54px;
line-height: 54px;
float: left;
margin: 2px;
cursor: pointer;
border-radius: 4px;
}
.bootstrap-datetimepicker-widget td span:hover {
background: #eeeeee;
}
.bootstrap-datetimepicker-widget td span.active {
background-color: #428bca;
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.bootstrap-datetimepicker-widget td span.old {
color: #999999;
}
.bootstrap-datetimepicker-widget td span.disabled,
.bootstrap-datetimepicker-widget td span.disabled:hover {
background: none;
color: #999999;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget th.switch {
width: 145px;
}
.bootstrap-datetimepicker-widget th.next,
.bootstrap-datetimepicker-widget th.prev {
font-size: 21px;
}
.bootstrap-datetimepicker-widget th.disabled,
.bootstrap-datetimepicker-widget th.disabled:hover {
background: none;
color: #999999;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget thead tr:first-child th {
cursor: pointer;
}
.bootstrap-datetimepicker-widget thead tr:first-child th:hover {
background: #eeeeee;
}
.input-group.date .input-group-addon span {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.bootstrap-datetimepicker-widget.left-oriented:before {
left: auto;
right: 6px;
}
.bootstrap-datetimepicker-widget.left-oriented:after {
left: auto;
right: 7px;
}
.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td {
padding: 0px !important;
}

1166
js/bootstrap-datetimepicker.js vendored Normal file

File diff suppressed because it is too large Load Diff

78
js/datetimefield-init.js Normal file
View File

@ -0,0 +1,78 @@
$(document).ready(function() {
var createDefaultDateValue = function(date, time) {
console.log(time);
var d = new Date()
, datePart = date || ((1900 + d.getYear()) + '-' + (1 + d.getMonth()) + '-' + d.getDate())
, timePart = time || (d.getHours() + ':' + d.getMinutes())
;
return datePart + ' ' + timePart;
};
$('.hhtml-datetime-field').each(function(index, element) {
var $element = $(element)
, defaultDate = $element.val() || createDefaultDateValue($element.attr('data-options-defaultdate'), $element.attr('data-options-defaulttime'))
, $dateInput = $('<input value="' + defaultDate + '" type="text" class="' + $element.attr('class') + '" />')
, dateTimepickerDefaultOptions = {
pickDate: true,
pickTime: false,
useMinutes: true,
useSeconds: false,
showToday: true,
language: 'en',
use24hours: true,
sideBySide: false,
format: 'YYYY-MM-DD hh:mm'
}
, dateTimepickerOptions = {}
, re_dataAttr = /^data\-options\-(.+)$/
;
$.each(element.attributes, function(index, attr) {
if (re_dataAttr.test(attr.nodeName)) {
var key = attr.nodeName.match(re_dataAttr)[1]
, nodeValue = attr.nodeValue
;
nodeValue = nodeValue === 'true' ? true : nodeValue;
nodevalue = nodeValue === 'false' ? false : nodeValue;
dateTimepickerOptions[key] = nodeValue;
}
});
if ($element.attr('data-options-pickTime') == "true") {
dateTimepickerOptions.pickTime = true;
}
dateTimepickerOptions = $.extend({}, dateTimepickerDefaultOptions, dateTimepickerOptions);
$dateInput.datetimepicker(dateTimepickerOptions);
var datepicker = $dateInput.data("DateTimePicker");
if (typeof $element.attr('data-options-displayFormat') === "undefined") {
if (!dateTimepickerOptions.pickTime) {
datepicker.format = "DD.MM.YYYY";
} else {
datepicker.format = "DD.MM.YYYY - HH:mm";
}
} else {
datepicker.format = $element.attr('data-options-displayFormat');
}
datepicker.setDate(datepicker.date); // update visible date to correct Format
$dateInput.bind('blur change', function(ev) {
if (datepicker.getDate()) {
$element.val(datepicker.getDate().format('YYYY-MM-DD HH:mm:00'));
}
});
$element
.hide()
.after($dateInput)
;
$dateInput.trigger('change');
});
});

2400
js/moment.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*/
/**
* Extends CActiveFrom with extra field types
*
* @package humhub.components
* @author Andi
* @since 0.6.3
*/
class HActiveForm extends CActiveForm
{
/**
* Renders a datetime field for a model attribute.
*
* Utilizes bootstrap-datetimepicker.js
* @param CModel $model the data model
* @param string $attribute the attribute
* @param array $htmlOptions additional HTML attributes.
* @param array $fieldOptions additional picker attributes. (see HHTML::activeDateTimeField)
*
* @return string the generated input field
*/
public function dateTimeField($model, $attribute, $htmlOptions = array(), $fieldOptions = array())
{
return HHtml::activeDateTimeField($model, $attribute, $htmlOptions, $fieldOptions);
}
}

View File

@ -23,12 +23,71 @@
*
* @author luke
*/
class HFormInputElement extends CFormInputElement {
class HFormInputElement extends CFormInputElement
{
public function render() {
/**
* Options for dateTimePicker Element
* See HHTML::dateTimeField for more datails.
*
* @var Array
*/
public $dateTimePickerOptions = array();
/**
* @var array Core input types (alias=>CHtml method name)
*/
public static $coreTypes = array(
'text' => 'activeTextField',
'hidden' => 'activeHiddenField',
'password' => 'activePasswordField',
'textarea' => 'activeTextArea',
'file' => 'activeFileField',
'radio' => 'activeRadioButton',
'checkbox' => 'activeCheckBox',
'listbox' => 'activeListBox',
'dropdownlist' => 'activeDropDownList',
'checkboxlist' => 'activeCheckBoxList',
'radiolist' => 'activeRadioButtonList',
'url' => 'activeUrlField',
'email' => 'activeEmailField',
'number' => 'activeNumberField',
'range' => 'activeRangeField',
'date' => 'activeDateField',
'datetime' => 'activeDateTimeField',
);
/**
* Renders the input field.
* The default implementation returns the result of the appropriate CHtml method or the widget.
* @return string the rendering result
*/
public function renderInput()
{
if (isset(self::$coreTypes[$this->type])) {
$method = self::$coreTypes[$this->type];
if (strpos($method, 'List') !== false) {
return HHtml::$method($this->getParent()->getModel(), $this->name, $this->items, $this->attributes);
} elseif ($method == "activeDateTimeField") {
return HHtml::activeDateTimeField($this->getParent()->getModel(), $this->name, $this->attributes, $this->dateTimePickerOptions);
} else {
return HHtml::$method($this->getParent()->getModel(), $this->name, $this->attributes);
}
} else {
$attributes = $this->attributes;
$attributes['model'] = $this->getParent()->getModel();
$attributes['attribute'] = $this->name;
ob_start();
$this->getParent()->getOwner()->widget($this->type, $attributes);
return ob_get_clean();
}
}
public function render()
{
if ($this->type === 'checkbox') {
$output = "<div class='checkbox'><label>". $this->renderInput() . $this->getLabel() . $this->renderHint()."</label></div>";
$output = "<div class='checkbox'><label>" . $this->renderInput() . $this->getLabel() . $this->renderHint() . "</label></div>";
return $output;
}

View File

@ -251,6 +251,78 @@ class HHtml extends CHtml
return $text;
}
/**
* ActiveForm Variant of DateTime Field
*
* @param type $model
* @param type $attribute
* @param type $htmlOptions
* @param type $pickerOptions See HHTML::dateTimeField for details.
* @return type
*/
public static function activeDateTimeField($model, $attribute, $htmlOptions = array(), $pickerOptions = array())
{
$value = self::resolveValue($model, $attribute);
self::resolveNameID($model, $attribute, $htmlOptions);
$name = $htmlOptions['name'];
self::clientChange('change', $htmlOptions);
return self::dateTimeField($name, $value, $htmlOptions, $pickerOptions);
}
/**
* Standalone DateTime Field.
* Internal Format: 2017-01-01 00:00:00
*
* Picker Options Attributes:
* pickDate = TRUE/false
* pickTime = true/FALSE
* displayFormat = Default: DD.MM.YYYY[ - HH:mm]
*
* @param String $name
* @param String $value
* @param Array $htmlOptions
* @param Array $pickerOptions
*
* @return String datetimeField HTML
*/
public static function dateTimeField($name, $value = "", $htmlOptions = array(), $pickerOptions = array())
{
// load js for datetimepicker component
Yii::app()->clientScript->registerScriptFile(
Yii::app()->baseUrl . '/js/moment.js', CClientScript::POS_END
);
Yii::app()->clientScript->registerScriptFile(
Yii::app()->baseUrl . '/js/bootstrap-datetimepicker.js', CClientScript::POS_END
);
Yii::app()->clientScript->registerScriptFile(
Yii::app()->baseUrl . '/js/datetimefield-init.js', CClientScript::POS_END
);
// load css for datetimepicker component
Yii::app()->clientScript->registerCssFile(
Yii::app()->baseUrl . '/css/bootstrap-datetimepicker.css'
);
if (isset($pickerOptions['pickTime']) && $pickerOptions['pickTime'] == true) {
$htmlOptions['data-options-pickTime'] = "true";
}
if (isset($pickerOptions['displayFormat'])) {
$htmlOptions['data-options-displayFormat'] = $pickerOptions['displayFormat'];
}
if (!isset($htmlOptions['class'])) {
$htmlOptions['class'] = 'hhtml-datetime-field';
} else {
$htmlOptions['class'] .= ' hhtml-datetime-field';
}
return self::textField($name, $value, $htmlOptions);
}
}
?>