Commit 6089b063 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Mise à jour du FormControlGroup :

Refactoring (normalement : aucune incidence sur les fonctionnalités existantes)
Ajout de la possibilité de mettre des préfix et des suffix sur les champs( pour préciser un pourcentage par exemple, etc. sous forme d'InputGroup)
parent 9edb995e
Loading
Loading
Loading
Loading
+223 −64
Changes for src/UnicaenApp/Form/View/Helper/FormControlGroup.php: 223 added lines, 64 removed lines.
Original line number Diff line number Diff line
@@ -20,30 +20,48 @@ use Zend\Form\View\Helper\FormElementErrors;
 */
class FormControlGroup extends AbstractHelper
{
    /**
     * @var bool
     */
    protected $includeLabel = true;

    /**
     * @var bool
     */
    protected $includeErrors = true;

    /**
     * @var bool
     */
    protected $addClearButton = false;

    /**
     * @var string|null
     */
    protected $prefix;

    /**
     * @var string|null
     */
    protected $suffix;

    /**
     * @var string
     */
    protected $helpContent = ['before' => '', 'after' => ''];



    /**
     * Appel de l'objet comme une fonction.
     *
     * @param ElementInterface $element     Élément de formulaire
     * @param string|null      $pluginClass Plugin
     *
     * @return string|FormControlGroup
     */
    public function __invoke(ElementInterface $element = null, $pluginClass = 'formElement')
    {
        $this
            ->setHelpContent(null)
            ->setIncludeLabel(true)
            ->setIncludeErrors(true)
            ->setAddClearButton(false);

        if (null === $element) {
            return $this;
        }
@@ -51,17 +69,22 @@ class FormControlGroup extends AbstractHelper
        return $this->render($element, $pluginClass);
    }



    /**
     * Génère le code HTML.
     *
     * @param ElementInterface $element
     * @param string|null      $pluginClass
     *
     * @return string
     */
    public function render(ElementInterface $element, $pluginClass = 'formElement')
    {
        $this->normalizeElement($element);
        $this->customFromOptions($element);

        /* Bypass pour des éléments spécofiques */
        if ($element instanceof Date) {
            $helper = $this->getView()->plugin('formDate');

@@ -73,41 +96,42 @@ class FormControlGroup extends AbstractHelper
            return $helper($element);
        }

        $input = $this->inputHtml($element, $pluginClass);

        $label = $this->labelHtml($element);

        $clearButton = $this->addClearButton ?
            '<span class="input-group-btn"><button class="btn btn-default btn-xs" type="button" title="Vider" onclick="$(this).siblings(\':input\').val(null).focus();"><span class="glyphicon glyphicon-remove"></span></button></span>' :
            null;

        $helpContentBefore = null;
        if (!empty($this->helpContent['before'])) {
            $helpContentBefore = sprintf('<p class="help-block help-block-before">%s<p>', $this->helpContent['before']);
        $inputGroup = [];
        if ($this->getPrefix()){
            $inputGroup[] = $this->prefixHtml($element);
        }
        $helpContentAfter = null;
        if (!empty($this->helpContent['after'])) {
            $helpContentAfter = sprintf('<p class="help-block help-block-after">%s<p>', $this->helpContent['after']);
        $inputGroup[] = $this->inputHtml($element, $pluginClass);
        if ($this->getSuffix()){
            $inputGroup[] = $this->suffixHtml($element);
        }
        if ($this->addClearButton){
            $inputGroup[] = $this->clearButtonHtml($element);
        }

        $errors = $this->errorsHtml($element);

        $class = [];
        $class[] = $this->addClearButton ? 'input-group' : null;
        $class[] = $errors ? 'has-error' : null;
        $class = implode(' ', $class);
        $class = ['form-group'];
        if ($this->elementHasErrors($element)) $class[] = 'has-error';

        $divContent = $this->assembleDivContent($element, $label, $helpContentBefore, $input, $clearButton, $helpContentAfter, $errors);
        if (count($inputGroup) == 1){
            $input = $inputGroup[0];
        }else{
            $class[] = 'input-group';
            $input = sprintf('<div class="input-group">%s</div>',implode( '', $inputGroup) );
        }

        $html = <<<EOT
<div class="form-group $class">
    $divContent
</div>
EOT;
        $divContent =
            $this->labelHtml($element)
            . $this->helpContentBeforeHtml($element)
            . $input
            . $this->clearButtonHtml($element)
            . $this->helpContentAfterHtml($element)
            . $this->errorsHtml($element);

        return $html;
        return $this->getView()->tag('div', ['class' => $class])->html($divContent);
    }



    private function normalizeElement(ElementInterface $element)
    {
        if (!$element instanceof Button && !$element instanceof Checkbox) {
@@ -119,15 +143,42 @@ EOT;
        }
    }



    /**
     * On récupère des options de l'élément directement la customisation de l'affichage
     *
     * @param ElementInterface $element
     *
     * @return $this
     */
    private function customFromOptions(ElementInterface $element)
    {
        if ($prefix = $element->getOption('prefix')) {
            $this->setPrefix($prefix);
        }

        if ($suffix = $element->getOption('suffix')) {
            $this->setSuffix($suffix);
        }

        if ($addClearBtn = $element->getOption('add-clear-btn')) {
            $this->setAddClearButton($addClearBtn);
        }

        return $this;
    }



    private function labelHtml(ElementInterface $element)
    {
        $html = '';

        if ($this->includeLabel && $element->getLabel() && !$element instanceof Button) {
            if ($element instanceof Checkbox && !$element instanceof MultiCheckbox) {
                $html = $element->getLabel();
            }
            else {
                $html = null;
            } else {
                $helper = $this->getView()->plugin('formLabel');
                $html   = $helper($element);
            }
@@ -143,6 +194,46 @@ EOT;
        return $html;
    }



    private function prefixHtml(ElementInterface $element)
    {
        return sprintf('<span class="input-group-addon">%s</span>',$this->getPrefix() );
    }



    private function suffixHtml(ElementInterface $element)
    {
        return sprintf('<span class="input-group-addon">%s</span>',$this->getSuffix() );
    }



    private function helpContentBeforeHtml(ElementInterface $element)
    {
        $helpContentBefore = null;
        if (!empty($this->helpContent['before'])) {
            $helpContentBefore = sprintf('<p class="help-block help-block-before">%s<p>', $this->helpContent['before']);
        }

        return $helpContentBefore;
    }



    private function helpContentAfterHtml(ElementInterface $element)
    {
        $helpContentAfter = null;
        if (!empty($this->helpContent['after'])) {
            $helpContentAfter = sprintf('<p class="help-block help-block-after">%s<p>', $this->helpContent['after']);
        }

        return $helpContentAfter;
    }



    private function inputHtml(ElementInterface $element, $pluginClass = 'formElement')
    {
        if (!$pluginClass) {
@@ -167,16 +258,47 @@ EOT;

        if ($element instanceof MultiCheckbox) {
            $html = '<div class="multicheckbox">' . $html . '</div>';
        } elseif ($element instanceof Checkbox) {
            $html = sprintf('
            <div class="checkbox">
            <label>
                %s <span class="checkbox-label">%s</span>
            </label>
            </div>', $html, $element->getLabel());
        }

        return $html;
    }



    private function clearButtonHtml(ElementInterface $element)
    {
        if ($element instanceof Checkbox) { // pas de bouton de nettoyage pour une case à cocher...
            return null;
        }

        if ($this->addClearButton) {
            return '<span class="input-group-btn"><button class="btn btn-default btn-xs" type="button" title="Vider" onclick="$(this).siblings(\':input\').val(null).focus();"><span class="glyphicon glyphicon-remove"></span></button></span>';
        } else {
            return null;
        }
    }



    private function elementHasErrors(ElementInterface $element)
    {
        return $element->getMessages() && $this->getIncludeErrors();
    }



    private function errorsHtml(ElementInterface $element)
    {
        $html = '';

        if ($element->getMessages() && $this->getIncludeErrors()) {
        if ($this->elementHasErrors($element)) {
            /** @var FormElementErrors $helper */
            $helper = $this->getView()->plugin('formElementErrors');
            $html   = $helper($element, ['class' => 'error text-danger']);
@@ -185,35 +307,7 @@ EOT;
        return $html;
    }

    private function assembleDivContent(ElementInterface $element, $label, $helpContentBefore, $input, $clearButton, $helpContentAfter, $errors)
    {
        if ($element instanceof Checkbox && ! $element instanceof MultiCheckbox) {
            $clearButton = ''; // n'a pas de sens
            $html = <<<EOT
    $helpContentBefore
    <div class="checkbox">
        <label>
            $input <span class="checkbox-label">$label</span>
        </label>
    </div>
    $clearButton
    $helpContentAfter
    $errors
EOT;
        }
        else {
            $html = <<<EOT
    $label
    $helpContentBefore
    $input
    $clearButton
    $helpContentAfter
    $errors
EOT;
        }

        return $html;
    }

    /**
     * @return bool
@@ -223,6 +317,8 @@ EOT;
        return $this->includeLabel;
    }



    /**
     * @return bool
     */
@@ -231,10 +327,13 @@ EOT;
        return $this->addClearButton;
    }



    /**
     * Spécifie si le label doit être inclu ou non dans le rendu.
     *
     * @param bool $includeLabel
     *
     * @return self
     */
    public function setIncludeLabel($includeLabel)
@@ -244,6 +343,8 @@ EOT;
        return $this;
    }



    /**
     * @return boolean
     */
@@ -252,10 +353,13 @@ EOT;
        return $this->includeErrors;
    }



    /**
     * Spécifie si les erreurs de validation éventuelles doivent être inclues ou non dans le rendu.
     *
     * @param bool $includeErrors
     *
     * @return self
     */
    public function setIncludeErrors($includeErrors = true)
@@ -265,10 +369,13 @@ EOT;
        return $this;
    }



    /**
     * Active ou non la présence d'un bouton permettant d'effacer le contenu de l'élément de formulaire.
     *
     * @param bool $addClearButton
     *
     * @return self
     */
    public function setAddClearButton($addClearButton)
@@ -278,11 +385,14 @@ EOT;
        return $this;
    }



    /**
     * Spécifie le texte d'aide ou de description affiché dans un <code><p class="help-block"></code>.
     *
     * @param string $helpContent Texte d'aide
     * @param string $placement   'before' ou 'after'
     *
     * @return FormControlGroup
     */
    public function setHelpContent($helpContent, $placement = 'after')
@@ -291,4 +401,53 @@ EOT;

        return $this;
    }



    /**
     * @return string|null
     */
    public function getPrefix()
    {
        return $this->prefix;
    }



    /**
     * @param string|null $prefix
     *
     * @return FormControlGroup
     */
    public function setPrefix($prefix = null)
    {
        $this->prefix = $prefix;

        return $this;
    }



    /**
     * @return string|null
     */
    public function getSuffix()
    {
        return $this->suffix;
    }



    /**
     * @param string|null $suffix
     *
     * @return FormControlGroup
     */
    public function setSuffix($suffix = null)
    {
        $this->suffix = $suffix;

        return $this;
    }

}
 No newline at end of file