• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
send input file info via ajax

#1
I have a form with 4 fields: title, price, image and category.

When submitted, it inserts the 3 strings into the DB and uploads the image, or returns errors. It all works fine.

However, now I want it to be done via ajax.

It works fine for the title, price and category fields, but how do I pass the info needed from the file field so that codeigniter can upload it?

Right now it keeps saying "You did not select a file to upload."

My controller:

Code:
function add_new_product_ajax()
    {
        // make sure it's the admin, else redirect
        if ( ! $this->session->userdata('is_admin') ) {
            redirect('admin/login');
            exit();
        }

        // get product name
        $pn = $this->input->post('product_title');

        // get price
        $p = $this->input->post('price');

        // get category id
        $cid = $this->input->post('categories');

        // upload config
        $config['upload_path'] = './uploads/';
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size'] = '100';
        $config['max_width']  = '1024';
        $config['max_height']  = '768';
        $config['overwrite']  = TRUE;

        // load form validation
        $this->load->library('form_validation');

        // validate fields
        $this->form_validation->set_rules('product_title', 'Product Name', 'trim|required|is_unique[products.name]');
        $this->form_validation->set_rules('price', 'Price', 'trim|required|callback_check_price');
        $this->form_validation->set_rules('categories', 'Product\'s Category', 'required');

         // if validation failed
        if ($this->form_validation->run($this) == FALSE)
        {  
            // dummy var
            $data['dummy'] = '';

            // load categories module to make a select list
            $this->load->module('categories/categories');
            $data['options'] = $this->categories->categories_select();

            // load the view        
            $this->load->view('new_product_view', $data);        
        }
        else // validation passed
        {
            // do upload
            $this->load->library('upload', $config);
            $field_name = "userfile";
            // $this->upload->do_upload($field_name);

            // try to upload
            if ( ! $this->upload->do_upload()) {

                $data['error'] = $this->upload->display_errors();

                // load categories module to make a select list
                $this->load->module('categories/categories');
                $data['options'] = $this->categories->categories_select();

                // load the view        
                $this->load->view('new_product_view', $data);        

            }
            else // upload successful, insert data into table
            {
                // insert product data
                $this->mdl_products->add_product($pn, $p, $cid);

                // success msg
                $data['msg'] = '<div class=successmsg>The product has been added!</div>';

                // load categories module to make a select list
                $this->load->module('categories/categories');
                $data['options'] = $this->categories->categories_select();

                // load the view        
                $this->load->view('new_product_view', $data);        
            }

        }

    }

My ajax ( with missing file value parameter):

Code:
$('body').on('click', 'a.submitnewprod', function(e) {
        e.preventDefault();
        // alert('code');return;

        // get product title
        var pt = $('#product_title').val();

        // get product price
        var pp = $('#price').val();

        // get category id
        var cid = $('#categories').val();

        // get userfile ???????
        var uf = $('#uploadImage').val();

        $.ajax({
            type: "POST",
            url: site + "admin/add-new-product-ajax",
            data: {
                product_title:pt,
                price: pp,
                categories: cid
            },

            beforeSend: function() {
                 $('#ajaximg img').addClass('act');
            },

            success: function(data) {
                // $('.results').html(data);
                $('#ajax').html(data);
            },

            complete: function() {
                 $('#ajaximg img').removeClass('act');
            }

        });


    });

the file html from my view file:

Code:
<input id="uploadImage" type="file" name="userfile" size="20" onchange="PreviewImage();" />

What do I need to pass in my ajax call inside data parameter, so that the upload can work normally?
Reply

#2
There are a number of different ways to do this, depending on which browsers you want to support and whether you are using HTML5 and/or the File API. A number of these choices are outlined in the following StackOverflow post:

http://stackoverflow.com/questions/23200...ile-upload
Reply

#3
The point is the following:

To give the input and select validation statements their data to check:

Code:
$this->form_validation->set_rules('product_title', 'Product Name', 'trim|required|is_unique[products.name]');
$this->form_validation->set_rules('price', 'Price', 'trim|required|callback_check_price');
$this->form_validation->set_rules('categories', 'Product\'s Category', 'required');

I got their values using val() and passed them as data parameters in the ajax request:
Code:
data: {
                product_title:pt,
                price: pp,
                categories: cid
            },

An that works.

What additional parameter do I need to pass so that the following CI method can do it's job?
Code:
if ( ! $this->upload->do_upload()) {... (the file input's name is userfile, the CI standard).

I tried the following from the SO link you gave me:
Code:
var fd = new FormData(document.getElementById("uploadImage"));
fd.append("label", "WEBUPLOAD");

and then modified the data parameter like so:
Code:
data: {
                product_title:pt,
                price: pp,
                categories: cid,
                userfile : fd
            },

however when I try to submit the form I get the following console error:
Code:
Argument 1 of FormData.constructor does not implement interface HTMLFormElement.

Is there something similar I can do to get the needed value from the file field so that CI can upload it?
Reply

#4
(02-04-2015, 05:43 AM)dzoniboj Wrote: The point is the following:

To give the input and select validation statements their data to check:
...
I got their values using val() and passed them as data parameters in the ajax request:

...
An that works.

What additional parameter do I need to pass so that the following CI method can do it's job?

Code:
if ( ! $this->upload->do_upload()) {... (the file input's name is userfile, the CI standard).

I tried the following from the SO link you gave me:

Code:
var fd = new FormData(document.getElementById("uploadImage"));
fd.append("label", "WEBUPLOAD");

and then modified the data parameter like so:

Code:
data: {
               product_title:pt,
               price: pp,
               categories: cid,
               userfile : fd
           },

however when I try to submit the form I get the following console error:

Code:
Argument 1 of FormData.constructor does not implement interface HTMLFormElement.

Is there something similar I can do to get the needed value from the file field so that CI can upload it?

The form has to actually submit the file upload, which isn't necessarily an easy thing to accomplish with AJAX. The console error you are getting is trying to tell you that the argument you supplied to new FormData() is not a form. It looks like you tried to supply the file input to the constructor instead of the form.

Once you actually get the form to submit the file for upload, you can start worrying about CI's upload library and performing validation. Right now, there's no indication that there is any problem with the PHP code. You could verify that by posting the form via a normal HTTP post instead of using AJAX.
Reply

#5
It does work as supposed to without ajax.

But without ajax, it redirects to url that is the controller method.

What I wanted to achieve with ajax is to load the view on the same page, not redirect to url that is the controller method.

Also, the validation methods for the text inputs and the select input work with ajax, it's just the file input type I am having trouble passing so it's recognized by CI.
Reply

#6
If the only problem you have with the page when you submit it without AJAX is that it changes the URL, then you know your server-side code is working properly (barring any errors other than those you have already detailed). It doesn't matter what the code in your controller is, because your JavaScript isn't uploading the file.

AJAX file uploads are a complex issue, which is why I linked you to an outside discussion of those issues. In most cases, you are better off using someone else's file upload code if you want to use AJAX to upload a file (in fact, most of us are better off using someone else's file upload code for every facet of file uploads).

If you choose to use FormData, you accept that it will not work in older browsers or when JavaScript is disabled (unless you code the page to work without it). If you choose to ignore the error message in the JavaScript console, and the explanation of that message which I included in my previous reply, you will likely have a hard time getting AJAX to do much for you.
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.