dlanr
dlanr

Reputation: 21

Laravel upload image through modal using ajax/jquery

I'm making a small system that has inventory in it. I have a products table that has an image column that represents a picture of a specific product. My problem is why I can't upload using my modal and ajax code in my project in Laravel? Does anyone know how to solve this issue? I spend 2 days already in figuring out how to solve this error:

message: "Undefined index: product_name"

I already made the fields fillable in my model. Help will be highly appreciated.

output

Modal Code

 <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalCenterTitle">Register New Product</h5>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
        <p style="font-weight: bold;">Name </p>
          <input   type="text" class="form-control" id="product_name"/>
          <p style="font-weight: bold;">Description </p>
          <input   type="text" class="form-control" id="description"/>
          <p style="font-weight: bold;">Price </p>
          <input   type="text" class="form-control" id="currentprice"/>
          {{-- <input style="text-transform:uppercase"   type="text" class="form-control" id="supplier_id"/> --}}
          <p style="font-weight: bold;">Supplier </p>
          <select class="form-control"  id="supplier_id"  >
              @foreach ($suppliers as $supplier)
          <option value="{{$supplier->id}}">{{$supplier->name}}</option>
              @endforeach
              </select>
         <p style="font-weight: bold;">Picture </p>
          <input  type="file" class="form-control" id="picture"/>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary" id="add_product">Add</button>
        </div>
      </div>
    </div>
  </div>

Script

 $(document).ready(function() {
    //add
    $('#add_product').click(function(e) {
        e.preventDefault();
        var name = $('#product_name').val();
        var description = $('#description').val();
        var price = $('#currentprice').val();
        var supplier_id = $('#supplier_id').val();
        var image = $('#picture').val();

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $.ajax({
            url: "{{    url('/product')     }}",
            method: 'post',
            enctype: 'multipart/form-data',
            processData: false, 
            contentType: false,
            data:{
                product_name: name,
                description: description,
                price: price,
                supplier_id: supplier_id,
                image: image,
            },
            success: function (res) {
                console.log(res);
                window.location.href = '{{route("products")}}'
            }
        });
    });
});

ProductsController.php

 public function store(Request $request)
    {
        $data = $request->all();
        $data['product_name'] = ($data['product_name']);
        $data['description'] = ($data['description']);
        $data['supplier_id'] = ($data['supplier_id']);
        $data['price'] = ($data['price']);



        if ($request->hasFile('image')){
            //Add new photo
                $image = $request->file('image');
                $filename = time() . '.' . $image->getClientOriginalExtension();
                $location = public_path('img/' . $filename);
                Image::make($image)->resize(300,300)->save($location);
                $oldFilename = $products->image;
            //Update DB
                $products->image = $filename;
             //Delete the old photo
                // Storage::delete($oldFilename);
            }

        Product::create($data);
        return response()->json($data);
    }

route for products

//products
Route::resource('product', 'ProductsController');

Upvotes: 1

Views: 1519

Answers (2)

AbdulkadirFaghi
AbdulkadirFaghi

Reputation: 96

I know this question is quite old but I faced the same problem in the past days so I think an answer could be usefull to other developers.

You need only to use FormData instead of serialize your form. Note that FormData need an HTMLFormElement so you need to add [0] to your jQuery object. And you have NOT to add dataType directive.

This is my code:

$('#submit').on('click', function(e) {
    e.preventDefault();
    $(this).attr('disabled','disabled');
    var form = $(this).closest('form');
    jQuery.ajax({
        type: 'POST',
        processData: false,
        contentType: false,
        data: new FormData(form[0]),
        url: form.attr('action'),
        enctype: 'multipart/form-data',
        headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
        success: function (data) {
            $('#submit').removeAttr('disabled');
            // YOUR SUCCESS MANAGEMENT
        },
        error: function (e) {
            $('#submit').removeAttr('disabled');
            // YOUR ERROR MANAGEMENT
        }
    });
});

Upvotes: 0

Roman Meyer
Roman Meyer

Reputation: 2872

Seems like you send to server an object, when server expect JSON. Try to add dataType:

$.ajax({
    url: "{{ url('/product') }}",
    method: 'post',
    enctype: 'multipart/form-data',
    contentType: false,
    dataType: 'json', // setting of data type
    data:{
        product_name: name,
        description: description,
        price: price,
        supplier_id: supplier_id,
        image: image,
    },
    success: function (res) {
        console.log(res);
        window.location.href = '{{route("products")}}'
    }
});

Upvotes: 0

Related Questions