Рекомендации мастера многостраничных форм Yii

Я пытаюсь создать многостраничную форму с помощью Yii, но я новичок в PHP и Yii, и мне интересно, как лучше всего писать многостраничная форма. Пока что я планирую добавить скрытое поле с именем «шаг», которое содержит текущий шаг, на котором находится пользователь в форме (форма разбита на 3 шага / страницы). Имея это в виду, я планирую обрабатывать пользователя, нажимающего кнопки «предыдущий / следующий» в контроллере следующим образом:

public function actionCreate()
 {
  $userModel = new User;

  $data['activityModel'] = $activityModel; 
  $data['userModel'] = $userModel; 

  if (!empty($_POST['step']))
  {
   switch $_POST['step']:
    case '1':
     $this->render('create_step1', $data);
     break;

    case '2':
     $this->render('create_step2', $data);
     break;

  }else
  {
   $this->render('create_step1', $data);
  }
 }

Имеет ли смысл этот подход? Или я не в своей основе, и есть гораздо лучший и оптимизированный способ сделать это в Yii / PHP?

Спасибо!

23
задан niac 30 October 2019 в 15:28
поделиться

1 ответ

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

Я сделал (только для простая двухэтапная форма ActiveRecord) предприняла одно действие и разделила его на условные блоки на основе имени кнопки, которое Yii POST отправляет при отправке формы (примечание: не работает с отправкой ajax). Затем, в зависимости от того, какая кнопка была нажата, я визуализирую правильную форму и устанавливаю правильный сценарий для своей модели для целей проверки.

Скрытое поле «шаг», как у вас, может служить той же цели, что и проверка имени submitButton. Я бы, возможно, сохранил «шаг» в состоянии формы вместо добавления скрытого поля, но и то, и другое было бы хорошо.

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

Вот пример того, что я в основном сделал для формы ActiveRecord. Это входит в "actionCreate":

<?php if (isset($_POST['cancel'])) {
  $this->redirect(array('home'));
} elseif (isset($_POST['step2'])) {
  $this->setPageState('step1',$_POST['Model']); // save step1 into form state
  $model=new Model('step1');
  $model->attributes = $_POST['Model'];
  if($model->validate())
    $this->render('form2',array('model'=>$model));
  else {
    $this->render('form1',array('model'=>$model));
  }
} elseif (isset($_POST['finish'])) {
  $model=new Model('finish');
  $model->attributes = $this->getPageState('step1',array()); //get the info from step 1
  $model->attributes = $_POST['Model']; // then the info from step2
  if ($model->save())
    $this->redirect(array('home'));
  else {
    $this->render('form2',array('model'=>$model));
} else { // this is the default, first time (step1)
  $model=new Model('new');
  $this->render('form1',array('model'=>$model));
} ?>

Формы будут выглядеть примерно так:

Form1:

<?php $form=$this->beginWidget('CActiveForm', array(
    'enableAjaxValidation'=>false,
    'id'=>'model-form',
    'stateful'=>true,
));
<!-- form1 fields go here -->
echo CHtml::submitButton("Cancel",array('name'=>'cancel');
echo CHtml::submitButton("On to Step 2 >",array('name'=>'step2');
$this->endWidget(); ?>

Form 2:

<?php $form=$this->beginWidget('CActiveForm', array(
    'enableAjaxValidation'=>false,
    'id'=>'model-form',
    'stateful'=>true,
));
<!-- form2 fields go here -->
echo CHtml::submitButton("Back to Step 1",array('name'=>'step1');
echo CHtml::submitButton("Finish",array('name'=>'finish');
$this->endWidget(); ?>

Надеюсь, это поможет!

35
ответ дан 29 November 2019 в 02:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: