1

I want to make multiple delete in laravel 5.5, I have tried forms it didn't work so i decided to use ajax instead.

What I try to do:

  1. Use checkbox to select multiple post/product id's.
  2. Send them to controller by ajax.
  3. Delete them.

Codes

controller

public function multipledel(Request $request){
      $deli = $request->input('productsfordel'); //get id's of selected post/products
      $product = Product::where('id', [$deli]); //find those id's in DB
      $product->delete(); // Delete them

      Session::flash('success', 'Selected products are successfully deleted.');
      return redirect()->route('products.index');
    }

route

Route::post('delmultipleproducts', 'ProductController@multipledel')->name('delmultipleproducts');

ajax

<script type="text/javascript">
  $(document).ready(function() {
    $('#multidel').on('click', function(e) {  //define which button to click for multiple delete
      e.preventDefault();
      $.ajaxSetup({
          headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') }
      });

      var idss = $('#productsfordel').val(); //where to get id's from
      if(idss) {
      $.ajax({
        url: '{{ url('admin/delmultipleproducts') }}',
        type: "POST",
        dataType: "json",
        success:function(data) {
          console.log('working');
        }
      });
      }else{
        console.log('not working');
      } 
    });
  });
</script>

blade

<button id="multidel" name="multidel">Delete All</button>

<thead>
  <th class="text-center">xxxxx</th>
</thead>
<tbody>
  @foreach($products as $product)
  <tr>
    <td>
      <input type="checkbox" id="productsfordel" name="productsfordel[]" value="{{ $product->id }}" />
    </td>

// rest of table

Issues

this is what i get in my network as result:

screen 1

Any idea?

UPDATE

Base on Babak answer I can get some result on network which means id's are actually sending, here is error:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`mysite`.`product_relatives`, CONSTRAINT `product_relatives_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)) (SQL: delete from `products` where `id` = 48)

so I realize it must have to do something with my products sync method such as options and specification and i changed my function to:

public function multipledel(Request $request){
      $deli = $request->input('productsfordel');
      $product = Product::where('id', [$deli]);
// added from here
      $product->suboptions()->detach();
      $product->subspecifications()->detach();
      if(!empty($product->imageOne)){
        Storage::delete($product->imageOne);
      }
      if(!empty($product->imageTwo)){
        Storage::delete($product->imageTwo);
      }
//to here
      $product->delete();

      Session::flash('success', 'Selected products are successfully deleted.');
      return redirect()->route('products.index');
    }

now i'm getting:

Call to undefined method Illuminate\Database\Query\Builder::suboptions()

any idea?

