介绍 入门 应用结构 请求处理 关键概念 配合数据库工作 接收用户数据 显示数据 安全 缓存 RESTfulWeb服务 开发工具 测试 高级专题 小部件 助手类 其他

发布于 2015-08-01 11:32:35 | 239 次阅读 | 评论: 0 | 来源: 网络整理

Sometimes you need to handle multiple models of the same kind in a single form. For example, multiple settings, where each setting is stored as a name-value pair and is represented by a Setting active record model. This kind of form is also often referred to as "tabular input". In contrast to this, handling different models of different kind, is handled in the section Complex Forms with Multiple Models.

The following shows how to implement tabular input with Yii.

There are three different situations to cover, which have to be handled slightly different:

  • Updating a fixed set of records from the database
  • Creating a dynamic set of new records
  • Updating, creating and deleting of records on one page

In contrast to the single model forms explained before, we are working with an array of models now. This array is passed to the view to display the input fields for each model in a table like style and we will use helper methods of yiibaseModel that allow loading and validating multiple models at once:

  • yiibaseModel::loadMultiple() load post data into an array of models.
  • yiibaseModel::validateMultiple() validates an array of models.

Updating a fixed set of records

Let's start with the controller action:

<?php

namespace appcontrollers;

use Yii;
use yiibaseModel;
use yiiwebController;
use appmodelsSetting;

class SettingsController extends Controller
{
    // ...

    public function actionUpdate()
    {
        $settings = Setting::find()->indexBy('id')->all();

        if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) {
            foreach ($settings as $setting) {
                $setting->save(false);
            }
            return $this->redirect('index');
        }

        return $this->render('update', ['settings' => $settings]);
    }
}

In the code above we're using yiidbActiveQuery::indexBy() when retrieving models from the database to populate an array indexed by models primary keys. These will be later used to identify form fields. yiibaseModel::loadMultiple() fills multiple models with the form data coming from POST and yiibaseModel::validateMultiple() validates all models at once. As we have validated our models before, using validateMultiple(), we're now passing false as a parameter to yiidbActiveRecord::save() to not run validation twice.

Now the form that's in update view:

<?php
use yiihelpersHtml;
use yiiwidgetsActiveForm;

$form = ActiveForm::begin();

foreach ($settings as $index => $setting) {
    echo $form->field($setting, "[$index]value")->label($setting->name);
}

ActiveForm::end();

Here for each setting we are rendering name and an input with a value. It is important to add a proper index to input name since that is how yiibaseModel::loadMultiple() determines which model to fill with which values.

Creating a dynamic set of new records

Creating new records is similar to updating, except the part, where we instantiate the models:

public function actionCreate()
{
    $count = count(Yii::$app->request->post('Setting', []));
    $settings = [new Setting()];
    for($i = 1; $i < $count; $i++) {
        $settings[] = new Setting();
    }

    // ...
}

Here we create an initial $settings array containing one model by default so that always at least one text field will be visible in the view. Additionally we add more models for each line of input we may have received.

In the view you can use javascript to add new input lines dynamically.

Combining Update, Create and Delete on one page

Note: This section is under development.

It has no content yet.

TBD

最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务