Как создать тип формы Symfony для тегов с select2 v4
Я пытаюсь обновить уже созданный тип формы (TagsType
) от выбора 2 v3 до v4. Но я обнаружил проблему, заключающуюся в том, что новое select2 использует select вместо текстового поля. Следующий код прекрасно работает с v3.
class TagsType extends AbstractType
{
/**
* @inheritdoc
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addViewTransformer(new StringToArrayTransformer());
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$attr = isset($view->vars['attr']) ? $view->vars['attr'] : [];
$view->vars['attr'] = array_merge($attr, ['data-toggle' => 'tags']);
}
/**
* @inheritdoc
*/
public function getParent()
{
return 'text';
}
/**
* @inheritdoc
*/
public function getName()
{
return 'tags';
}
}
StringToArrayTransformer:
class StringToArrayTransformer implements DataTransformerInterface
{
/**
* @inheritdoc
*/
public function transform($value)
{
if (!$value ) {
return [];
}
if (!is_array($value)) {
throw new TransformationFailedException('Expected a Array.');
}
return implode(',', $value);
}
/**
* @inheritdoc
*/
public function reverseTransform($value)
{
if (null === $value) {
return [];
}
if (!is_string($value)) {
throw new TransformationFailedException('Expected a String.');
}
return explode(',', $value);
}
}
Приведенный выше код отлично работает с сущностью с полем типа simple_array
(разделенные запятой). Мне нужно сделать то же самое, но с использованием новой версии select2.
Рефакторинг:
class TagsType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$attr = isset($view->vars['attr']) ? $view->vars['attr'] : [];
$view->vars['attr'] = array_merge($attr, ['data-toggle' => 'tags']);
}
/**
* @inheritdoc
*/
public function getParent()
{
return 'choice';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['multiple' => true]);
}
/**
* @inheritdoc
*/
public function getName()
{
return 'tags';
}
}
Рефакторинг генерирует тег select с несколькими, но пустыми. А когда попробуем добавить какую-то опцию (Tag
) проверка не проходит, потому что динамическое создание новых опций в select.
Мои вопросы:
- Как реализовать выбор с динамическими опциями в symfony?
- Как установить выбор по умолчанию из данных поля (массива)
1 ответ
Забудьте все о ',' и преобразуйте строку в массив или наоборот и сохраните каждую сущность Tag по отдельности.
Таким образом, чтобы сделать вашу форму совместимой с select2-v4.x, вам нужно одно поле EntityType с атрибутом "множественный", установленным в значение "ИСТИНА".
Каждая вещь обрабатывается Symfony, каждая опция (и) в теге select вашей формы связана с ее сущностью.
Я только что нашел это решение, и оно работает для меня, но я не знаю, может быть, некоторые вещи отсутствуют...
Очень старый вопрос, но я нашел его из поисковой системы. Я попытался сделать это с помощью преобразователя данных simple_array + - это неправильный путь (как сказал @YaserKH). Лучше сделать теги как Entity Tag и т. Д. (Вы можете найти в официальных документах). Но если вам нужно простое решение по каким-то причинам (как я):
- Создать столбец типа Text в базе данных (не simple_array)
- Определите его как HiddenType в конструкторе форм:
$builder->add('tagsForSearch', HiddenType::class, [ 'required' => false ])
- Сделайте веточку вроде:
{{ form_row(form.tagsForSearch) }}
<select id="tags" multiple="multiple">
{% for tag in form.tagsForSearch.vars.value|split(',')|default %}
<option value="{{ tag|raw }}" selected="selected">{{ tag|raw }}</option>
{% endfor %}
</select>
- И сценарий:
$('#tags').select2({
tags: true
});
$('#form').submit(function () {
var tags = $('#tags').select2().val().join(',');
$('#{{ form.tags.vars.id }}').val(tags);
});