In a projects/create active form I have a field "related company account" as a dropdown (select2 by kartik). Behind this field I'd like to place a plus sign or something else to add new accounts to the dropdown with the following behavior:
$input = compact(array_keys(get_defined_vars()));
but probably needed on client side)return $this->redirect(Yii::$app->request->referrer);
) and fill the previously entered data (extract($input, EXTR_PREFIX_SAME, "arr");
)I'm struggling now with several issues:
Any hints are welcome. Thank you in advance.
One alternative i would suggest is using Session.
As for the "Add Accounts" button, i would use Submit button, and give different name to actual Submit button (two submit button in form, as answered in here). So, the projects/create view will look like this :
<?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(); ?>
And then check in ProjectsController, which submit button pressed by user. If add account was pressed, then save the inputed field (i would put this function in model for clearance), else, save the model or anything. And, before all that, check if session about project is set, if yes then pre-load it to model (again, in model). Okay, like they say, one code is worth a thousand words, so, this is ProjectsController will look like :
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,
]);
}
...
...
...
}
And Projects model will look like :
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
...
}
...
...
...
}
And in the AccountsController, just tell the program to jump back to projects/create if projects session is set, like so :
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,
]);
}
...
...
...
}
Well, it's looks bit lengthy, but yeah, it's worth trying. Anyway, you could use this approach for another purpose, save current form state for example.
Oh, one more thing, i haven't tested this in real code, so if any error exposed on my code, hit me up in comment.
Happy coding. :)