Софтплюс

Вы здесь

Symfony - веб-формы без перезагрузки

Работа с веб-формами является одним из наиболее распространенных и сложных задач для веб-разработчиков. В Symfony интегрирован компонент для разработки формам, который позволяет легко и просто создавать веб-формы. В этой статье мы будем строить простую веб-форму с нуля, изучая наиболее важные особенности форм.

Построение простейшей формы в symfony

1. Процесс построение формы начинается с класса-сущности формы. Данный класс необходим для хранения данных, отправляемых с помощью веб-формы. Более подробную информацию о сущностях вы можете найти в официальной документации.

namespace AppBundle\Entity;

class Contact{
   protected $name;
   protected $phone;
   protected $location;

   public function getName() {
      return $this->name;
   }
   public function setName($name) {
      $this->name = $name;
   }
   public function getPhone() {
      return $this->phone;
   }
   public function setPhone($phone) {
      $this->phone = $phone;
   }
   public function getLocation() {
      return $this->location;
   }
   public function setLocation($location) {
      $this->location = $location;
   }
}

2. Далее, необходимо создать класс формы, в котором будет логика построения самой формы.

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class ContactType extends AbstractType {
   public function buildForm(FormBuilderInterface $builder, array $options) {
      $builder
         ->add('name')
         ->add('phone')
         ->add('location')
         ->add('save', SubmitType::class)
      ;
   }
}

3. После того, как мы создали все необходимые компоненты для создания веб-формы, можем производить ее сборку в контроллере.

namespace AppBundle\Сontroller;

use AppBundle\Form\ContactType;
use AppBundle\Entity\Contact;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class ContactsController extends Controller {
   public function newAction(Request $request) {
      $entity = new Contact();
      $form = $this->createForm(ContactType::class, $entity);
      $form->handleRequest($request);
      if($form->isValid()) {
          // persist
      }
      return $this->render('contacts/new.html.twig', array('form'=>$form->createView()));
   }
}

После того, как мы создали контроллер формы, получаем рабочую веб-форму.

Отправка веб-форм по технологии AJAX

Теперь, когда форма работает, данные отправляются с перезагрузкой страницы, нам необходимо научить форму отправлять данные без перезагрузки страницы.

1. Создаем обработчик формы с помощью javascript.

(function ($) {
   $(document).on('submit', 'form.contact', function (e) {
      e.preventDefault();
      $.ajax({
         url: window.location.href,
         processData: false,
         type: 'GET',
         contentType: 'application/x-www-form-urlencoded',
         data: function () {
            $('form.contact).serialize();
         },
         success: function ( data ) {
            $('form.contact').html(data);
         }
      });
   });
})(jQuery);

Данный обработчик подключается к событию отправки веб-формы, отменяет действие браузера на событие submit и отправляет данные формы по технологии AJAX.

2. Теперь веб-форма имеет возможность отправки без перезагрузки, но не имеет правильного ререндера. Для того, чтобы сервер нам ответ на наш запрос не присылал целую страницу, а только код формы нужно в контроллере добавить логику, определяющая, каким способом была отправлена веб-форма.

namespace AppBundle\Сontroller;

use AppBundle\Form\ContactType;
use AppBundle\Entity\Contact;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class ContactsController extends Controller {
   public function newAction(Request $request) {
      $entity = new Contact();
      $form = $this->createForm(ContactType::class, $entity);
      $form->handleRequest($request);
      if($form->isValid()) {
          // persist
      }
      $template = 'contacts/new.html.twig;
      if(strstr($request->headers->get('content-type'),'application/x-www-form-urlencoded')) {
         $template = 'contacts/form.html.twig';
      }
      return $this->render($template, array('form'=>$form->createView()));
   }
}

В случае, когда веб-форма отправляются по технологии AJAX, в заголовках запроса будет присутствовать строка application/x-www-form-urlencoded, именно по ней мы будем идентифицировать, каким способом отправлена форма.
В случае, если форма отправлена с помощью AJAX, то ответ от сервера будет содержать только html код формы, во всех остальных случаях будет загружаться страница целиком.

Данный способ разработки веб-форм является наиболее правильным, т.к. не нарушается работа формы с отключенным javascript, а также используется единая логика валидации формы на стороне сервера.