bootstrap-form icon indicating copy to clipboard operation
bootstrap-form copied to clipboard

Customizing form-groups

Open tmaly1980 opened this issue 7 years ago • 2 comments

It would be nice if I could pass a parameter to my input fields to add an additional class to the form-group wrappers, such as styling multiple columns (this IS bootstrap, afterall), like so:

<div class='row'>
{!! BootstrapForm::text('first_name','First Name','James',['div'=>'col-md-6']) !!}
{!! BootstrapForm::text('last_name','Last Name','Doohan',['div'=>'col-md-6']) !!}
</div>

'div' would take an array, but if it's a string, assume we are assigning to the 'class' attribute. GetFormGroupOptions supports passing $options as a 2nd parameter, but it's not used anywhere! I'd suggest that 'class' be appended to rather than overwritten. Always add form-group along with whatever classes they want.

tmaly1980 avatar Oct 07 '16 21:10 tmaly1980

This is what I came up with. I didn't fork a version because I want to keep the composer dependency to your updates while still keeping my changes (in a child class):

    protected function getFormGroupWithLabel($name, $value, $element,$divoptions=[])
    {
        if(is_string($divoptions)) { $divoptions = ['class'=>$divoptions]; } # Convert string to class
        $options = $this->getFormGroupOptions($name,$divoptions); 

        return '<div' . $this->html->attributes($options) . '>' . $this->label($name, $value) . $element . '</div>';
    }

    protected function getFormGroupOptions($name = null, array $options = [])
    {
        $class = 'form-group';

        if ($name) {
            $class .= ' ' . $this->getFieldErrorClass($name);
        }

        if(!empty($options['class']))
        {
            $class .= " ".$options['class']; # Append, not overwrite
            unset($options['class']);
        }

        return array_merge(['class' => $class], $options);
    }

    #######################

    public function input($type, $name, $label = null, $value = null, array $options = [])
    {
        $label = $this->getLabelTitle($label, $name);

        $options = $this->getFieldOptions($options, $name);
        $inputElement = $type === 'password' ? $this->form->password($name, $options) : $this->form->{$type}($name, $value, $options);

        $wrapperOptions = $this->isHorizontal() ? ['class' => $this->getRightColumnClass()] : [];
        $wrapperElement = '<div' . $this->html->attributes($wrapperOptions) . '>' . $inputElement . $this->getFieldError($name) . $this->getHelpText($name, $options) . '</div>';

        return $this->getFormGroupWithLabel($name, $label, $wrapperElement, !empty($options['div'])?$options['div']:[]); 
    }

    public function select($name, $label = null, $list = [], $selected = null, array $options = [])
    {
        $label = $this->getLabelTitle($label, $name);

        $options = $this->getFieldOptions($options, $name);
        $inputElement = $this->form->select($name, $list, $selected, $options);

        $wrapperOptions = $this->isHorizontal() ? ['class' => $this->getRightColumnClass()] : [];
        $wrapperElement = '<div' . $this->html->attributes($wrapperOptions) . '>' . $inputElement . $this->getFieldError($name) . $this->getHelpText($name, $options) . '</div>';

        return $this->getFormGroupWithLabel($name, $label, $wrapperElement, !empty($options['div'])?$options['div']:[]);
    }

    public function checkbox($name, $label = null, $value = 1, $checked = null, array $options = [])
    {
        $inputElement = $this->checkboxElement($name, $label, $value, $checked, false, $options);

        $wrapperOptions = $this->isHorizontal() ? ['class' => implode(' ', [$this->getLeftColumnOffsetClass(), $this->getRightColumnClass()])] : [];
        $wrapperElement = '<div' . $this->html->attributes($wrapperOptions) . '>' . $inputElement . '</div>';

        return $this->getFormGroup(null, $wrapperElement, !empty($options['div'])?$options['div']:[]);
    }

    public function radio($name, $label = null, $value = null, $checked = null, array $options = [])
    {
        $inputElement = $this->radioElement($name, $label, $value, $checked, false, $options);

        $wrapperOptions = $this->isHorizontal() ? ['class' => implode(' ', [$this->getLeftColumnOffsetClass(), $this->getRightColumnClass()])] : [];
        $wrapperElement = '<div' . $this->html->attributes($wrapperOptions) . '>' . $inputElement . '</div>';

        return $this->getFormGroup(null, $wrapperElement, !empty($options['div'])?$options['div']:[]);
    }

tmaly1980 avatar Oct 07 '16 21:10 tmaly1980

Hey, thanks for taking the time to put this together.

I understand there can be a need to customise different parts of the "form-group" and this library doesn't expose great control over them, but I'm not sure this is the direction I'd want to go. Introducing another options array makes it harder to see what's going on, and appending to class names when the rest of the library overrides them would just be confusing for develops.

I know this isn't the answer you're after and I apologise. To be honest, this package is long overdue for a complete overhaul and I just haven't had time to do it. I still try to maintain it whenever I can but I'm hesitant to continue development in it's current state. I would encourage you to fork (or just override in your own app) to get the package working the way you need.

Again, thanks for putting this together and I'm sorry for the delay in responding. I'll keep this ticket open as a feature to consider if there ever becomes a major new version.

dwightwatson avatar Oct 11 '16 10:10 dwightwatson