alexs / yii2-tabularload
为Yii2框架提供表格输入功能的简单扩展。
1.1.0
2021-10-09 22:05 UTC
Requires
- php: >=7.1
- yiisoft/yii2: ^2.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-10 06:43:25 UTC
README
为Yii2框架中具有表格输入的复杂表单提供简单特质。
当我们有一个创建/更新表单,其中包含一个多对一的关系,例如主表单添加国家,并且它内部有许多相关城市时,这样做是有意义的,以便快速输入。
SQL
CREATE TABLE `country` (
`id` int(4) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`population` int(4) DEFAULT NULL
) ENGINE=InnoDB;
CREATE TABLE `city` (
`id` int(4) NOT NULL,
`country_id` int(4) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`is_capital` tinyint(1) DEFAULT '0',
`foundation` int(4) DEFAULT NULL,
`image` varchar(255) DEFAULT NULL
) ENGINE=InnoDB;
ALTER TABLE `country`
ADD PRIMARY KEY (`id`);
ALTER TABLE `city`
ADD PRIMARY KEY (`id`),
ADD KEY `fk-city-country_id` (`country_id`);
ALTER TABLE `country`
MODIFY `id` int(4) NOT NULL AUTO_INCREMENT;
ALTER TABLE `city`
MODIFY `id` int(4) NOT NULL AUTO_INCREMENT;
ALTER TABLE `city`
ADD CONSTRAINT `fk-city-country_id` FOREIGN KEY (`country_id`) REFERENCES `country` (`id`) ON DELETE SET NULL;
模型
国家
<?php
namespace alexs\yii2tabularload\tests\models;
use yii\db\ActiveRecord;
/**
* @property int $id
* @property string $name
* @property int $population
*/
class Country extends ActiveRecord
{
public function rules() {
return [
[['name', 'population'], 'filter', 'filter'=>'trim'],
[['name', 'population'], 'required'],
['population', 'integer'],
];
}
}
城市
<?php
namespace alexs\yii2tabularload\tests\models;
use alexs\yii2tabularload\TraitTabularload;
use yii\db\ActiveRecord;
/**
* @property int $id
* @property int $country_id
* @property string $name
* @property int $is_capital
* @property int $foundation
* @property string $image
* @property Country $course
*/
class City extends ActiveRecord
{
use TraitTabularload;
public function rules() {
return [
[['name', 'foundation'], 'filter', 'filter'=>'trim'],
[['name', 'foundation'], 'required'],
[['is_capital', 'foundation'], 'integer'],
//['image', 'image', 'extensions'=>['jpg', 'jpeg', 'png', 'gif']],
['image', 'string'], // just for tests
];
}
/**
* @return \yii\db\ActiveQuery
*/
public function getCountry() {
return $this->hasOne(Country::class, ['id' => 'country_id']);
}
}
表单
<div class="form">
<!-- existing cities -->
<?php if (!empty($cities)) { ?>
<?php foreach ($cities as $i=>$city) { ?>
<div class="row">
<div class="col col-lg-6">
<?=$activeForm->field($city, "[$i]name", ['enableClientValidation'=>false])?>
<?=$activeForm->field($city, "[$i]foundation", ['enableClientValidation'=>false])->textarea();?>
<?=$activeForm->field($city, "[$i]is_capital", ['enableClientValidation'=>false])->checkbox();?>
</div>
<?=$activeForm->field($city, "[$i]id", ['enableClientValidation'=>false])->hiddenInput()->label(false);?>
</div>
<?php } ?>
<?php } ?>
<!-- 3 new empty blocks, they can be added via JS -->
<?php $city = new City;?>
<?php for ($i = 0; $i <= 2; $i ++) { ?>
<div class="row">
<div class="col col-lg-6">
<?=$activeForm->field($city, "[$i]name", ['enableClientValidation'=>false])?>
<?=$activeForm->field($city, "[$i]foundation", ['enableClientValidation'=>false])->textarea();?>
<?=$activeForm->field($city, "[$i]is_capital", ['enableClientValidation'=>false])->checkbox();?>
</div>
</div>
<?php } ?>
</div>
操作
创建
<?php
public function actionCreate() {
$country = new Country();
$cities = [];
if (\Yii::$app->request->isPost) {
$country->load(\Yii::$app->request->post());
$cities = City::tabularloadCreate('\app\models\City');
$valid = $country->validate() && City::validateMultiple($cities);
if ($valid) {
$country->save(false);
City::tabularloadSave($cities, 'country', $country);
return $this->redirect('/countries');
}
}
return $this->render([
'country'=>$country,
'cities'=>$cities,
]);
}
更新
<?php
public function actionUpdate($id) {
if (!$country = Country::findOne($id)) {
throw new \yii\web\NotFoundHttpException;
}
$cities = [];
if (\Yii::$app->request->isPost) {
$country->load(\Yii::$app->request->post());
$cities = City::tabularloadUpdate('\app\models\City', ['country_id'=>$country->id]);
$valid = $country->validate() && City::validateMultiple($cities);
if ($valid) {
$country->save(false);
City::tabularloadSave($cities, 'country', $country);
return $this->redirect('/countries');
}
}
return $this->render([
'country'=>$country,
'cities'=>$cities,
]);
}