Не загружает файл в форме при использовании Pjax и модального окна

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

Привет! Делаю раздел сайта для управления фотографиями. Использовал расширение для генерации crud

https://github.com/johnitvn/yii2-ajaxcrud

которое в свою очередь использует расширения kartik-a

http://demos.krajee.com/grid-demo

Так вот, всё это очень хорошо и красиво работает с использованием pjax и модальных окон, пока мне не потребовалось добавить загрузку файла. Для начала сделал модель формы для загрузки фото в модальном окне:

Код: Выделить всё

<?php

namespace app\models;

use Yii;

/**
 * This is the model class for table "photo".
 *
 * @property string $id
 * @property string $file_name
 * @property string $name
 * @property string $description
 */
class UploadPhotoForm extends \yii\db\ActiveRecord
{

    public $image;


    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'photo';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['file_name', 'description'], 'string', 'max' => 32],
            [['name'], 'string', 'max' => 50],
            [['image','description','name'], 'safe'],
            [['image'], 'file', 'extensions'=>'jpg, gif, png'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'file_name' => 'File Name',
            'name' => 'Name',
            'description' => 'Description',
        ];
    }
}
 


Дальше сделал представление:

Код: Выделить всё

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\widgets\FileInput;


/* @var $this yii\web\View */
/* @var $model app\models\Photo */

?>
<div class="photo-create">
    <div class="photo-form">

        <?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>

<?php
        // your fileinput widget for single file upload
        echo $form->field($model, 'image')->widget(FileInput::classname(), [
        'options'=>['accept'=>'image/*'],
        'pluginOptions'=>['allowedFileExtensions'=>['jpg','gif','png']
        ]]);
?>

        <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>

        <?= $form->field($model, 'description')->textInput(['maxlength' => true]) ?>


        <?php if (!Yii::$app->request->isAjax){ ?>
            <div class="form-group">
                <?= Html::submitButton('Create', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
            </div>
        <?php } ?>

        <?php ActiveForm::end(); ?>
    </div>
</div>
Экшн:

Код: Выделить всё

    /**
     * Creates a new Photo model.
     * For ajax request will return json object
     * and for non-ajax request if creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $request = Yii::$app->request;
        $model = new UploadPhotoForm();

        if($request->isAjax) {
            /*
            *   Process for ajax request
            */
            Yii::$app->response->format = Response::FORMAT_JSON;
            if ($request->isGet) {

                return [
                    'title' => "Create new Photo",
                    'content' => $this->renderAjax('create', [
                        'model' => $model,
                    ]),
                    'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
                        Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])

                ];
            } else if ($model->load($request->post()) && $model->validate()) {


                    $image = UploadedFile::getInstance($model, 'image');



                ob_start();
                var_dump($model);
                var_dump($image);
                $result = ob_get_clean();




//                    $photo = new Photo();
//                    $photo->save();
//
//                    $photo->file_name = 'img/photo/' .
//                        $photo->id . '.'
//                        . $image->extension;
//
//                    $path = Yii::$app->basePath . '/web/' . $photo->file_name;
//                    $image->saveAs($path);
//
//                    $photo->name = $model->name;
//                    $photo->description = $model->description;
//                    $photo->save();

                    return [
                        'forceReload' => '#crud-datatable-pjax',
                        'title' => "Create new Photo",
                        'content' => '<span class="text-success">Create Photo success</span>'.$result,
                        'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
                            Html::a('Create More', ['create'], ['class' => 'btn btn-primary', 'role' => 'modal-remote'])

                    ];
                } else {
                    return [
                        'title' => "Create new Photo",
                        'content' => $this->renderAjax('create', [
                            'model' => $model,
                        ]),
                        'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
                            Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])

                    ];
                }
            } else {
                /*
                *   Process for non-ajax request
                */
                if ($model->load($request->post()) && $model->save()) {
                    return $this->redirect(['view', 'id' => $model->id]);
                } else {
                    return $this->render('create', [
                        'model' => $model,
                    ]);
                }
            }
    }
 
Теперь проверяю, подсовываю файл:
Изображение

В итоге ничего не загружается, в моделе формы на месте картинки пусто:
Изображение

В чем проблема, что делать?
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

rugabarbo писал(а):Дебажить.
Как раз этим и занимаюсь :)
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

Не понимаю почему, но через $_POST данные из других полей передаются (name, description), а вот файл — шиш. Тут запечатлён момент сразу после отправки данных через $_POST, при этом все три поля были заполненны, включая файл, но как видно, поле с файлом пустое.
Изображение

Я уже и стандартный fileInput использую, результат тот же:

Код: Выделить всё

        echo $form->field($model, 'image')->fileInput();
 
Почему обычные поля передают данные, а поле с файлом нет?

