Skip to content

Reusable form types

wfForm JavaScript plugin

Enabling the wfForm plugin

Most of these types require JavaScript code. To wire these inputs in JavaScript, include wfca/form/plugin as a dependency. Once you have a reference to the jQuery form object, wire the fields using $form.wfForm():

javascript
define(['jquery', 'wfca/form/plugin'], ($, wfForm) => {
  // obtain a reference to the form object as a jQuery collection
  // e.g.: const $form = $('.my-awesome-form')
  $form.wfForm();
})

wfForm Special types

Besides the PHP types mentioned below, wfForm JavaScript plugin also supports the following special types - configurable via HTML attributes

v7.1+wfForm for-field type

Shows/hides the current form field depending on the value of another input value. Add this to a row_attr.class.

Example:

php
<?php

$builder->add('contentType', ChoiceType::class, [
    'choices' => [
        'Article' => 'article',
        'Gallery' => 'gallery',
        'Video' => 'video',
    ]
);

// show this field only for `article` content types
$builder->add('status', ChoiceType::class, [
    'choices' => [
        'Draft' => 'draft',
        'Published' => 'published',
    ],
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'contentType:article',
    ]
);

// show this field only for `article` content types, when `published` status is selected
$builder->add('publishedAt', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'contentType:article;status:published',
    ]
);

// show this field only for `gallery` and `video` content types
$builder->add('createdAt', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'contentType:gallery,video',
    ]
);

Example: Show some elements depending on whether a single (toggle) checkbox is checked

php
<?php

$builder->add('toggleField', CheckboxType::class);

$builder->add('onlyWhenChecked', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'toggleField:1',
    ]
);

$builder->add('onlyWhenUnchecked', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'toggleField:0',
    ]
);

Example: Show some elements depending on whether some choices (multiple checkboxes) are checked

php
<?php

$builder->add('choicesField', ChoiceType::class, [
    'choices' => [
        'Option A' => 'a',
        'Option B' => 'b',
        'Option C' => 'c',
    ],
    'multiple' => true,
    'expanded' => true,
]);

$builder->add('onlyWhenAIsChecked', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'choicesField:a',
    ]
);

$builder->add('onlyWhenAAndBAreChecked', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'choicesField:a,b',
    ]
);

$builder->add('onlyWhenNoCheckboxIsChecked', DateType::class, [
    'row_attr' => [
        'data-wf-form-type' => 'for-field',
        'data-wf-for-field' => 'choicesField:',
    ]
);

v7.1+ArticleStatusType

Displays a dropdown with a list of available article statuses (default/published/verified).

php
<?php
    // single category
    $form->add('template', Wf\Bundle\CmsBaseAdminBundle\Form\Type\ArticleStatusType::class, [
        'required' => false,
    ]);

v7.1+ArticleTypesType

Displays a dropdown with a list of available article templates.

php
<?php
    // single category
    $form->add('template', Wf\Bundle\CmsBaseAdminBundle\Form\Type\ArticleTypesType::class, [
        'required' => false,
    ]);

CategoryType

Allows adding one or more categories (pass "multiple" = true option to it).

php
<?php
    // single category
    $form->add('category', Wf\Bundle\CmsBaseAdminBundle\Form\Type\CategoryType::class, [
        'required' => false,
    ]);
    
    // multiple categories
    $form->add('category', Wf\Bundle\CmsBaseAdminBundle\Form\Type\CategoryType::class, [
        'required' => false,
        'multiple' => true
    ]);

v7.1+DateRangeType

Displays two date inputs, allowing to select a range of dates (from/until).

php
<?php
    $form->add('createdAt', Wf\Bundle\CmsBaseAdminBundle\Form\Type\DateRangeType::class, [
        'required' => false,
        'label' => 'form.search.group.created_at', // the label for the whole group
        'label_from' => 'form.search.created_at.from', // the label for the "from" field
        'label_until' => 'form.search.created_at.until', // the label for the "until" field
    ]);

ImageContentTypeType

Allows selecting one of the already uploaded images or uploading a new one:

php
<?php
    $form->add('main_image', Wf\Bundle\CmsBaseAdminBundle\Form\Type\ImageContentTypeType::class, [
        'required' => false,
    ]);

TagType

Allows selecting an already added tag or adding a new one:

php
<?php
    // allow choosing a single tag
    $form->add('supratitle', Wf\Bundle\CmsBaseAdminBundle\Form\Type\TagType::class, [
        'required' => false,
        'multiple' => false,
    ]);
    
    // allow choosing multiple tags
    $form->add('supratitle', Wf\Bundle\CmsBaseAdminBundle\Form\Type\TagType::class, [
        'required' => false,
        'multiple' => true,
    ]);

v7.2 Taxonomies support, multiple tags

Starting with v7.2, the TagType implements support for working with taxonomies.

php
<?php

class PageArticle 
{
    /**
     * @ORM\ManyToMany(targetEntity="Tag", cascade={"persist"})
     *
     * @ORM\JoinTable(name="page_author_tag",
     *      joinColumns={@ORM\JoinColumn(name="page_id", onDelete="CASCADE", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
     * )
     *
     * @Serializer\SerializedName("authors_tags")
     *
     * @Serializer\Groups({"edit", "list", "version", "api"})
     */
    protected $authorsTags;

    public function getAuthorsTags()
    {
        return $this->collectionGet('authorsTags');
    }

    public function setAuthorsTags($authorsTags): void
    {
        $this->collectionSet('authorsTags', $authorsTags);
    }
}
  • Use the TagType form type:
php
<?php

class PageArticleFormTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('authorsTags', TagType::class, [
            TagType::OPTION_TAG_TYPE_SLUG => 'authors',
            'multiple' => true,
            'attr' => [
                'data-bind' => 'arrayValue:authorsTags',
            ],
        ]);
    }
}

