向下拉列表添加新值
Add new value to dropdown list
在 projects/create 活动表单中,我有一个字段 "related company account" 作为下拉列表 (select2 by kartik)。在这个字段后面,我想放置一个加号或其他东西来将新帐户添加到具有以下行为的下拉列表中:
- 收集到目前为止完成的所有输入(类似于
$input = compact(array_keys(get_defined_vars()));
但客户端可能需要)
- 跳转到accounts/create并传递$input
- 提交新帐户后跳回projects/create(例如
return $this->redirect(Yii::$app->request->referrer);
)并填写之前输入的数据(extract($input, EXTR_PREFIX_SAME, "arr");
)
我现在正在努力解决几个问题:
- 这个过程是根据最佳实践还是我应该从根本上改变一些东西?
- 这个按钮怎么样?提交按钮,link 或某种形式的 javascript?
- “提交”按钮的问题是可能无法填写所有必填字段。所以保存和 resuming/updating 项目模型可能是不可能的。
- link 的问题在于它是在输入数据之前构建的
- javascript的问题是我没有胶水
欢迎任何提示。提前谢谢你。
我建议的另一种选择是使用 Session。
至于 "Add Accounts" 按钮,我会使用提交按钮,并为实际的提交按钮指定不同的名称(表单中有两个提交按钮,如 here 中的回答)。因此,projects/create 视图将如下所示:
<?php $form = ActiveForm::begin(); ?>
...
...
...
<?= $form->field($model, 'account_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Account::find()->all(), "id", "name"),
'options' => ['placeholder' => 'Select a related company account ...'],
'pluginOptions' => [
'allowClear' => true
],
]) ?>
<?= Html::submitButton('Add Account ;)', ['class' => 'btn btn-success', 'name' => 'add_account_submit']) ?>
...
...
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
然后检查 ProjectsController,用户按下提交按钮。如果添加帐户被按下,然后保存输入的字段(我会把这个功能放在模型中以便清除),否则,保存模型或任何东西。并且,在此之前,检查是否设置了有关项目的会话,如果是,则将其预加载到模型(再次在模型中)。好的,就像他们说的,一个代码抵得上一千个单词,所以,这是 ProjectsController 看起来像:
class ProjectsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Projects();
if (Projects::isSavedInSession()) {
$model->loadFromSession();
}
if (Yii::$app->request->post('add_account_submit')) { // if add_account_submit is clicked
$model->saveTosession(Yii::$app->request->post('Projects')); // I assume your model named Projects, if not, change this value to your model name
return $this->redirect(['accounts/create']);
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->clearSession(); // we dont need the session anymore
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
Projects 模型将如下所示:
class Projects extends \yii\db\ActiveRecord
{
...
...
...
public static function isSavedInSession() { // why this is static is beyond this question context
if (Yii::$app->session->get('projects')) return true;
return false;
}
public function loadFromSession() {
if (Yii::$app->session->get('projects_name')) $this->name = if (Yii::$app->session->get('projects_name'));
if (Yii::$app->session->get('projects_account_id')) $this->account_id = if (Yii::$app->session->get('projects_account_id'));
...
... // insert all model's field here
...
}
public function saveToSession($fields) {
Yii::$app->session->set('projects', 1);
foreach ($fields as $field=>$value) {
Yii::$app->session->set('projects_' . $field, $value);
}
}
public function clearSession() {
Yii::$app->session->remove('projects'));
Yii::$app->session->remove('projects_name'));
Yii::$app->session->remove('projects_account_id'));
...
... // insert all model's field here
...
}
...
...
...
}
并且在 AccountsController 中,如果设置了项目会话,只需告诉程序跳回到 projects/create,就像这样:
class AccountsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Accounts();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if (Projects::isSavedInSession()) {
return $this->redirect(['projects/create');
}
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
好吧,它看起来有点冗长,但是是的,值得一试。无论如何,您可以将此方法用于其他目的,例如保存当前表单状态。
哦,还有一件事,我还没有在真实代码中测试过,所以如果我的代码出现任何错误,请在评论中打我。
编码愉快。 :)
在 projects/create 活动表单中,我有一个字段 "related company account" 作为下拉列表 (select2 by kartik)。在这个字段后面,我想放置一个加号或其他东西来将新帐户添加到具有以下行为的下拉列表中:
- 收集到目前为止完成的所有输入(类似于
$input = compact(array_keys(get_defined_vars()));
但客户端可能需要) - 跳转到accounts/create并传递$input
- 提交新帐户后跳回projects/create(例如
return $this->redirect(Yii::$app->request->referrer);
)并填写之前输入的数据(extract($input, EXTR_PREFIX_SAME, "arr");
)
我现在正在努力解决几个问题:
- 这个过程是根据最佳实践还是我应该从根本上改变一些东西?
- 这个按钮怎么样?提交按钮,link 或某种形式的 javascript?
- “提交”按钮的问题是可能无法填写所有必填字段。所以保存和 resuming/updating 项目模型可能是不可能的。
- link 的问题在于它是在输入数据之前构建的
- javascript的问题是我没有胶水
欢迎任何提示。提前谢谢你。
我建议的另一种选择是使用 Session。
至于 "Add Accounts" 按钮,我会使用提交按钮,并为实际的提交按钮指定不同的名称(表单中有两个提交按钮,如 here 中的回答)。因此,projects/create 视图将如下所示:
<?php $form = ActiveForm::begin(); ?>
...
...
...
<?= $form->field($model, 'account_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Account::find()->all(), "id", "name"),
'options' => ['placeholder' => 'Select a related company account ...'],
'pluginOptions' => [
'allowClear' => true
],
]) ?>
<?= Html::submitButton('Add Account ;)', ['class' => 'btn btn-success', 'name' => 'add_account_submit']) ?>
...
...
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
然后检查 ProjectsController,用户按下提交按钮。如果添加帐户被按下,然后保存输入的字段(我会把这个功能放在模型中以便清除),否则,保存模型或任何东西。并且,在此之前,检查是否设置了有关项目的会话,如果是,则将其预加载到模型(再次在模型中)。好的,就像他们说的,一个代码抵得上一千个单词,所以,这是 ProjectsController 看起来像:
class ProjectsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Projects();
if (Projects::isSavedInSession()) {
$model->loadFromSession();
}
if (Yii::$app->request->post('add_account_submit')) { // if add_account_submit is clicked
$model->saveTosession(Yii::$app->request->post('Projects')); // I assume your model named Projects, if not, change this value to your model name
return $this->redirect(['accounts/create']);
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->clearSession(); // we dont need the session anymore
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
Projects 模型将如下所示:
class Projects extends \yii\db\ActiveRecord
{
...
...
...
public static function isSavedInSession() { // why this is static is beyond this question context
if (Yii::$app->session->get('projects')) return true;
return false;
}
public function loadFromSession() {
if (Yii::$app->session->get('projects_name')) $this->name = if (Yii::$app->session->get('projects_name'));
if (Yii::$app->session->get('projects_account_id')) $this->account_id = if (Yii::$app->session->get('projects_account_id'));
...
... // insert all model's field here
...
}
public function saveToSession($fields) {
Yii::$app->session->set('projects', 1);
foreach ($fields as $field=>$value) {
Yii::$app->session->set('projects_' . $field, $value);
}
}
public function clearSession() {
Yii::$app->session->remove('projects'));
Yii::$app->session->remove('projects_name'));
Yii::$app->session->remove('projects_account_id'));
...
... // insert all model's field here
...
}
...
...
...
}
并且在 AccountsController 中,如果设置了项目会话,只需告诉程序跳回到 projects/create,就像这样:
class AccountsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Accounts();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if (Projects::isSavedInSession()) {
return $this->redirect(['projects/create');
}
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
好吧,它看起来有点冗长,但是是的,值得一试。无论如何,您可以将此方法用于其他目的,例如保存当前表单状态。
哦,还有一件事,我还没有在真实代码中测试过,所以如果我的代码出现任何错误,请在评论中打我。
编码愉快。 :)