Картинка побольше:
http://i.piccy.info/i9/b95320b819212b26 ... ebug_1.png
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

А вот если сделать без модальных окон и без Pjax, то всё работает замечательно:
Изображение

Картинка побольше:
http://i.piccy.info/i9/3a74ba7709d7975c ... ebug_2.png
Аватара пользователя
ArtAv
Сообщения: 16
Зарегистрирован: 2012.06.30, 06:00

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение ArtAv »

Если без Pjax и модального окна работает, значит есть проблема с JS, посмотри что у тебя в консоли JS пишет.
http://shef96.ru интернет магазин подарков и сувениров
vkabachenko
Сообщения: 6
Зарегистрирован: 2015.06.12, 10:07
Откуда: Псков

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение vkabachenko »

FormData используйте для Ajax upload
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

ArtAv писал(а):Если без Pjax и модального окна работает, значит есть проблема с JS, посмотри что у тебя в консоли JS пишет.
Там чисто, лишь такое предупреждение:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

vkabachenko писал(а):FormData используйте для Ajax upload
Можно немного подробнее? я ничего не понял :?
Вроде и поискал по этим словам, но без толку.
Аватара пользователя
ArtAv
Сообщения: 16
Зарегистрирован: 2012.06.30, 06:00

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение ArtAv »

Я бы вернулся бы к расширению с jQuery upload.
FileInput::classname(), [
'options'=>['accept'=>'image/*'],
'pluginOptions'=>[
'uploadUrl'=>Yii:$app->urlManager->createUrl(['photo/upload']),
'allowedFileExtensions'=>['jpg','gif','png'],
'fileuploaded'=>'function(event, data, previewId, index){$("#photo-file_name").val(data.files);}'
]]
...
<?= $form->field($model, 'file_name')->textHidden() ?>
В контрольное прописываем actionUpload соответственно тут записываем файл и возвращаем json со статусом и названием файла.
ЗЫ сильно не пинайте пишу с телефона)
http://shef96.ru интернет магазин подарков и сувениров
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

ArtAv, вы имеете ввиду стандартный виджет для загрузки файлов?
Аватара пользователя
ArtAv
Сообщения: 16
Зарегистрирован: 2012.06.30, 06:00

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение ArtAv »

smck87,
нет, этот
use kartik\widgets\FileInput;
http://shef96.ru интернет магазин подарков и сувениров
vkabachenko
Сообщения: 6
Зарегистрирован: 2015.06.12, 10:07
Откуда: Псков

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение vkabachenko »

Можно немного подробнее? я ничего не понял :?
Вроде и поискал по этим словам, но без толку.
Посмотрите, например, http://stackoverflow.com/questions/2723 ... y-formdata
polumerk
Сообщения: 80
Зарегистрирован: 2015.07.09, 16:04

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение polumerk »

smck87, на днях тоже хочу попробовать данный генератор и расширения, если то того у вас получится решить проблему напишите решение, а если у меня в друг тоже самое будет, то я сюда отпишусь как сам решил.
smck87
Сообщения: 133
Зарегистрирован: 2011.01.30, 21:22

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение smck87 »

vkabachenko, большое спасибо! Изучаю.

polumerk, договорились :)
polumerk
Сообщения: 80
Зарегистрирован: 2015.07.09, 16:04

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение polumerk »

smck87 писал(а):vkabachenko, большое спасибо! Изучаю.

polumerk, договорились :)
В итоге уже более месяца бьюсь с этой проблемой, все точно так же:(

уже что не перепробовал не могу понять, как победить проблему((

У вас получилось?
polumerk
Сообщения: 80
Зарегистрирован: 2015.07.09, 16:04

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение polumerk »

Решил проблему!

В итоге как выяснилось через аякс нельзя передать файлы с помощью serializeArray(), он подменяет contentType на не верный и файлы не доходят до файлы обработчика загрузки файла.
В итоге заменил вот эту строку:
var data = $(modalForm).serializeArray();
на
var data = new FormData(modalForm);

конечно это решение не для старых версий браузеров, но для меня подходит.
ikarus
Сообщения: 9
Зарегистрирован: 2023.08.10, 13:23

Re: Не загружает файл в форме при использовании Pjax и модального окна

Сообщение ikarus »

polumerk писал(а): 2016.03.18, 14:40 Решил проблему!

В итоге как выяснилось через аякс нельзя передать файлы с помощью serializeArray(), он подменяет contentType на не верный и файлы не доходят до файлы обработчика загрузки файла.
В итоге заменил вот эту строку:
var data = $(modalForm).serializeArray();
на
var data = new FormData(modalForm);

конечно это решение не для старых версий браузеров, но для меня подходит.
вот спасибо, а то лоб разбил уже
Ответить