A
A
Alexander Bulatov2021-02-05 18:16:00
Yii
Alexander Bulatov, 2021-02-05 18:16:00

How to correctly add a new FileInput from Kartik to an existing form in ActiveForm Yii2?

Good day!

The task is such that we need to add a new FileInput field from Kartik to a form that is created by ActiveForm and has already been rendered.

I have done it in the following way.

Action in controller:

public function actionCreate()
    {
        $model = new Slider();
        $uploadingForm = new UploadingForm();

        if ($model->load(Yii::$app->request->post()) && $model->save()) { 
            $this->saveImages($model, $uploadingForm);                   
            return $this->redirect(['view', 'id' => $model->id]);
        }

        return $this->render('_form', [
            'model' => $model,
            'uploadingForm' => $uploadingForm,
        ]);
    }


view:
<?php

use yii\helpers\Html;
use yii\bootstrap4\ActiveForm;
use kartik\file\FileInput;
use yii\helpers\Url;

/* @var $this yii\web\View */
/* @var $model app\models\Slider */
/* @var $form yii\bootstrap4\ActiveForm */
/* @var $uploadingForm app\models\UploadingForm */
/* @var $collectionFileArray this is a collection of a current slider represented as an array of paths  */
?>
<div class="slider-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'where')->dropDownList(
        $model::associatedArrayOfLocations()
    ) ?>

    <?= $form->field($model, 'status')->radioList([
        $model::STATUS_OFF => 'Выключен',
        $model::STATUS_ON => 'Включён',
    ], [
        'item' => function($index, $label, $name, $checked, $value) {
            $item = Html::beginTag('div', ['class' => 'custom-control custom-radio']);
            $item .= Html::radio($name, $checked, ['id' => 'article-status-'.$index, 'value' => $value, 'class' => 'custom-control-input']);
            $item .= Html::label($label, 'article-status-'.$index, ['class' => 'custom-control-label']);
            $item .= Html::endTag('div');
            return $item;
        },
    ])->hint('По умолчанию "Включен"') ?>

    <?= $form->field($uploadingForm, 'imageFiles[]')->widget(FileInput::class, [
        'options' => ['id' => 'foo', 'accept' => 'image/*'],
        'pluginOptions' => [
            'initialPreview' => $collectionFileArray ?? '',
            'initialPreviewAsData' => true,
            'fileActionSettings' => [
                'showZoom' => false,
                'showRemove' => false,
            ],
            'showCaption' => true, // show an input where we show the name of an uploading file
            'showRemove' => false,
            'showUpload' => false,
            'showCancel' => false, // show a cancel of uploading process button
            'browseClass' => 'btn btn-primary',
            'browseLabel' => 'Загрузить',
            //'maxFileSize' => 15000,
        ],
    ]) ?>

    <?= $form->field($uploadingForm, 'imageFiles[]')->widget(FileInput::class, [
        'options' => ['id' => 'bar', 'accept' => 'image/*'],
        'pluginOptions' => [
            'initialPreview' => $collectionFileArray ?? '',
            'initialPreviewAsData' => true,
            'fileActionSettings' => [
                'showZoom' => false,
                'showRemove' => false,
            ],
            'showCaption' => true, // show an input where we show the name of an uploading file
            'showRemove' => false,
            'showUpload' => false,
            'showCancel' => false, // show a cancel of uploading process button
            'browseClass' => 'btn btn-primary',
            'browseLabel' => 'Загрузить',
            //'maxFileSize' => 15000,
        ],
    ]) ?>

    <?= Html::button('add', [
        'class' => 'btn btn-primary', 'id' => 'add-input',
        'data-url' => Url::to(['/admin/slider/add-input'])
    ]) ?>
    <?php $this->registerJs("
        $('#add-input').on('click', function() {
            let self = this;
            $.ajax($(self).data('url'), {
                method: 'post',
                processData : false,
                contentType : false,
                success: function(r) {
                    $(self).before(r);
                },
            });
        });
    "); ?>

    <div class="form-group">
        <?= Html::submitButton('Сохранить', ['class' => 'btn btn-block btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>


Action to add a new field via Ajax:
public function actionAddInput()
    {
        return $this->renderAjax('_ajax-slide');
    }


View _ajax-slide:
<?php

use yii\bootstrap4\ActiveForm;
use kartik\file\FileInput;
use app\models\forms\UploadingForm;


$form = new ActiveForm();
$model = new UploadingForm();
?>

<?= $form->field($model, 'imageFiles[]')->widget(FileInput::class, [
    'options' => ['id' => 'new-input', 'accept' => 'image/*'],
    'pluginOptions' => [
        'initialPreview' => false,
        'initialPreviewAsData' => true,
        'fileActionSettings' => [
            'showZoom' => false,
            'showRemove' => false,
        ],
        'showCaption' => true, // show an input where we show the name of an uploading file
        'showRemove' => false,
        'showUpload' => false,
        'showCancel' => false, // show a cancel of uploading process button
        'browseClass' => 'btn btn-primary',
        'browseLabel' => 'Загрузить',
        //'maxFileSize' => 15000,
    ],
]); ?>


The field is indeed added by clicking on the button, but it is not displayed. This brings up a tiny square and you can click on it and actually upload the image, but the FileInput widget itself is not shown.

The following error is shown in the browser console:
Uncaught ReferenceError: fileinput_0c236089 is not defined


My understanding is that FileInput creates a unique page ID when rendering a page (I thought so, since all other FileInput widgets, if added, will have the same number). Here's the question, how do I add this number to my new field so that the widget will display the field?

And in general, how to update it, or what? Reinitialize? Whereas?

I would be grateful for any idea how to solve. In general, the task is to dynamically add and remove this FileInput widget, and in any quantity on the current page.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question