Good day mates!
Given the next task. I need to add a new field of FileInput of Kartik to the current rendered form of ActiveRecord.
I made it the next way.
the action of the 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,
]);
}
_form:
<?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 => 'Swithed off',
$model::STATUS_ON => 'Switched 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('Default "Switch On"') ?>
<?= $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' => 'Upload',
//'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' => 'Upload',
//'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('Save', ['class' => 'btn btn-block btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
The action for addition of a new field by Ajax:
public function actionAddInput()
{
return $this->renderAjax('_ajax-slide');
}
_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 actually added by clicking on the button, but it is not displayed. At the same time, a tiny square appears and you can click on it and actually load the image, but the FileInput widget itself is not shown.
At the same time, an error is displayed in the browser console:
Uncaught ReferenceError: fileinput_0c236089 is not defined
I understand that when rendering a page, FileInput creates a unique page ID (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 displays the field?
And in general, how to update it, or what? Initialize it? Then how?
I would be grateful for any idea how to solve it. In general, the task is to dynamically add and remove this FileInput widget, and in any quantity on the current page.