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}}}
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* 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 int $value The default timestamp
|
||||
* @param DateTime $value The default timestamp
|
||||
* @param array $attribs Attributes for the element tag
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
$info = $this->_getInfo($name, $value, $attribs);
|
||||
extract($info); // name, value, attribs, options, listsep, disable
|
||||
// Is it disabled?
|
||||
extract($info); // name, id, value, attribs, options, listsep, disable
|
||||
/** @var string $id */
|
||||
/** @var bool $disable */
|
||||
$disabled = '';
|
||||
if ($disabled) {
|
||||
if ($disable) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
}
|
||||
|
||||
$jspicker = (isset($attribs['jspicker']) && $attribs['jspicker'] === true) ? true : false;
|
||||
|
||||
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 = '';
|
||||
if ($value instanceof DateTime) {
|
||||
// If value was valid, it's a DateTime object
|
||||
$value = $this->formatDate($value, $attribs['local']);
|
||||
}
|
||||
|
||||
// Build the element
|
||||
$xhtml = '<div class="datetime' . (($jspicker === true) ? ' input-group' : ''). '">';
|
||||
|
||||
$xhtml .= '<input type="text" name="' . $name . '"'
|
||||
. ' id="' . $name . '"'
|
||||
. $value
|
||||
. $disabled
|
||||
. $this->_htmlAttribs($attribs);
|
||||
|
||||
if ($jspicker === true) {
|
||||
$xhtml .= 'data-icinga-component="app/datetime"';
|
||||
$min = '';
|
||||
if (! empty($attribs['min'])) {
|
||||
$min = sprintf(' min="%s"', $this->formatDate($attribs['min'], $attribs['local']));
|
||||
}
|
||||
|
||||
$xhtml .= $this->getClosingBracket();
|
||||
|
||||
if ($jspicker === true) {
|
||||
$xhtml .= '<span class="input-group-addon">'
|
||||
. '<a href="#">'
|
||||
. '<i class="icinga-icon-reschedule"></i>'
|
||||
. '</a>'
|
||||
. '</span>';
|
||||
unset($attribs['min']); // Unset min to not render it again in $this->_htmlAttribs($attribs)
|
||||
$max = '';
|
||||
if (! empty($attribs['max'])) {
|
||||
$max = sprintf(' max="%s"', $this->formatDate($attribs['max'], $attribs['local']));
|
||||
}
|
||||
|
||||
$xhtml .= '</div>';
|
||||
|
||||
return $xhtml;
|
||||
unset($attribs['max']); // Unset max to not render it again in $this->_htmlAttribs($attribs)
|
||||
$type = $attribs['local'] === true ? 'datetime-local' : 'datetime';
|
||||
unset($attribs['local']); // Unset local to not render it again in $this->_htmlAttribs($attribs)
|
||||
$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;
|
||||
|
||||
use Icinga\Web\Form\Validator\DateTimeValidator;
|
||||
use Zend_Form_Element_Text;
|
||||
use DateTime;
|
||||
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
|
||||
* DateTimeFactory to ensure time zone awareness
|
||||
* A date-and-time input control
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public $helper = 'formDateTime';
|
||||
|
||||
/**
|
||||
* The validator used for datetime validation
|
||||
* @var DateTimeValidator
|
||||
* @var bool
|
||||
*/
|
||||
private $dateValidator;
|
||||
protected $local = true;
|
||||
|
||||
/**
|
||||
* Valid formats to check user input against
|
||||
* @var array
|
||||
*/
|
||||
public $patterns = array();
|
||||
|
||||
/**
|
||||
* Create a new DateTimePicker
|
||||
* The expected lower bound for the element’s value
|
||||
*
|
||||
* @param array|string|\Zend_Config $spec
|
||||
* @param null $options
|
||||
* @see Zend_Form_Element::__construct()
|
||||
* @var DateTime|null
|
||||
*/
|
||||
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);
|
||||
$this->addValidator($this->dateValidator);
|
||||
public function getLocal()
|
||||
{
|
||||
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
|
||||
* if the input is considered valid. Utilizes DateTimeFactory to ensure time zone awareness.
|
||||
* @param DateTime $min
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function isValid($value, $context = null)
|
||||
{
|
||||
// Overwrite the internal validator to use
|
||||
|
||||
if (!parent::isValid($value, $context)) {
|
||||
if (! parent::isValid($value, $context)) {
|
||||
return false;
|
||||
}
|
||||
$pattern = $this->dateValidator->getValidPattern();
|
||||
if (!$pattern) {
|
||||
$this->setValue($value);
|
||||
return true;
|
||||
if (! $value instanceof DateTime) {
|
||||
$format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
|
||||
$this->setValue(DateTime::createFromFormat($format, $value));
|
||||
}
|
||||
$this->setValue(DateTimeFactory::parse($value, $pattern)->getTimestamp());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function enableJsPicker()
|
||||
{
|
||||
$this->jspicker = true;
|
||||
}
|
||||
|
||||
public function disableJsPicker()
|
||||
{
|
||||
$this->jspicker = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue