1

I need to upload image with ajax call. But POST field with image always is empty. Part of my form:

<div class="col-lg-6">
    <?php echo CHtml::activeFileField($model, 'logo'); ?>
    <?php echo CHtml::textField('test', 'test'); ?>
    <?php echo CHtml::submitButton('Upload'); ?>        
    <?php echo CHtml::ajaxSubmitButton('Upload ajax', '#');?>
</div>

If i click submitButton, then i have both test and logo fields - image uploaded. And if i click ajaxSubmitButton, then i have only test field, logo is empty. What is the solution?

PS: i need non-extension solution.

f0rtis
  • 326
  • 2
  • 13

3 Answers3

2

You cannot upload files with ajaxSubmitButton by default. Use simple submit or some uploader. If you want to upload image via ajax, here's example:

<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"js:upload_file(this)"));?>

In your js:

function upload_file(){
    var fd = new FormData();
    var e = document.getElementById("Model_logo");
    fd.append( "Model[logo]", $(e)[0].files[0]);
    $.ajax({
        url: 'upload',
        type: 'POST',
        cache: false,
        data: fd,
        processData: false,
        contentType: false,
        success: function (data) { 

        },
        error: function () {
            alert("ERROR in upload");
        }
    });
}

Change Model to your model name and this will work. Also now you can append any data to FormData and it will be passed in $_POST and your file in $_FILES. Be carefull, this way doesn't work on ie7 and ie8 as i remember.

ineersa
  • 3,445
  • 30
  • 40
1

Based on ineersa's answer, I made some improvements:

<?php echo CHtml::link('Upload ajax', '#', array("onclick"=>"upload_file()")); ?>

In your js:

function upload_file(){
    var fd = new FormData($('#model-form')[0]);
    $.ajax({
        url: 'upload',
        type: 'POST',
        cache: false,
        data: fd,
        processData: false,
        contentType: false,
        success: function (data) { 

        },
        error: function () {
            alert("ERROR in upload");
        }
    });
}

This way you don't have to append each form field manually. All form data will be read automatically (including files). Just make sure that #model-form is changed according to your form id.

user2513149
  • 850
  • 12
  • 15
0

A way you don't need to call $.ajax(...) by yourself.

$(document).on('ajaxBeforeSend', 'form.my-form', function (event, jqXHR, settings) {
    if ((settings.url.indexOf("js_skip") == -1) && $("form.my-form input[type=file]")[0].files.length) {
        jqXHR.abort();
        settings.cache = false;
        settings.contentType = false;
        settings.processData = false;
        settings.data = new FormData(this);
        settings.url = settings.url + "&js_skip=1";
        jqXHR = $.ajax(settings);
    }
});
Ramil
  • 1