Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Fieldset type #701

Open
valentinoeval opened this issue Dec 7, 2022 · 3 comments
Open

Add Fieldset type #701

valentinoeval opened this issue Dec 7, 2022 · 3 comments
Labels

Comments

@valentinoeval
Copy link

valentinoeval commented Dec 7, 2022

I need to create < fieldset > element into form with associated fields list like subform

@rudiedirkx
Copy link
Collaborator

You can do that in your view, using the global form functions like form_start, form_row, etc. See helpers.php.

There are several other issues where we decided not to create a fieldset field.

@rudiedirkx rudiedirkx pinned this issue Dec 7, 2022
@rudiedirkx
Copy link
Collaborator

Mainly #582

@valentinoeval
Copy link
Author

valentinoeval commented Dec 9, 2022

Fieldset is a form element who deserves to have his own element.
For those who would absolutely like to generate this element here is my class

  • FieldsetType.php :
<?php

namespace App\Forms\Fields;

use Kris\LaravelFormBuilder\Events\AfterFieldCreation;
use Kris\LaravelFormBuilder\Fields\FormField;
use Kris\LaravelFormBuilder\Form;

/**
 * Generate <fieldset> element to build inputs block
 *
 * @author Valentin GOLLIOT
 * @since 2022-12-08
 */
class FieldsetType extends FormField
{
    /**
     * All fields that are added.
     *
     * @var array
     */
    protected $fields = [];

    /**
     * Wether the fieldset is beign rebuild.
     *
     * @var bool
     */
    protected $rebuilding = false;

    /**
     * Form specific configuration.
     *
     * @var array
     */
    protected $fieldsetConfig = [];

    /**
     * @var string
     */
    protected $templatePrefix;

    /**
     * @var array
     */
    protected $defaultOptions = [];

    /**
     * Get template from options if provided, otherwise fallback to config.
     *
     * @return mixed
     */
    protected function getTemplate()
    {
        return $this->getTemplatePrefix() . $this->getConfig('fieldset');
    }

    /**
     * @param string $name
     * @param string $type
     * @param Form $parent
     * @param array $options
     */
    public function __construct($name, $type, Form $parent, array $options = [])
    {
        $optionsMerged = array_merge_recursive($this->defaultOptions, $options);

        parent::__construct($name, $type, $parent, $optionsMerged);
    }

    /**
     * Create a new field and add it to the form.
     *
     * @param string $name
     * @param string $type
     * @param array  $options
     * @param bool   $modify
     * @return $this
     */
    public function add($name, $type = 'text', array $options = [], $modify = false)
    {
        $this->formHelper->checkFieldName($name, get_class($this));

        if ($this->rebuilding && !$this->has($name)) {
            return $this;
        }

        $this->addField($this->makeField($name, $type, $options), $modify);

        return $this;
    }

    /**
     * Check if fieldset has field.
     *
     * @param string $name
     * @return bool
     */
    public function has($name)
    {
        return array_key_exists($name, $this->fields);
    }

    /**
     * Render the fieldset.
     *
     * @param array $options
     * @param bool  $showLabel
     * @param bool  $showField
     * @param bool  $showError
     * @return string
     */
    public function render(array $options = [], $showLabel = true, $showField = true, $showError = true)
    {
        $fieldsetTitle = (isset($this->options['title'])) ? $this->options['title'] : '';

        return $this->formHelper->getView()
            ->make($this->getTemplate())
            ->with('fields', $this->fields)
            ->with('fieldsetTitle', $fieldsetTitle)
            ->with('fieldsetName', $this->options['label'])
            ->render();
    }

    /**
     * Get template prefix that is prepended to all template paths.
     *
     * @return string
     */
    public function getTemplatePrefix()
    {
        return $this->getConfig('template_prefix');
    }

    /**
     * Get the passed config key using the custom
     * fieldset config, if any.
     *
     * @param string $key
     * @param mixed $default
     *
     * @return mixed
     */
    public function getConfig($key = null, $default = null)
    {
        return $this->formHelper->getConfig($key, $default, $this->fieldsetConfig);
    }

    /**
     * Add a FormField to the form's fields.
     *
     * @param FormField $field
     * @return $this
     */
    protected function addField(FormField $field, $modify = false)
    {
        $this->fields[$field->getRealName()] = $field;

        return $this;
    }

    /**
     * Create the FormField object.
     *
     * @param string $name
     * @param string $type
     * @param array  $options
     * @return FormField
     */
    protected function makeField($name, $type = 'text', array $options = [])
    {
        $this->setupFieldOptions($name, $options);

        $fieldName = $this->getFieldName($name);
        $fieldType = $this->getFieldType($type);

        return new $fieldType($fieldName, $type, $this->parent, $options);
    }

    /**
     * Set up options on single field depending on form options.
     *
     * @param string $name
     * @param $options
     */
    protected function setupFieldOptions($name, &$options)
    {
        $options['real_name'] = $name;
    }

    /**
     * If form is named form, modify names to be contained in single key (parent[child_field_name]).
     *
     * @param string $name
     * @return string
     */
    protected function getFieldName($name)
    {
        $formName = $this->getName();
        if ($formName !== null) {
            if (strpos($formName, '[') !== false || strpos($formName, ']') !== false) {
                return $this->formHelper->transformToBracketSyntax(
                    $this->formHelper->transformToDotSyntax(
                        $formName . '[' . $name . ']'
                    )
                );
            }

            return $formName . '[' . $name . ']';
        }

        return $name;
    }

    /**
     * Returns and checks the type of the field.
     *
     * @param string $type
     * @return string
     */
    protected function getFieldType($type)
    {
        $fieldType = $this->formHelper->getFieldType($type);

        return $fieldType;
    }
}
  • config/laravel-form-builder.php :
...
'fieldset'      => 'laravel-form-builder::fieldset',
'custom_fields' => [
    'fieldset' => \App\Forms\Fields\FieldsetType::class,
],
...
  • resources/views/vendor/laravel-form-builder/fieldset.php :
<div class="col-3">
    <div class="card shadow">
        <?php if ($fieldsetTitle) : ?>
            <div class="card-header">
                <h5 class="card-title">
                    <?php echo __($fieldsetTitle) ?>
                    <i class="fa fa-chevron-up chervron-margin show-hide-card"
                       data-bs-toggle="collapse"
                       data-bs-target="#fieldset-<?php echo $fieldsetName ?>"
                       aria-expanded="true"
                       aria-controls="#fieldset-<?php echo $fieldsetName ?>"
                    ></i>
                </h5>
            </div>
        <?php endif; ?>
        <div id="fieldset-<?php echo $fieldsetName ?>" class="card-body collapse show">
            <?php foreach ($fields as $field): ?>
                <?php echo $field->render() ?>
            <?php endforeach; ?>
        </div>
    </div>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants