mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-31 01:34:09 +02:00
lib: Let the date-and-time input control behave as defined in HTML5
refs #6593
This commit is contained in:
parent
906de4e679
commit
2025fb3a2f
@ -2,18 +2,30 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use Zend_View_Helper_FormElement;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to generate a "datetime" element
|
* Render date-and-time input controls
|
||||||
*/
|
*/
|
||||||
class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement
|
class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Generate a 'datetime' element
|
* Format date and time
|
||||||
|
*
|
||||||
|
* @param DateTime $dateTime
|
||||||
|
* @param bool $local
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function formatDate(DateTime $dateTime, $local)
|
||||||
|
{
|
||||||
|
$format = (bool) $local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
|
||||||
|
return $dateTime->format($format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the date-and-time input control
|
||||||
*
|
*
|
||||||
* @param string $name The element name
|
* @param string $name The element name
|
||||||
* @param int $value The default timestamp
|
* @param DateTime $value The default timestamp
|
||||||
* @param array $attribs Attributes for the element tag
|
* @param array $attribs Attributes for the element tag
|
||||||
*
|
*
|
||||||
* @return string The element XHTML
|
* @return string The element XHTML
|
||||||
@ -21,50 +33,41 @@ class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement
|
|||||||
public function formDateTime($name, $value = null, $attribs = null)
|
public function formDateTime($name, $value = null, $attribs = null)
|
||||||
{
|
{
|
||||||
$info = $this->_getInfo($name, $value, $attribs);
|
$info = $this->_getInfo($name, $value, $attribs);
|
||||||
extract($info); // name, value, attribs, options, listsep, disable
|
extract($info); // name, id, value, attribs, options, listsep, disable
|
||||||
// Is it disabled?
|
/** @var string $id */
|
||||||
|
/** @var bool $disable */
|
||||||
$disabled = '';
|
$disabled = '';
|
||||||
if ($disabled) {
|
if ($disable) {
|
||||||
$disabled = ' disabled="disabled"';
|
$disabled = ' disabled="disabled"';
|
||||||
}
|
}
|
||||||
|
if ($value instanceof DateTime) {
|
||||||
$jspicker = (isset($attribs['jspicker']) && $attribs['jspicker'] === true) ? true : false;
|
// If value was valid, it's a DateTime object
|
||||||
|
$value = $this->formatDate($value, $attribs['local']);
|
||||||
if (isset($value) && !empty($value)) {
|
|
||||||
if ($jspicker) {
|
|
||||||
$value = ' value="' . $this->view->dateFormat()->format($value, $attribs['defaultFormat']) . '"';
|
|
||||||
} else {
|
|
||||||
$value = ' value="' . $this->view->dateFormat()->formatDateTime($value) . '"';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$value = '';
|
|
||||||
}
|
}
|
||||||
|
$min = '';
|
||||||
// Build the element
|
if (! empty($attribs['min'])) {
|
||||||
$xhtml = '<div class="datetime' . (($jspicker === true) ? ' input-group' : ''). '">';
|
$min = sprintf(' min="%s"', $this->formatDate($attribs['min'], $attribs['local']));
|
||||||
|
|
||||||
$xhtml .= '<input type="text" name="' . $name . '"'
|
|
||||||
. ' id="' . $name . '"'
|
|
||||||
. $value
|
|
||||||
. $disabled
|
|
||||||
. $this->_htmlAttribs($attribs);
|
|
||||||
|
|
||||||
if ($jspicker === true) {
|
|
||||||
$xhtml .= 'data-icinga-component="app/datetime"';
|
|
||||||
}
|
}
|
||||||
|
unset($attribs['min']); // Unset min to not render it again in $this->_htmlAttribs($attribs)
|
||||||
$xhtml .= $this->getClosingBracket();
|
$max = '';
|
||||||
|
if (! empty($attribs['max'])) {
|
||||||
if ($jspicker === true) {
|
$max = sprintf(' max="%s"', $this->formatDate($attribs['max'], $attribs['local']));
|
||||||
$xhtml .= '<span class="input-group-addon">'
|
|
||||||
. '<a href="#">'
|
|
||||||
. '<i class="icinga-icon-reschedule"></i>'
|
|
||||||
. '</a>'
|
|
||||||
. '</span>';
|
|
||||||
}
|
}
|
||||||
|
unset($attribs['max']); // Unset max to not render it again in $this->_htmlAttribs($attribs)
|
||||||
$xhtml .= '</div>';
|
$type = $attribs['local'] === true ? 'datetime-local' : 'datetime';
|
||||||
|
unset($attribs['local']); // Unset local to not render it again in $this->_htmlAttribs($attribs)
|
||||||
return $xhtml;
|
$html5 = sprintf(
|
||||||
|
'<input type="%s" name="%s" id="%s" value="%s"%s%s%s%s%s',
|
||||||
|
$type,
|
||||||
|
$this->view->escape($name),
|
||||||
|
$this->view->escape($id),
|
||||||
|
$this->view->escape($value),
|
||||||
|
$min,
|
||||||
|
$max,
|
||||||
|
$disabled,
|
||||||
|
$this->_htmlAttribs($attribs),
|
||||||
|
$this->getClosingBracket()
|
||||||
|
);
|
||||||
|
return $html5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,100 +4,145 @@
|
|||||||
|
|
||||||
namespace Icinga\Web\Form\Element;
|
namespace Icinga\Web\Form\Element;
|
||||||
|
|
||||||
use Icinga\Web\Form\Validator\DateTimeValidator;
|
use DateTime;
|
||||||
use Zend_Form_Element_Text;
|
|
||||||
use Zend_Form_Element;
|
use Zend_Form_Element;
|
||||||
use Icinga\Util\DateTimeFactory;
|
use Icinga\Web\Form\Validator\DateTimeValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Datetime form element which returns the input as Unix timestamp after the input has been proven valid. Utilizes
|
* A date-and-time input control
|
||||||
* DateTimeFactory to ensure time zone awareness
|
|
||||||
*
|
*
|
||||||
* @see isValid()
|
* @method DateTime getValue()
|
||||||
*/
|
*/
|
||||||
class DateTimePicker extends Zend_Form_Element_Text
|
class DateTimePicker extends Zend_Form_Element
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Default format used my js picker
|
* Disable default decorators
|
||||||
|
*
|
||||||
|
* \Icinga\Web\Form sets default decorators for elements.
|
||||||
*
|
*
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $defaultFormat = 'Y-m-d H:i:s';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JS picker support on or off
|
|
||||||
* @var bool
|
* @var bool
|
||||||
|
*
|
||||||
|
* @see \Icinga\Web\Form::__construct() For default element decorators.
|
||||||
*/
|
*/
|
||||||
public $jspicker = true;
|
protected $_disableLoadDefaultDecorators = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View helper to use
|
* Form view helper to use for rendering
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $helper = 'formDateTime';
|
public $helper = 'formDateTime';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The validator used for datetime validation
|
* @var bool
|
||||||
* @var DateTimeValidator
|
|
||||||
*/
|
*/
|
||||||
private $dateValidator;
|
protected $local = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Valid formats to check user input against
|
* The expected lower bound for the element’s value
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $patterns = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new DateTimePicker
|
|
||||||
*
|
*
|
||||||
* @param array|string|\Zend_Config $spec
|
* @var DateTime|null
|
||||||
* @param null $options
|
|
||||||
* @see Zend_Form_Element::__construct()
|
|
||||||
*/
|
*/
|
||||||
public function __construct($spec, $options = null)
|
protected $min;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The expected upper bound for the element’s
|
||||||
|
*
|
||||||
|
* @var DateTime|null
|
||||||
|
*/
|
||||||
|
protected $max;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (non-PHPDoc)
|
||||||
|
* @see \Zend_Form_Element::init() For the method documentation.
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
{
|
{
|
||||||
parent::__construct($spec, $options);
|
$this->addValidator(
|
||||||
|
new DateTimeValidator($this->local), true // true for breaking the validator chain on failure
|
||||||
|
);
|
||||||
|
if ($this->min !== null) {
|
||||||
|
$this->addValidator('GreaterThan', true, array('min' => $this->min));
|
||||||
|
}
|
||||||
|
if ($this->max !== null) {
|
||||||
|
$this->addValidator('LessThan', true, array('max' => $this->max));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->patterns[] = $this->defaultFormat;
|
public function setLocal($local)
|
||||||
|
{
|
||||||
|
$this->local = (bool) $local;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
$this->dateValidator = new DateTimeValidator($this->patterns);
|
public function getLocal()
|
||||||
$this->addValidator($this->dateValidator);
|
{
|
||||||
|
return $this->local;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate filtered date/time strings
|
* Set the expected lower bound for the element’s value
|
||||||
*
|
*
|
||||||
* Expects one or more valid formats being set in $this->patterns. Sets element value as Unix timestamp
|
* @param DateTime $min
|
||||||
* if the input is considered valid. Utilizes DateTimeFactory to ensure time zone awareness.
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setMin(DateTime $min)
|
||||||
|
{
|
||||||
|
$this->min = $min;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the expected lower bound for the element’s value
|
||||||
|
*
|
||||||
|
* @return DateTime|null
|
||||||
|
*/
|
||||||
|
public function getMin()
|
||||||
|
{
|
||||||
|
return $this->min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the expected upper bound for the element’s value
|
||||||
|
*
|
||||||
|
* @param DateTime $max
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setMax(DateTime $max)
|
||||||
|
{
|
||||||
|
$this->max = $max;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the expected upper bound for the element’s value
|
||||||
|
*
|
||||||
|
* @return DateTime|null
|
||||||
|
*/
|
||||||
|
public function getMax()
|
||||||
|
{
|
||||||
|
return $this->max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the date and time valid?
|
||||||
|
*
|
||||||
|
* @param string|DateTime $value
|
||||||
|
* @param mixed $context
|
||||||
*
|
*
|
||||||
* @param string $value
|
|
||||||
* @param mixed $context
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isValid($value, $context = null)
|
public function isValid($value, $context = null)
|
||||||
{
|
{
|
||||||
// Overwrite the internal validator to use
|
if (! parent::isValid($value, $context)) {
|
||||||
|
|
||||||
if (!parent::isValid($value, $context)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$pattern = $this->dateValidator->getValidPattern();
|
if (! $value instanceof DateTime) {
|
||||||
if (!$pattern) {
|
$format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
|
||||||
$this->setValue($value);
|
$this->setValue(DateTime::createFromFormat($format, $value));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
$this->setValue(DateTimeFactory::parse($value, $pattern)->getTimestamp());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enableJsPicker()
|
|
||||||
{
|
|
||||||
$this->jspicker = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function disableJsPicker()
|
|
||||||
{
|
|
||||||
$this->jspicker = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user