mafortis
  • 6,750
  • 23
  • 130
  • 288
  • it seems like you didn't include the 'productsfordel' parameter in your ajax request. $.ajax({ url: "", type:"", dataType: "", data: { productsfordel: idss } }) – xanadev May 06 '18 at 15:17
  • @xanadev i tried that, didn't work even in network i get nothing now. – mafortis May 06 '18 at 15:22
  • sorry, in the statement $.ajax({ url: "", type:"", dataType: "", data: { productsfordel: idss } }) , you should fill in url and type and datatype with the same values i just didn't want to type them again :), like so $.ajax({ url: "{{ url('admin/delmultipleproducts') }}", type:"POST", dataType: "json", data: { productsfordel: idss } }) – xanadev May 06 '18 at 15:28
  • Seems to be a relation-related problem indeed, see https://stackoverflow.com/questions/14174070/automatically-deleting-related-rows-in-laravel-eloquent-orm –  May 06 '18 at 16:05
  • @Allaiks but it is working just fine with destroy method, just when i bring them to my multiple delete method\ get this error. if it was something to do with my model i think i should get same error on destroy method as well no? – mafortis May 06 '18 at 16:08
  • Ah, then it may be a problem due to the fact that you must append ->get to your query to get a collection of your products, and then loop through this collection and apply the suboptions method to each element ( so try $products = Product::where('id', [$deli])->get() and loop through $products) –  May 06 '18 at 16:15
  • @Allaiks would you mind help with an answer? `in other hand` what if i use findOrfail` instead of comparing id's by `where`? – mafortis May 06 '18 at 16:17
  • What matters is that you apply your subOptions and other relation methods on models, not on the query. If you do Product::find(&whateverId), then you can call your relation like $product->subOptions()... but you want to apply the detach on several products, not one, don't you ? So get all the products you want to delete with get, and then detach them one by one with a loop –  May 06 '18 at 16:19
  • @Allaiks 1) as my site is e-commerce and almost every page relay on products i'm afraid for fixing this issue broke all other parts so i really try to avoid add/remove anything extra to my model. 2) i have tried to use `FindOrFail($deli)` and i got: `Method suboptions does not exist.` – mafortis May 06 '18 at 16:23
  • @Allaiks i actually get it to work now by looping my `$deli` it is deleting my products and their suboptions etc. but also i get `302` error and my page won't reload, `see this please` https://ibb.co/eMtFKS , what should i do? – mafortis May 06 '18 at 16:37
  • Do the redirect with Javascript in your success function : window.location="/your/url" ; –  May 06 '18 at 16:53

3 Answers3

2

First of all add data to your ajax

  var idss = $('#productsfordel').val();
  if(idss) {
  $.ajax({
    url: '{{ url('admin/delmultipleproducts') }}',
    type: "POST",
    dataType: "json",
    data: {
    productsfordel: idss
    }
    success:function(data) {
      console.log('working');
    }
  });
  }else{
    console.log('not working');
  } 

Then add a foreach in your controller like this

    $deli = $request->get('productsfordel'); //get id's of selected post/products
   Foreach($deli as $item){
  $product = Product::find($item); //find those id's in DB
  $product->delete(); // Delete them
    }
Babak Asadzadeh
  • 1,207
  • 1
  • 11
  • 21
1

You are giving your inputs the same id: not a good idea. First ou should remove the id attribute from your input tags.

Then you'd better enclose your inputs in a form tag with an id (let's say "myForm"):

<form id="myForm">
    <table>
    // ...
    @foreach($products as $product)
        <tr>
            <td>
                <input type="checkbox" id="productsfordel" name="productsfordel[]" value="{{ $product->id }}" />
            </td>
    // ...
    </table>
</form>

There's no need to set any action method since the route is defined within your Ajax request.

talking about your Ajax request, don't forget to pass your data (i.e you array of ids) with the data property like this:

...
dataType: "json"
data : $('#myForm').serialize()

So the controller receives an array of ids that you can delete with the Eloquent's destroy method :

Product::destroy($request->input('productsfordel'));

EDIT: If you don't want to use a form, you could instead give your inputs a class instead of an id (class="someClass") and then pass your data with

data: $('.someClass:checked').serialize(),
  • so what you say is that i open form around my `table` and what about form action? since i use my route in ajax `delmultipleproducts` should i repeat it in form as well? – mafortis May 06 '18 at 15:22
  • There's no need to set an action, you indeed set it in your ajax request. The form tag will just wrap your inputs so you can send it easily to your controller. –  May 06 '18 at 15:23
  • here is what i have base on your answer https://ibb.co/idbhYn and nothing happens, not even in network. – mafortis May 06 '18 at 15:26
  • Try wrapping the entire table within the form, maybe putting a form tag inside isn't great –  May 06 '18 at 15:29
  • warpping entire table is not a good idea bro because i have another forms there as well and it will conflict/ effect another forms csrf's. – mafortis May 06 '18 at 15:39
  • sorry, then give your input a CLASS instead of an id (e.g. class="products") and pass your data like this : data: $('.products:checked').serialize() –  May 06 '18 at 15:47
  • 1
    Try Product::destroy($request->input('productsfordel')) like i mentioned in my answer (which i had edited while chatting) –  May 06 '18 at 15:52
  • ok now, with that `destroy` you mentioned we will back to my question update, i get `SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: .................` please see my updates. – mafortis May 06 '18 at 15:56
0

Ajax call and select the multiple values

 var id=[];
            $('.subcheckes').each(function(){
               var values=$(this).attr('value')
                id.push(values)
            });                
            var url ="{{route('routeName')}}"
           var token = $("meta[name='csrf-token']").attr("content");
 
  $.ajax({
                   url: url,
                    type: 'POST',
                    data: {
                       "id": id,
                       "_token": token,
                   },
                    success: function(result) {
                       // Do something with the result
 
                      console.log('first')
                       $('#dataTable').DataTable().ajax.reload();
                    },
                    error:function(e){
                        console.error(e);
                    }
                });
                Swal.fire(
 
                    'Deleted!',
                    'Your file has been deleted.',
                    'success'
                )

Controller

    public function selectedData(Request $request)
    {
      $ids=$request->id;
       $categories=Category::whereIn('id',$ids)->get();
        foreach ($categories as $key => $category) {
            $category->delete();
        }

    }