как разделить длинную форму symfony на несколько страниц?

Я хочу создать форму для сущности, которая имеет множество атрибутов. Чтобы упростить ввод данных, я хочу разделить эту форму на несколько страниц (например, на 2 или 3 страницы). Возьмем пример объекта объявления:

  1. На странице 1 пользователь вводит текст объявления
  2. На странице 2 пользователь введет свой контакт
  3. На странице 3 пользователь указывает (X,Y) позицию объявления.

Это разделение потребует сохранения доступных данных (вставка в базу данных) на 1-й странице перед переходом на следующую страницу. К сожалению, это невозможно из-за ограничений.

Вопрос в следующем: есть ли какие-либо документы или примеры, решающие эту проблему?

Если документация отсутствует, как вы думаете, лучше ли разделить мой объект на n объектов, чтобы иметь один объект на странице?

Спасибо за помощь.


person Amine Jallouli    schedule 21.01.2014    source источник


Ответы (3)


Вероятно, вам следует использовать CraueFormFlowBundle. Он предоставляет средства для построения многошаговых форм.

Вы можете создать один тип формы для всего потока или один тип формы для каждого шага.

Это очень легко настроить. Все объясняется здесь.

person Picoss    schedule 21.01.2014
comment
Большое спасибо. Кажется, отличное решение! :) - person Amine Jallouli; 22.01.2014
comment
Абсолютно идеально! Спасибо еще раз! - person Amine Jallouli; 22.01.2014
comment
Я сомневаюсь, что Bundle может быть отличным решением. Лично я часто предпочитаю кодирование как хорошее решение. - person Pmpr; 12.01.2017
comment
Плохое решение, все еще есть проблема с отображаемыми => ложными полями. - person anyapps; 08.07.2021

Вам не нужно разделять свою сущность, но вашу форму: создайте 3 формы, каждая из которых содержит свойство, необходимое для рекламной сущности.

Вам нужно:

  • сохранять (а не сбрасывать) объект $ad на каждом этапе внутри вашего контроллера
  • передать объект $ad в качестве аргумента при пересылке внутри вашего контроллера
  • сбросить объект $ad на последнем шаге

В псевдокоде ваш контроллер будет выглядеть так:

public function newAdStep1() {
    new Ad() // New instance of $ad
    new formStep1($ad) // The first form containing only the ad text field

    // The form was filled, manage it...
    form->isValid()? {
        persist($ad); // Persist the first part of your ad object
        forward(newAdStep2, $ad) // Go on to step 2, your $ad object as an argument
    }

    // ... or display step1 to user
    createView createAdStep1.html.twig('form' => $form);
}

public function newAdStep2($ad) {
    new formStep2($ad); // Now the second form, containing the "contact" fields
    isValid ? {
        persist($ad)
        forward(newAdStep3, $ad)
    }
    createView createAdStep2($form, $ad); // Your $ad object needs to be sent to the view
}

public function newAdStep3($ad) {
    new formStep3($ad); // Third and last form, containing the (X,Y) fields
    isValid ? {
        $em->persist($ad);
        $em->flush(); // Your instance of $ad can be stored in database now
        return('success !');
    }
    return view createAdStep3($form, $ad);
}
person np87    schedule 21.01.2014
comment
Большое спасибо. Я должен попробовать ваше решение. Меня немного беспокоит функция isValid(). - person Amine Jallouli; 22.01.2014
comment
Я попробовал, и isValid возвращает true после createForm, поэтому это решение может оказаться нежизнеспособным. Тем не менее, концепция использования форвардов довольно изящна. - person crafter; 17.11.2014
comment
Было бы полезно, если бы вы пересмотрели свой фрагмент кода и заменили его реальным кодом. - person Pmpr; 20.01.2017
comment
Можете ли вы проверить свой код, пожалуйста? Я попробовал ваше решение с Symfony3, но сброс не работает на последнем шаге. Можете ли вы помочь мне здесь: stackoverflow.com/questions/47650477/ - person Eve; 05.12.2017
comment
А что, если после, скажем, первого шага пользователь закроет браузер? - person ; 30.03.2018

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

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

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

person antony    schedule 21.01.2014
comment
Сессия не является хорошим местом и приведет к злоупотреблению сессией. Я бы использовал кеш. - person Eddie Jaoude; 17.06.2015