【问题标题】:Add new value to dropdown list向下拉列表添加新值
【发布时间】:2017-03-01 20:57:01
【问题描述】:

在项目/创建活动表单中,我有一个字段“相关公司帐户”作为下拉列表 (select2 by kartik)。在此字段后面,我想放置一个加号或其他内容,以将新帐户添加到具有以下行为的下拉列表中:

  • 收集到目前为止完成的所有输入(例如 $input = compact(array_keys(get_defined_vars()));,但客户端可能需要)
  • 跳转到账户/创建并传递$input
  • 提交新帐户后跳转回项目/创建(例如return $this->redirect(Yii::$app->request->referrer);)并填写之前输入的数据(extract($input, EXTR_PREFIX_SAME, "arr");

我现在正在努力解决几个问题:

  • 这个过程是根据最佳实践还是我应该从根本上改变一些东西?
  • 按钮怎么样?提交按钮、链接或某种形式的 javascript?
  • 提交按钮的问题是并非所有必填字段都可以填写。因此,可能无法保存和恢复/更新项目模型。
  • 链接的问题是它是在输入数据之前构建的
  • javascript 的问题是我没有胶水

欢迎任何提示。提前谢谢你。

【问题讨论】:

  • 如果我是你,我只会使用按下加号按钮时出现的模态表单。表单需要使用 ajax 来发送要保存的数据,并且您可能希望使用 Select2 的 ajax 加载,因此您不必担心向其添加新选项。
  • 听起来是个不错的选择。我一定会试一试的。谢谢。

标签: yii2 select2 active-form


【解决方案1】:

我建议的另一种选择是使用Session

至于“添加帐户”按钮,我会使用提交按钮,并为实际的提交按钮赋予不同的名称(表单中的两个提交按钮,如 here 中的回答)。因此,项目/创建视图将如下所示:

<?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 中,如果设置了项目会话,只需告诉程序跳回项目/创建,如下所示:

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,
        ]);
    }

...
...
...
}

嗯,它看起来有点长,但是是的,值得一试。无论如何,您可以将此方法用于其他目的,例如保存当前表单状态。

哦,还有一件事,我还没有在实际代码中测试过,所以如果我的代码有任何错误,请在评论中联系我。

愉快的编码。 :)

【讨论】:

  • 很好,谢谢。它解决了在没有验证麻烦的情况下跳跃和返回的问题。与marche 的想法相比,它不需要AJAX 并且保持在同一层/没有弹出窗口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
相关资源
最近更新 更多