私はそれを達成するためにカスタムフォーム要素を使用します。
namespace VendorName\ModuleName\Block\Widget\Form\Element;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Data\Form\Element\Factory as ElementFactory;
use Magento\Framework\Data\Form\Element\CollectionFactory;
use Magento\Framework\Escaper;
/**
* Class Time.
*/
class Time extends AbstractElement
{
/**
* Constructor.
*
* @param ElementFactory $elementFactory
* @param CollectionFactory $collectionFactory
* @param Escaper $escaper
* @param array $data
*/
public function __construct(
ElementFactory $elementFactory,
CollectionFactory $collectionFactory,
Escaper $escaper,
array $data = []
) {
parent::__construct($elementFactory, $collectionFactory, $escaper, $data);
$this->setType('time');
}
/**
* {@inheritdoc}
*/
public function getElementHtml()
{
$this->addClass('select admin__control-select');
$defaultValues = [
'time' => '00:00:00',
'hour' => '00',
'minute' => '00',
'second' => '00',
];
$values = $this->getValue();
if (!$values) {
$values = $defaultValues;
} else {
$time = explode(':', $values);
$values = [
'time' => $values,
'hour' => $time[0],
'minute' => $time[1],
'second' => $time[2],
];
}
// value container element
$html = '<input type="hidden" id="' . $this->getHtmlId() . '" name="' . $this->getName()
. '" value="' . $values['time'] . '" '. $this->_getUiId() . '/>' . PHP_EOL
;
// hours control
$html .= '<select style="width:80px" id="' . $this->getHourControlHtmlId() . '" '
. $this->serialize($this->getControlHtmlAttributes()) . ' title="' . __('hours') . '" '
. $this->_getUiId('hour') . '>' . PHP_EOL
;
for ($i = 0; $i < 24; $i++) {
$hour = str_pad($i, 2, '0', STR_PAD_LEFT);
$html .= '<option'
. ' value="' . $hour . '"'
. ($values['hour'] == $i ? ' selected="selected"' : '') . '>'
. $hour
. '</option>' . PHP_EOL
;
}
$html .= '</select>' . PHP_EOL;
// minutes control
$html .= ': <select style="width:80px" id="' . $this->getMinuteControlHtmlId() . '" '
. $this->serialize($this->getControlHtmlAttributes()) . ' title="' . __('minutes') . '" '
. $this->_getUiId('minute') . '>' . PHP_EOL
;
for ($i = 0; $i < 60; $i++) {
$minute = str_pad($i, 2, '0', STR_PAD_LEFT);
$html .= '<option'
. ' value="' . $minute . '"'
. ($values['minute'] == $i ? ' selected="selected"' : '') . '>'
. $minute
. '</option>' . PHP_EOL
;
}
$html .= '</select>' . PHP_EOL;
// seconds control
$html .= ': <select style="width:80px" id="' . $this->getSecondControlHtmlId() . '" '
. $this->serialize($this->getControlHtmlAttributes()) . ' title="' . __('seconds') . '" '
. $this->_getUiId('second') . '>' . PHP_EOL
;
for ($i = 0; $i < 60; $i++) {
$second = str_pad($i, 2, '0', STR_PAD_LEFT);
$html .= '<option'
. ' value="' . $second . '"'
. ($values['hour'] == $i ? ' selected="selected"' : '') . '>'
. $second
. '</option>' . PHP_EOL
;
}
$html .= '</select>' . PHP_EOL;
$html .= $this->getAfterElementHtml();
$html .= $this->getAfterElementJs();
return $html;
}
/**
* Get after element JS.
*
* @return string
*/
public function getAfterElementJs()
{
$js = '
<script type="text/javascript">
require(["jquery"], function ($) {
var onTimeContainerChange = function () {
var time = $("#' . $this->getHtmlId() . '").val();
var timeArray = time.split(":");
$("#' . $this->getHourControlHtmlId() . '").val(timeArray[0]);
$("#' . $this->getMinuteControlHtmlId() . '").val(timeArray[1]);
$("#' . $this->getSecondControlHtmlId() . '").val(timeArray[2]);
};
$(document).ready(onTimeContainerChange);
$("#' . $this->getHtmlId() . '").change(onTimeContainerChange);
var onTimeControlChange = function () {
var time = $("#' . $this->getHourControlHtmlId() . '").val()
+ ":" + $("#' . $this->getMinuteControlHtmlId() . '").val()
+ ":" + $("#' . $this->getSecondControlHtmlId() . '").val()
;
$("#' . $this->getHtmlId() . '").val(time);
}
$("'
. '#' . $this->getHourControlHtmlId() . ','
. '#' . $this->getMinuteControlHtmlId() . ','
. '#' . $this->getSecondControlHtmlId()
. '").change(onTimeControlChange);
});
</script>
';
return $js;
}
/**
* Get hour control html id prefix.
*
* @return string
*/
protected function getHourControlHtmlId()
{
return $this->getHtmlId() . '_hour_control';
}
/**
* Get minute control html id prefix.
*
* @return string
*/
protected function getMinuteControlHtmlId()
{
return $this->getHtmlId() . '_minute_control';
}
/**
* Get second control html id prefix.
*
* @return string
*/
protected function getSecondControlHtmlId()
{
return $this->getHtmlId() . '_second_control';
}
/**
* Get control html attributes.
*
* @return array
*/
protected function getControlHtmlAttributes()
{
$propertiesToClear = ['title'];
$htmlAttributes = $this->getHtmlAttributes();
return array_diff($htmlAttributes, $propertiesToClear);
}
}
たとえば、2番目のフィールドを削除するなど、要件に合わせてカスタマイズします。
使い方:
use VendorName\ModuleName\Block\Widget\Form\Element\Time as TimeElement;
$form->addType('custom_time', TimeElement::class);
$form->addField(
'[id_of_your_field]',
'custom_time',
[
... // data
]
);