Note: The above example applies to articles - hence the data-bind attribute. For other form types it's not necessary to specify this attribute.

Note: The above example uses the arrayValue binding handler, while most of the other form types use value. This is important, without it, you won't be able to save articles.

v7.2 Taxonomies support, single tag

The main difference compared to multiple tags come when declaring the relating entity's property/getter/setters:

php
<?php

class PageArticle 
{
    /**
     * @ORM\ManyToOne(targetEntity="Tag", cascade={"persist"})
     *
     * @ORM\JoinColumn(name="main_tag_id", referencedColumnName="id", onDelete="SET NULL", nullable=true)
     *
     * @Serializer\SerializedName("editorial_tag")
     *
     * @Serializer\Groups({"edit", "list", "version", "api"})
     */
    protected $editorialTag;

    public function getEditorialTag()
    {
        return $this->editorialTag;
    }

    public function setEditorialTag($editorialTag): void
    {
        $this->editorialTag = $editorialTag;
    }
}

Note: There's no need for an additional join table, since this is a many-to-one relationship, a join column is enough.

Note: The getter and setters are more straight forward compared to the multiple ones - since they work with a single value, not a collection of values.

The other change compared to the multiple version is, of course, changing the multiple=true value to false when adding the form type. And just like the entity's getter/setter, this one works with the value binding handler, since it handles a single value and not an array of values.

php
<?php

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Wf\Bundle\CmsBaseAdminBundle\Form\Type\TagType;

class PageArticleFormTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('editorialTag', TagType::class, [
            TagType::OPTION_TAG_TYPE_SLUG => 'editorial',
            'multiple' => false,
            'attr' => [
                'data-bind' => 'value:editorialTag',
            ],
        ]);
    }
}

allowClearing the single value

It might be a good idea to allow clearing the single value - otherwise, once the editor chooses one, there's no way they can remove it.

For this, use the Select2InlineType:JS_CONFIG_OPTION:

php
<?php

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Wf\Bundle\CmsBaseAdminBundle\Form\Type\TagType;
use Wf\Bundle\CmsBaseAdminBundle\Form\Type\Select2InlineType;

class PageArticleFormTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('editorialTag', TagType::class, [
            TagType::OPTION_TAG_TYPE_SLUG => 'editorial',
            'multiple' => false,
            Select2InlineType::JS_CONFIG_OPTION => [
                'allowClear' => true,
                'placeholder' => 'Select editorial',
            ],
            'attr' => [
                'data-bind' => 'value:editorialTag',
            ],
        ]);
    }
}

Note: Inside the Select2InlineType::JS_CONFIG_OPTION you can pass whatever options that select2 accepts.

Note: allowClear works only if there's a placeholder - like in the example above 😃

UserType

Allows adding one or more users (pass "multiple" = true option to it).