Loading src/UnicaenApp/Form/View/Helper/FormElementCollection.php +36 −54 Original line number Diff line number Diff line <?php namespace UnicaenApp\Form\View\Helper; use UnicaenApp\Form\Element\Collection; use Laminas\Form\View\Helper\FormCollection; use Laminas\Form\ElementInterface; use Laminas\Form\Element\Collection as CollectionElement; use Laminas\Form\ElementInterface; use Laminas\Form\FieldsetInterface; use Laminas\Form\LabelAwareInterface; use Laminas\Form\Element\Button; use Laminas\Form\View\Helper\FormCollection; use UnicaenApp\Form\Element\Collection; /** * Aide de vue dessinant une collection d'éléments. Loading Loading @@ -37,18 +36,13 @@ class FormElementCollection extends FormCollection protected $defaultElementHelper = 'formControlGroup'; /** * Nombre d'éléments à afficher * * @var int * Nombre d'éléments à afficher. */ protected $countElements; protected int $countElements; /** * Render a collection by iterating through all fieldsets and elements * * @param ElementInterface $element * @return string * Render a collection by iterating through all fieldsets and elements. */ public function render(ElementInterface $element): string { Loading @@ -65,7 +59,9 @@ class FormElementCollection extends FormCollection $css = null; $templateMarkup = ''; $elementHelper = $this->getElementHelper(); assert(is_callable($elementHelper)); $fieldsetHelper = $this->getFieldsetHelper(); assert(is_callable($fieldsetHelper)); if ($element instanceof CollectionElement && $element->shouldCreateTemplate()) { $this->countElements = $element->getCount(); Loading @@ -82,17 +78,19 @@ class FormElementCollection extends FormCollection foreach ($element->getIterator() as $elementOrFieldset) { if ($elementOrFieldset instanceof FieldsetInterface) { $elementOrFieldset->setAttribute('data-index', $index); $markup .= $fieldsetHelper($elementOrFieldset, $this->shouldWrap()); $fieldsetHtml = $fieldsetHelper($elementOrFieldset, $this->shouldWrap()); $fieldsetHtml = str_replace('__index__', $index, $fieldsetHtml); $index++; $markup .= $fieldsetHtml; } elseif ($elementOrFieldset instanceof ElementInterface) { if ($element instanceof FieldsetInterface) { $domId = $elementOrFieldset->getAttribute('id') ?: uniqid('element-'); $elementOrFieldset->setAttribute('id', $domId . '-__index__'); // NB : la valeur d'un id doit être unique dans un DOM. Or, en cas de collection autorisant l'ajout d'élément // (par clonage), on garantit l'unicité en concaténant le pattern '__index__', pattern qui est remplacé/incrémenté // par le moteur js de cette aide de vue (cf. plus bas). /** Par ex, {@see \UnicaenApp\Form\Element\SearchAndSelect} ne fonctionne plus dans une collection en cas de doublon d'id. */ } /** * NB : la valeur d'un id doit être unique dans un DOM. Or, en cas de collection autorisant l'ajout d'élément * (par clonage), on garantit l'unicité en concaténant le pattern '__index__', pattern qui est remplacé/incrémenté * par le moteur js de cette aide de vue (cf. plus bas). * Par ex, {@see \UnicaenApp\Form\Element\SearchAndSelect} ne fonctionne plus dans une collection en cas de doublon d'id. */ $id = $elementOrFieldset->getAttribute('id') ?: uniqid('element-'); $elementOrFieldset->setAttribute('id', $id . '-__index__'); $markup .= $elementHelper($elementOrFieldset); } } Loading Loading @@ -142,7 +140,7 @@ class FormElementCollection extends FormCollection return $markup; } protected function getDelLink() protected function getDelLink(): string { return '<div class="collection-delete-link">' . '<a class="btn btn-link" title="Supprimer cet élément de la collection">' . Loading @@ -151,12 +149,7 @@ class FormElementCollection extends FormCollection '</div>'; } /** * Get add link * * @return string */ protected function getAddLink() protected function getAddLink(): string { return '<div class="collection-add-link">' . '<a class="btn btn-link" title="Ajouter un élément à la collection">' . Loading @@ -165,11 +158,7 @@ class FormElementCollection extends FormCollection '</div>'; } /** * @param Collection $container * @return string */ protected function getCss($container) protected function getCss(Collection $container): string { $fieldsetId = $container->getAttribute('id'); Loading Loading @@ -202,11 +191,7 @@ EOT; return $css; } /** * @param Collection $container * @return string */ protected function getJavascript($container) protected function getJavascript(Collection $container): string { $maxEnabled = ($container->getMaxElements()) ? 'true' : 'false'; $minEnabled = ($container->getMinElements()) ? 'true' : 'false'; Loading Loading @@ -291,24 +276,21 @@ $().ready(function updateButtons() }); } }); EOT; foreach($container->getAutocomplete() as $name => $options) { $javascript .= <<<EOT $('#{$container->getAttribute('id')}').on('keyup', '.{$container->getAttribute('id')}-autocomplete', function() { $(this).autocompleteOctopus({ source: '{$options['source']}', minLength: {$options['min-length']}, delay: {$options['delay']} }); }); EOT; } // foreach($container->getAutocomplete() as $name => $options) { // $javascript .= <<<EOT //$('#{$container->getAttribute('id')}').on('keyup', '.{$container->getAttribute('id')}-autocomplete', function() { // $(this).autocompleteOctopus({ // source: '{$options['source']}', // minLength: {$options['min-length']}, // delay: {$options['delay']} // }); //}); // // //EOT; // } return '<script type="text/javascript">' . $javascript . '</script>'; } Loading src/UnicaenApp/Form/View/Helper/FormSearchAndSelect.php +28 −94 Original line number Diff line number Diff line <?php namespace UnicaenApp\Form\View\Helper; use UnicaenApp\Exception\LogicException; use UnicaenApp\Form\Element\SearchAndSelect; use Laminas\Form\Element\Text; use Laminas\Form\ElementInterface; use Laminas\Form\Exception\InvalidElementException; use Laminas\Form\View\Helper\FormText; use UnicaenApp\Form\Element\SearchAndSelect; /** * Aide de vue générant le code HTML de l'élément de formulaire du même nom. * * @author <bertrand.gauthier@unicaen.fr> * @see \UnicaenApp\Form\Element\SearchAndSelect * Aide de vue générant le code HTML de l'élément de formulaire {@see \UnicaenApp\Form\Element\SearchAndSelect}. */ class FormSearchAndSelect extends FormText { /** * @var SearchAndSelect */ protected $element; /** * @var string */ protected $autocompleteSource; /** * @var int */ protected $autocompleteMinLength = 2; /** * @var string */ protected $spinnerSource = "//gest.unicaen.fr/images/ajax-loader-r.gif"; protected SearchAndSelect $element; protected Text $autocompleteElement; protected ?string $autocompleteSource = null; protected int $autocompleteMinLength = 2; protected string $spinnerSource = "//gest.unicaen.fr/images/ajax-loader-r.gif"; /** * {@inheritdoc} */ public function __invoke(ElementInterface $element = null) { if ($element && !$element instanceof SearchAndSelect) { throw new InvalidElementException("L'élément spécifié n'est pas du type attendu."); if (! $element) { return $this; } $this->element = $element; return parent::__invoke($element); return $this->render($element); } /** * {@inheritdoc} */ public function render(ElementInterface $element): string { if (!$element instanceof SearchAndSelect) { Loading @@ -74,20 +49,22 @@ class FormSearchAndSelect extends FormText // 'label' => libellé affiché (ex: nom complet de la personne) $this->element->setName($name . "[$id]"); // render parent $markup = parent::render($this->element); $elementDomId = $this->element->getAttribute('id'); $autocompleteDomId = $elementDomId . '-autocomplete'; $autocomplete = new Text(); $autocomplete->setAttributes($this->element->getAttributes()) $this->autocompleteElement = new Text(); $this->autocompleteElement ->setAttributes($this->element->getAttributes()) ->setName($name . "[$label]") ->setAttribute('id', $autocompleteDomId) ->setAttribute('class', 'form-control form-control-sm') ->setValue($this->element->getValueLabel() ?: $this->element->getValue()); $markup .= $this->getView()->formText($autocomplete); $this->element->setAttribute('style', $this->element->getAttribute('style') . ' display:none;'); $markup = parent::render($this->element); $markup .= $this->view->formText($this->autocompleteElement); $markup .= <<<EOS <style> Loading @@ -100,34 +77,21 @@ class FormSearchAndSelect extends FormText </style> EOS; // $this->getView()->plugin('inlineScript')->appendScript($this->getJavascript()); $markup .= PHP_EOL . '<script>' . $this->getJavascript() . '</script>' . PHP_EOL; return $markup; } /** * * @return string * @throws LogicException */ public function getJavascript() protected function getJavascript(): string { if (!$this->element) { throw new LogicException("Aucun élément spécifié, appelez render() auparavant."); } $elementDomId = $this->element->getAttribute('id'); $autocompleteDomId = $elementDomId . '-autocomplete'; $js = <<<EOT // cache l'élément contenant l'id de la sélection $("#{$elementDomId}").css('display', 'none'); $autocompleteDomId = $this->autocompleteElement->getAttribute('id'); return <<<EOT $(function() { // jQuery UI autocomplete var autocomp = $("#{$autocompleteDomId}"); autocomp.autocompleteUnicaen({ // autocompleteUnicaen() définie dans "public/js/util.js" autocomp.autocompleteUnicaen({ // autocompleteUnicaen() définie dans "public/unicaen/app/js/unicaen.js" elementDomId: '$elementDomId', source: '{$this->getAutocompleteSource()}', minLength: {$this->getAutocompleteMinLength()}, Loading @@ -135,27 +99,15 @@ $(function() { }); }); EOT; return $js; } /** * * * @param string|array $autocompleteSource * @return SearchAndSelect */ public function setAutocompleteSource($autocompleteSource) public function setAutocompleteSource(string $autocompleteSource): self { $this->autocompleteSource = $autocompleteSource; return $this; } /** * * * @return string|array $autocompleteSource */ public function getAutocompleteSource() public function getAutocompleteSource(): string { if (null !== $this->autocompleteSource) { return $this->autocompleteSource; Loading @@ -163,41 +115,23 @@ EOT; return $this->element->getAutocompleteSource(); } /** * * @return int */ public function getAutocompleteMinLength() public function getAutocompleteMinLength(): int { return $this->autocompleteMinLength; } /** * * @param int $autocompleteMinLength * @return SearchAndSelect */ public function setAutocompleteMinLength($autocompleteMinLength) public function setAutocompleteMinLength(int $autocompleteMinLength): self { $this->autocompleteMinLength = $autocompleteMinLength; return $this; } /** * * @return string */ public function getSpinnerSource() public function getSpinnerSource(): string { return $this->spinnerSource; } /** * * @param string $spinnerSource * @return SearchAndSelect */ public function setSpinnerSource($spinnerSource) public function setSpinnerSource(string $spinnerSource): self { $this->spinnerSource = $spinnerSource; return $this; Loading Loading
src/UnicaenApp/Form/View/Helper/FormElementCollection.php +36 −54 Original line number Diff line number Diff line <?php namespace UnicaenApp\Form\View\Helper; use UnicaenApp\Form\Element\Collection; use Laminas\Form\View\Helper\FormCollection; use Laminas\Form\ElementInterface; use Laminas\Form\Element\Collection as CollectionElement; use Laminas\Form\ElementInterface; use Laminas\Form\FieldsetInterface; use Laminas\Form\LabelAwareInterface; use Laminas\Form\Element\Button; use Laminas\Form\View\Helper\FormCollection; use UnicaenApp\Form\Element\Collection; /** * Aide de vue dessinant une collection d'éléments. Loading Loading @@ -37,18 +36,13 @@ class FormElementCollection extends FormCollection protected $defaultElementHelper = 'formControlGroup'; /** * Nombre d'éléments à afficher * * @var int * Nombre d'éléments à afficher. */ protected $countElements; protected int $countElements; /** * Render a collection by iterating through all fieldsets and elements * * @param ElementInterface $element * @return string * Render a collection by iterating through all fieldsets and elements. */ public function render(ElementInterface $element): string { Loading @@ -65,7 +59,9 @@ class FormElementCollection extends FormCollection $css = null; $templateMarkup = ''; $elementHelper = $this->getElementHelper(); assert(is_callable($elementHelper)); $fieldsetHelper = $this->getFieldsetHelper(); assert(is_callable($fieldsetHelper)); if ($element instanceof CollectionElement && $element->shouldCreateTemplate()) { $this->countElements = $element->getCount(); Loading @@ -82,17 +78,19 @@ class FormElementCollection extends FormCollection foreach ($element->getIterator() as $elementOrFieldset) { if ($elementOrFieldset instanceof FieldsetInterface) { $elementOrFieldset->setAttribute('data-index', $index); $markup .= $fieldsetHelper($elementOrFieldset, $this->shouldWrap()); $fieldsetHtml = $fieldsetHelper($elementOrFieldset, $this->shouldWrap()); $fieldsetHtml = str_replace('__index__', $index, $fieldsetHtml); $index++; $markup .= $fieldsetHtml; } elseif ($elementOrFieldset instanceof ElementInterface) { if ($element instanceof FieldsetInterface) { $domId = $elementOrFieldset->getAttribute('id') ?: uniqid('element-'); $elementOrFieldset->setAttribute('id', $domId . '-__index__'); // NB : la valeur d'un id doit être unique dans un DOM. Or, en cas de collection autorisant l'ajout d'élément // (par clonage), on garantit l'unicité en concaténant le pattern '__index__', pattern qui est remplacé/incrémenté // par le moteur js de cette aide de vue (cf. plus bas). /** Par ex, {@see \UnicaenApp\Form\Element\SearchAndSelect} ne fonctionne plus dans une collection en cas de doublon d'id. */ } /** * NB : la valeur d'un id doit être unique dans un DOM. Or, en cas de collection autorisant l'ajout d'élément * (par clonage), on garantit l'unicité en concaténant le pattern '__index__', pattern qui est remplacé/incrémenté * par le moteur js de cette aide de vue (cf. plus bas). * Par ex, {@see \UnicaenApp\Form\Element\SearchAndSelect} ne fonctionne plus dans une collection en cas de doublon d'id. */ $id = $elementOrFieldset->getAttribute('id') ?: uniqid('element-'); $elementOrFieldset->setAttribute('id', $id . '-__index__'); $markup .= $elementHelper($elementOrFieldset); } } Loading Loading @@ -142,7 +140,7 @@ class FormElementCollection extends FormCollection return $markup; } protected function getDelLink() protected function getDelLink(): string { return '<div class="collection-delete-link">' . '<a class="btn btn-link" title="Supprimer cet élément de la collection">' . Loading @@ -151,12 +149,7 @@ class FormElementCollection extends FormCollection '</div>'; } /** * Get add link * * @return string */ protected function getAddLink() protected function getAddLink(): string { return '<div class="collection-add-link">' . '<a class="btn btn-link" title="Ajouter un élément à la collection">' . Loading @@ -165,11 +158,7 @@ class FormElementCollection extends FormCollection '</div>'; } /** * @param Collection $container * @return string */ protected function getCss($container) protected function getCss(Collection $container): string { $fieldsetId = $container->getAttribute('id'); Loading Loading @@ -202,11 +191,7 @@ EOT; return $css; } /** * @param Collection $container * @return string */ protected function getJavascript($container) protected function getJavascript(Collection $container): string { $maxEnabled = ($container->getMaxElements()) ? 'true' : 'false'; $minEnabled = ($container->getMinElements()) ? 'true' : 'false'; Loading Loading @@ -291,24 +276,21 @@ $().ready(function updateButtons() }); } }); EOT; foreach($container->getAutocomplete() as $name => $options) { $javascript .= <<<EOT $('#{$container->getAttribute('id')}').on('keyup', '.{$container->getAttribute('id')}-autocomplete', function() { $(this).autocompleteOctopus({ source: '{$options['source']}', minLength: {$options['min-length']}, delay: {$options['delay']} }); }); EOT; } // foreach($container->getAutocomplete() as $name => $options) { // $javascript .= <<<EOT //$('#{$container->getAttribute('id')}').on('keyup', '.{$container->getAttribute('id')}-autocomplete', function() { // $(this).autocompleteOctopus({ // source: '{$options['source']}', // minLength: {$options['min-length']}, // delay: {$options['delay']} // }); //}); // // //EOT; // } return '<script type="text/javascript">' . $javascript . '</script>'; } Loading
src/UnicaenApp/Form/View/Helper/FormSearchAndSelect.php +28 −94 Original line number Diff line number Diff line <?php namespace UnicaenApp\Form\View\Helper; use UnicaenApp\Exception\LogicException; use UnicaenApp\Form\Element\SearchAndSelect; use Laminas\Form\Element\Text; use Laminas\Form\ElementInterface; use Laminas\Form\Exception\InvalidElementException; use Laminas\Form\View\Helper\FormText; use UnicaenApp\Form\Element\SearchAndSelect; /** * Aide de vue générant le code HTML de l'élément de formulaire du même nom. * * @author <bertrand.gauthier@unicaen.fr> * @see \UnicaenApp\Form\Element\SearchAndSelect * Aide de vue générant le code HTML de l'élément de formulaire {@see \UnicaenApp\Form\Element\SearchAndSelect}. */ class FormSearchAndSelect extends FormText { /** * @var SearchAndSelect */ protected $element; /** * @var string */ protected $autocompleteSource; /** * @var int */ protected $autocompleteMinLength = 2; /** * @var string */ protected $spinnerSource = "//gest.unicaen.fr/images/ajax-loader-r.gif"; protected SearchAndSelect $element; protected Text $autocompleteElement; protected ?string $autocompleteSource = null; protected int $autocompleteMinLength = 2; protected string $spinnerSource = "//gest.unicaen.fr/images/ajax-loader-r.gif"; /** * {@inheritdoc} */ public function __invoke(ElementInterface $element = null) { if ($element && !$element instanceof SearchAndSelect) { throw new InvalidElementException("L'élément spécifié n'est pas du type attendu."); if (! $element) { return $this; } $this->element = $element; return parent::__invoke($element); return $this->render($element); } /** * {@inheritdoc} */ public function render(ElementInterface $element): string { if (!$element instanceof SearchAndSelect) { Loading @@ -74,20 +49,22 @@ class FormSearchAndSelect extends FormText // 'label' => libellé affiché (ex: nom complet de la personne) $this->element->setName($name . "[$id]"); // render parent $markup = parent::render($this->element); $elementDomId = $this->element->getAttribute('id'); $autocompleteDomId = $elementDomId . '-autocomplete'; $autocomplete = new Text(); $autocomplete->setAttributes($this->element->getAttributes()) $this->autocompleteElement = new Text(); $this->autocompleteElement ->setAttributes($this->element->getAttributes()) ->setName($name . "[$label]") ->setAttribute('id', $autocompleteDomId) ->setAttribute('class', 'form-control form-control-sm') ->setValue($this->element->getValueLabel() ?: $this->element->getValue()); $markup .= $this->getView()->formText($autocomplete); $this->element->setAttribute('style', $this->element->getAttribute('style') . ' display:none;'); $markup = parent::render($this->element); $markup .= $this->view->formText($this->autocompleteElement); $markup .= <<<EOS <style> Loading @@ -100,34 +77,21 @@ class FormSearchAndSelect extends FormText </style> EOS; // $this->getView()->plugin('inlineScript')->appendScript($this->getJavascript()); $markup .= PHP_EOL . '<script>' . $this->getJavascript() . '</script>' . PHP_EOL; return $markup; } /** * * @return string * @throws LogicException */ public function getJavascript() protected function getJavascript(): string { if (!$this->element) { throw new LogicException("Aucun élément spécifié, appelez render() auparavant."); } $elementDomId = $this->element->getAttribute('id'); $autocompleteDomId = $elementDomId . '-autocomplete'; $js = <<<EOT // cache l'élément contenant l'id de la sélection $("#{$elementDomId}").css('display', 'none'); $autocompleteDomId = $this->autocompleteElement->getAttribute('id'); return <<<EOT $(function() { // jQuery UI autocomplete var autocomp = $("#{$autocompleteDomId}"); autocomp.autocompleteUnicaen({ // autocompleteUnicaen() définie dans "public/js/util.js" autocomp.autocompleteUnicaen({ // autocompleteUnicaen() définie dans "public/unicaen/app/js/unicaen.js" elementDomId: '$elementDomId', source: '{$this->getAutocompleteSource()}', minLength: {$this->getAutocompleteMinLength()}, Loading @@ -135,27 +99,15 @@ $(function() { }); }); EOT; return $js; } /** * * * @param string|array $autocompleteSource * @return SearchAndSelect */ public function setAutocompleteSource($autocompleteSource) public function setAutocompleteSource(string $autocompleteSource): self { $this->autocompleteSource = $autocompleteSource; return $this; } /** * * * @return string|array $autocompleteSource */ public function getAutocompleteSource() public function getAutocompleteSource(): string { if (null !== $this->autocompleteSource) { return $this->autocompleteSource; Loading @@ -163,41 +115,23 @@ EOT; return $this->element->getAutocompleteSource(); } /** * * @return int */ public function getAutocompleteMinLength() public function getAutocompleteMinLength(): int { return $this->autocompleteMinLength; } /** * * @param int $autocompleteMinLength * @return SearchAndSelect */ public function setAutocompleteMinLength($autocompleteMinLength) public function setAutocompleteMinLength(int $autocompleteMinLength): self { $this->autocompleteMinLength = $autocompleteMinLength; return $this; } /** * * @return string */ public function getSpinnerSource() public function getSpinnerSource(): string { return $this->spinnerSource; } /** * * @param string $spinnerSource * @return SearchAndSelect */ public function setSpinnerSource($spinnerSource) public function setSpinnerSource(string $spinnerSource): self { $this->spinnerSource = $spinnerSource; return $this; Loading