sharf
sharf

Reputation: 2143

Yii2 pjax file upload for use within activeForm

I'm creating a Yii2 activeForm for creating and editing a product, and want the page to manage images as well. I want to be able to upload (add) images for the product, and then have a sortable preview region where the images show up and can be sorted to the right order. My plan is to upload files via ajax/pjax to a temporary folder where the form will pull from to display them in the sortable region, and upon saving the model, the images will be moved/named accordingly.

Initially I'm using Kartik's FileInput widget (which may be unnecessary) and Kartik's Sortable Input for re-ordering the images.

I believe I can handle the file uploading and moving/renaming, my question is how do I upload the images separate from the rest of the form, and then have the ActiveForm pull them into the sortable input area? Additionally, I'll want to be able to delete images from it as well (with a little x in the corner of the thumbnail). I'm familiar with using pjax to wrap grid-views and even using pjax to submit a form to a pjax method (for use inside a modal), but not sure how to use it inside another form and make the other form dynamically load the images.

To clarify, I have a Product that extends ActiveRecord, and a ImageForm that extends Model. I then have ProductController with the following Create action:

public function actionCreate()
{
    $model = new Product();
    $images = new ImageForm();

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

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

My goal is to be able to upload images (through ImageForm) to a temporary location that is displayed on the Product's create view. However currently, using the upload function in the widget merely reloads the page and the images are gone.

Upvotes: 0

Views: 1184

Answers (1)

Muhammad Omer Aslam
Muhammad Omer Aslam

Reputation: 23748

You can use a separate model for Uploading the image and use the same form with just passing the $uploadForm model object to populate the form field for the file, you can use the kartik\FileInput widget which has the option to upload file via ajax via uploadUrl, you can trigger the upload on the selection of the file automatically via fileUploaded event and once uploaded you have 2 options either you use uploadAsync=>true and use filebatchuploadsuccess which triggers after all files are uploaded or use default setting and use filebatchuploadcomplete wchich will trigger after every file upload. Both of these events provide the list of files that are uploaded but be careful as you are validating the files after they are submitted you should return the response in case of error so that the user is notified for the files that were not uploaded, you can either the files list provided by the events or better use a separate action inside your controller and call it inside the relative success function you are using via an ajax call and populate the list of the uploaded files if you are saving them inside a table query the table to show the names

fileselect : This event is triggered after files are selected in the file input via the file browse button. This is slightly different than the change event in the sense that this will be triggered even if the file browse dialog is canceled.

How you are going to use it

//get filinput object
var $input=$("#input-id");

 $input.on('fileselect', function(event, numFiles, label) {

    //trigger file upload with 1 sec delay
    setTimeout(function() {
    $input.fileinput("upload");
}, 1000);
});

filebatchuploadcomplete: This event is triggered only for ajax uploads and after completion of either the synchronous OR asynchronous ajax batch upload.

Additional parameters available are:

  • files: the file stack array (or empty object if not available).

  • extra: the uploadExtraData settings for the plugin (or empty object if not available).

Sample Code

$('#input-id').on('filebatchuploadcomplete', function(event, files, extra) {
    //call the ajax function here to query the files that are uploaded
});

Upvotes: 1

Related Questions