Бортовой журнал Ктулху

Добавление нестандартного input в Symfony 2

Для чего все это было нужно. В Symfony была прикручена валидациячерез сторонний JS компонент который валидировал input type="digits" как integer. Я знаю что есть встроенный тип integer который дает input type="numbers" но в данном случае это не подходило.

 

Form Builder в Symfony 2 является очень гибким и имеет десятки готовых вариантов, но придет время, когда нужно будет создать свой собственный тип поля формы. Поваренная книга Symfony содержит большую статью о том, как создать пользовательский тип поля формы и использовать его в проекте.

В примере будем добавлять input type="tel" и класс будет называться TelType, файл, соответственно, TelType.php. Название файла должно совпадать с названием класса.

Создание класса типа поля формы

// Acme/Bundle/Form/Type
// или
// Acme/Bundle/Form/Extension/Type/
namespace Acme\Bundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TelType extends AbstractType
{
/**
* @author Joe Sexton <
 Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.
 >;
* @return string
*/
public function getName()
{
return 'tel';
}
/**
* @author Joe Sexton <
 Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.
 >;
* @return string
*/
public function getParent()
{
return 'text';
}
}

GetName() возвращает имя типа поля формы и GetParent () определяет родительский элемент type="text".

GetName - это создаваемый новый тип который наследуется от getParent(). 

Создание шаблона поля формы

Поскольку новое поле не сильно отличается от родительского, можно взять готовый шаблон input type="text" который находится по этому пути: Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig within the form_widget_simple block.

{# Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig #}
{% block form_widget_simple %}
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endspaceless %}
{% endblock form_widget_simple %}

Чтобы создать новый шаблон, нужно создать новый файл /Resources/views/Form/fields.html.twig с таким содержимым:

{# AcmeBundle/Resources/views/Form/fields.html.twig #}
{% block tel_widget %}
{% spaceless %}
{% set type = 'tel' %}
{{ block('form_widget_simple') }}
{% endspaceless %}
{% endblock %}

Конфигурация

В основной файл конфигурации config.xml в секции twig: добавить вызов нового шаблона:

  form:
    resources:
      'AcmeBundle:Form:fields.html.twig'

AcmeBundle/services.xml добавить:

form.type.tel:
  class: MainBundle\Form\Extension\Type\TelType
    tags:
       { name: form.type, alias: tel }

Форма

Теперь можно добавлять новый тип поля в форму и не словить exception.

{*AcmeBundle/Form/SalesType.php*}
->add('myfield', 'tel', array(

Надеюсь, ничего не упустил.