How to add a datalist to an input form
- asinkan
- Member | 38
Hi,
I have a form in my presenter
protected function createComponentPickChildForm()
{
$form = new Form;
$form->addText('child', 'Dítě:')
->setRequired('Prosím vyplňte jméno.');
$form->addProtection();
return $form;
}
how can I add there a datalist? Like in HTML:
<input list="browsers">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
The question is: How to add attribute list=“browsers” to
my input form. I can do other things in default.latte
Thx very much
++++++++++++++++++++++++++++++++++++++++++++++
OK I found nice solution. Everything is in the presenter
$form->addText('userId', 'Rodič (Parent):')->setRequired('Prosím vyplňte rodiče. (Please select the parent).')
->setAttribute('list', 'parentList')
->setAttribute('autocomplete', 'off');
$parents = $this->userRepository->findAllActiveUsers();
$dataList = Html::el('datalist id="parentList"');
foreach ($parents as $value) {
$dataList->create('option value="'.$value->lastname.' '.$value->firstname.'"');
}
echo $dataList;
Do not forget to add
use Nette\Utils\Html;
Last edited by asinkan (2018-11-27 23:17)
- Ondřej Kubíček
- Member | 494
nette doesnt support datalist, so the eastest way is manual rendering
<form n:name="pickChildForm">
<input list="browsers" n:name="child">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
</form>
- Martin
- Member | 171
Simpliest way, usable to standard renderer:
<?php
class DataList extends Nette\Forms\Controls\BaseControl
{
protected $values;
public function __construct($label = NULL, $values = NULL)
{
parent::__construct($label);
$this->values = $values;
}
function getControl()
{
$datalist = Nette\Utils\Html::el('datalist')->addAttributes([
'id' => $this->getHtmlId(),
]);
foreach ($this->values as $value) {
$datalist->addHtml(Nette\Utils\Html::el('option')->addAttributes([
'value' => $value,
])
);
}
return $datalist;
}
}
Nette\Object::extensionMethod('Nette\Forms\Container::addDataList', function($form, $name, $values = NULL){
$form[$name] = new DataList(NULL, $values);
return $form[$name];
});
Nette\Object::extensionMethod('Nette\Forms\Container::addDataListWithVisibleLabel', function($form, $name, $label = NULL, $values = NULL){
$form[$name] = new DataList($label, $values); // for testing only ...
return $form[$name];
});
?>
Using:
<?php
$dataList = $form->addDataList('dataListExample', ['Value 1', 'Value 2']);
$form->addText('textWithDataList', 'Text with DataList')
->setAttribute('list',$dataList->getHtmlId());
?>
Result:
You can also add extension method addDataList to TextBox or method to its
descendant.
Or define class TextBoxWithDatalist, but one DataList belongs to one TextBox in
this case, which could not be right way.
Or use more complex solution by deep Nette OOP and DI, but they are more
desirable ones to do it then me.
Last edited by Martin (2018-01-25 22:06)
- David Matějka
- Moderator | 6445
@Martin the way you are building the html is insecure and may result
in xss. you should at least use Nette\Utils\Html
- Martin
- Member | 171
David Matějka wrote:
@Martin the way you are building the html is insecure and may result in xss. you should at least use
Nette\Utils\Html
Thank you. I am sorry, I din not use Nette last 6 years. Do you mean to check $value only, or full result, or another way? I will repaire code above.
- David Matějka
- Moderator | 6445
@Martin yes, i mean $value
. it should look like
this:
$datalist = Nette\Utils\Html::el('datalist')->addAttributes([
'id' => $this->getHtmlId(),
]);
foreach ($this->values as $value) {
$datalist->addHtml(Nette\Utils\Html::el('option')->addAttributes([
'value' => $value,
]);
}
- Martin
- Member | 171
Thanks, I repaired a code. Hovewer, cutting off is not working
probably in <?php code ?> here, then I removed wrong code part. I will
try it when I am near my computer.
…
After adding one parenthesis the code is working. Thank you for the correction.
Last edited by Martin (2018-01-25 22:35)