在Yii2中执行向导表单的最佳方法是什么?

时间:2017-06-19 03:21:49

标签: yii2

我有一个包含多个步骤的表单,可以像向导形式订购商品......

1)我可以通过选项卡窗格在一个视图中对其进行编码,但是如何在移动到下一个选项卡之前验证每个选项卡。

2)有人根据“actionCreate”给了我一些建议,但是在成功保存之后重定向到下一步填充步骤,但是会有额外的2-3个表和模型...但它正在工作,请参见下面的示例:

public function actionShipping($id)
{
    $model = new OrderDeliveryMethod();
    $model->order_id = $id;

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['payment', 'id' => $model->id]);
    } else {
        return $this->render('shipping', [
            'model' => $model,
        ]);
    }
}

public function actionPayment($id)
{
    $model = new OrderPaymentMethod();
    $model->order_id = $id;

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['review', 'id' => $model->id]);
    } else {
        return $this->render('payment', [
            'model' => $model,
        ]);
    }
}

public function actionReview($id)
{
    return $this->render('review', [
        'model' => $this->findModel($id),
    ]);
}

还有其他办法吗?你能举个例子吗?

2 个答案:

答案 0 :(得分:1)

您可以将所有内容存储在一个表中,在一个模型中,但将您的方案更改为step1, step2, step3..

class User extends ActiveRecord
{
    const SCENARIO_STEP1 = 'step1';
    const SCENARIO_STEP2 = 'step2';
    ...

    public function scenarios()
    {
        return [
            self::SCENARIO_STEP1 => ['attr1', 'attr2'],
            self::SCENARIO_STEP2 => ['attr3', 'attr4', 'attr5'],
        ];
    }
    ...

这样,在第一步中,您将创建一个向导模型,并设置其方案(以便验证和保存仅为步骤1选择的属性)

public function actionStep1()
{
    $model = new OrderWizard();
    $model->setScenario(OrderWizard::SCENARIO_STEP1);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['step-2', 'id' => $model->id]);
    } else {
        return $this->render('step-1', [
            'model' => $model,
        ]);
    }
}

然后在第2步中,您将获取先前创建的模型并继续填充并验证其attrubtes,例如: 公共职能actionStep1()

public function actionStep2($id)
{
    $model = $this->findModel($id);
    $model->setScenario(OrderWizard::SCENARIO_STEP2);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
    ...

..但是给定的方法(我的和你的)有一个缺点,所以如果客户端完成第一步,然后放弃序列,你的表将填充大量未完成的数据。 因此,您可以使用JS hide / show attributes逻辑在单页面中实现向导,而不是重定向到多个操作。可以使用以下方式验证单个表单字段:

$('#contact-form').yiiActiveForm('validateAttribute', 'contactform-name');

整个表格:

$('#contact-form').yiiActiveForm('validate', true);

您可以从以下链接获取更多信息:Working with ActiveForm via JavaScript

关于在每个步骤中隐藏和显示属性,我不确定是否验证了隐藏属性,但是肯定会跳过“禁用”属性。我希望你明白这一点。谢谢!

答案 1 :(得分:0)

尽管这是一个古老的问题,并且已经回答了,但是,为以后的参考,如果有人要创建表单向导,我想添加我的答案,因为我已经创建了yii2-formwizard,使用{{ 1}}和ActiveForm

突出功能

  • 您可以在所有步骤中使用单个模型。
  • 致力于每个步骤的单一模型。
  • 一个步骤即可建立多个模型。
  • 禁用/启用验证。
  • 自定义和订购表单字段。
  • 带有添加行按钮的表格步骤可动态添加字段(如地址簿)。
  • 表单持久性(保存未保存的表单,以后使用Models进行还原)。
  • 预览步骤(在最后一步中预览所有带有标签的表单输入,并在单击时导航到该步骤)。
  • 多个主题

Demos

您可以看到DEMOS及其所有可用版本。

设置

使用作曲家安装扩展程序

localstorage

或在require部分下添加到composer.json文件中

php composer.phar require buttflattery/yii2-formwizard "@dev"

示例代码

"buttflattery/yii2-formwizard":"@dev"
相关问题