DataTypeDatalist: allow to customize behavior
Available options: * strict: select box * suggest_strict: auto-completion, allow only list values * suggest_optional: Allow for values not on the list * suggest_extend: Extend the list with new values fixes #1846
This commit is contained in:
parent
7177d489ec
commit
db8895ae10
|
@ -258,6 +258,22 @@ class SuggestController extends ActionController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function suggestDataListValuesForListId($id)
|
||||||
|
{
|
||||||
|
$db = $this->db()->getDbAdapter();
|
||||||
|
$select = $db->select()
|
||||||
|
->from('director_datalist_entry', ['entry_name', 'entry_value'])
|
||||||
|
->where('list_id = ?', $id)
|
||||||
|
->order('entry_value ASC');
|
||||||
|
|
||||||
|
$result = $db->fetchPairs($select);
|
||||||
|
if ($result) {
|
||||||
|
return $result;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function suggestDataListValues($field = null)
|
protected function suggestDataListValues($field = null)
|
||||||
{
|
{
|
||||||
if ($field === null) {
|
if ($field === null) {
|
||||||
|
|
|
@ -3,28 +3,87 @@
|
||||||
namespace Icinga\Module\Director\DataType;
|
namespace Icinga\Module\Director\DataType;
|
||||||
|
|
||||||
use Icinga\Module\Director\Acl;
|
use Icinga\Module\Director\Acl;
|
||||||
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Hook\DataTypeHook;
|
use Icinga\Module\Director\Hook\DataTypeHook;
|
||||||
|
use Icinga\Module\Director\Objects\DirectorDatalistEntry;
|
||||||
|
use Icinga\Module\Director\Web\Form\DirectorForm;
|
||||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||||
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||||
|
use Icinga\Module\Director\Web\Form\Validate\IsDataListEntry;
|
||||||
|
|
||||||
class DataTypeDatalist extends DataTypeHook
|
class DataTypeDatalist extends DataTypeHook
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @param QuickForm $form
|
||||||
|
* @return \Zend_Form_Element
|
||||||
|
* @throws \Zend_Form_Exception
|
||||||
|
*/
|
||||||
public function getFormElement($name, QuickForm $form)
|
public function getFormElement($name, QuickForm $form)
|
||||||
{
|
{
|
||||||
$enum = $this->getEntries($form);
|
|
||||||
$params = [];
|
$params = [];
|
||||||
if ($this->getSetting('data_type') === 'array') {
|
$behavior = $this->getSetting('behavior', 'strict');
|
||||||
$type = 'extensibleSet';
|
$targetDataType = $this->getSetting('data_type');
|
||||||
$params['sorted'] = true;
|
$listId = $this->getSetting('datalist_id');
|
||||||
$params = ['multiOptions' => $enum];
|
|
||||||
|
if ($behavior === 'strict') {
|
||||||
|
$enum = $this->getEntries($form);
|
||||||
|
if ($targetDataType === 'string') {
|
||||||
|
$params['sorted'] = true;
|
||||||
|
$params = ['multiOptions' => $enum];
|
||||||
|
$type = 'select';
|
||||||
|
} else {
|
||||||
|
$params = ['multiOptions' => $form->optionalEnum($enum)];
|
||||||
|
$type = 'extensibleSet';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$params = ['multiOptions' => [
|
if ($targetDataType === 'string') {
|
||||||
null => $form->translate('- please choose -'),
|
$type = 'text';
|
||||||
] + $enum];
|
} else {
|
||||||
$type = 'select';
|
$type = 'extensibleSet';
|
||||||
|
}
|
||||||
|
$params['class'] = 'director-suggest';
|
||||||
|
$params['data-suggestion-context'] = "dataListValuesForListId!$listId";
|
||||||
|
}
|
||||||
|
$element = $form->createElement($type, $name, $params);
|
||||||
|
if ($behavior === 'suggest_strict') {
|
||||||
|
$element->addValidator(new IsDataListEntry($listId, $form->getDb()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $form->createElement($type, $name, $params);
|
if ($behavior === 'suggest_extend') {
|
||||||
|
$form->callOnSucess(function (DirectorForm $form) use ($name, $listId) {
|
||||||
|
$value = (array) $form->getValue($name);
|
||||||
|
if ($value === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = $form->getDb();
|
||||||
|
foreach ($value as $entry) {
|
||||||
|
$this->createEntryIfNotExists($db, $listId, $entry);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Db $db
|
||||||
|
* @param $listId
|
||||||
|
* @param $entry
|
||||||
|
*/
|
||||||
|
protected function createEntryIfNotExists(Db $db, $listId, $entry)
|
||||||
|
{
|
||||||
|
if (! DirectorDatalistEntry::exists([
|
||||||
|
'list_id' => $listId,
|
||||||
|
'entry_name' => $entry,
|
||||||
|
], $db)) {
|
||||||
|
DirectorDatalistEntry::create([
|
||||||
|
'list_id' => $listId,
|
||||||
|
'entry_name' => $entry,
|
||||||
|
'entry_value' => $entry,
|
||||||
|
])->store($db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getEntries(QuickForm $form)
|
protected function getEntries(QuickForm $form)
|
||||||
|
@ -34,7 +93,7 @@ class DataTypeDatalist extends DataTypeHook
|
||||||
|
|
||||||
$roles = array_map('json_encode', Acl::instance()->listRoleNames());
|
$roles = array_map('json_encode', Acl::instance()->listRoleNames());
|
||||||
$select = $db->select()
|
$select = $db->select()
|
||||||
->from('director_datalist_entry', array('entry_name', 'entry_value'))
|
->from('director_datalist_entry', ['entry_name', 'entry_value'])
|
||||||
->where('list_id = ?', $this->getSetting('datalist_id'))
|
->where('list_id = ?', $this->getSetting('datalist_id'))
|
||||||
->order('entry_value ASC');
|
->order('entry_value ASC');
|
||||||
|
|
||||||
|
@ -47,17 +106,20 @@ class DataTypeDatalist extends DataTypeHook
|
||||||
return $db->fetchPairs($select);
|
return $db->fetchPairs($select);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QuickForm $form
|
||||||
|
* @throws \Zend_Form_Exception
|
||||||
|
*/
|
||||||
public static function addSettingsFormFields(QuickForm $form)
|
public static function addSettingsFormFields(QuickForm $form)
|
||||||
{
|
{
|
||||||
/** @var DirectorObjectForm $form */
|
/** @var DirectorObjectForm $form */
|
||||||
$db = $form->getDb();
|
$db = $form->getDb();
|
||||||
|
|
||||||
$form->addElement('select', 'datalist_id', array(
|
$form->addElement('select', 'datalist_id', [
|
||||||
'label' => 'List name',
|
'label' => 'List name',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'multiOptions' => array(null => '- please choose -') +
|
'multiOptions' => $form->optionalEnum($db->enumDatalist()),
|
||||||
$db->enumDatalist(),
|
]);
|
||||||
));
|
|
||||||
|
|
||||||
$form->addElement('select', 'data_type', [
|
$form->addElement('select', 'data_type', [
|
||||||
'label' => $form->translate('Target data type'),
|
'label' => $form->translate('Target data type'),
|
||||||
|
@ -68,6 +130,20 @@ class DataTypeDatalist extends DataTypeHook
|
||||||
'required' => true,
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $form;
|
$form->addElement('select', 'behavior', [
|
||||||
|
'label' => $form->translate('Element behavior'),
|
||||||
|
'value' => 'strict',
|
||||||
|
'description' => $form->translate(
|
||||||
|
'This allows to show either a drop-down list or an auto-completion'
|
||||||
|
),
|
||||||
|
'multiOptions' => [
|
||||||
|
'strict' => $form->translate('Dropdown (list values only)'),
|
||||||
|
$form->translate('Autocomplete') => [
|
||||||
|
'suggest_strict' => $form->translate('Strict, list values only'),
|
||||||
|
'suggest_optional' => $form->translate('Allow for values not on the list'),
|
||||||
|
'suggest_extend' => $form->translate('Extend the list with new values'),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Web\Form\Validate;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Db;
|
||||||
|
use Icinga\Module\Director\Objects\DirectorDatalistEntry;
|
||||||
|
use Zend_Validate_Abstract;
|
||||||
|
|
||||||
|
class IsDataListEntry extends Zend_Validate_Abstract
|
||||||
|
{
|
||||||
|
const INVALID = 'intInvalid';
|
||||||
|
|
||||||
|
/** @var Db */
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $dataListId;
|
||||||
|
|
||||||
|
public function __construct($dataListId, Db $db)
|
||||||
|
{
|
||||||
|
$this->db = $db;
|
||||||
|
$this->dataListId = (int) $dataListId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid($value)
|
||||||
|
{
|
||||||
|
if (is_array($value)) {
|
||||||
|
foreach ($value as $name) {
|
||||||
|
if (! $this->isListEntry($name)) {
|
||||||
|
$this->_error(self::INVALID, $value);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isListEntry($value)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
$this->_error(self::INVALID, $value);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isListEntry($name)
|
||||||
|
{
|
||||||
|
return DirectorDatalistEntry::exists([
|
||||||
|
'list_id' => $this->dataListId,
|
||||||
|
'entry_name' => $name,
|
||||||
|
], $this->db);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue