admin管理员组

文章数量:1406722

I have a table in Laravel 5.4 which is displaying news which have a delete option. The code is the following: news.blade.php:

@foreach($news as $article)
   <tr class="text-center">
       <td>{{ $article->title }}</td>
       <td>{{ $article->created_at }}</td>
       <td>{{ $article->views }}</td>
       <td>
          <a class="btn btn-primary btn-flat" href="#">
             <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
          </a>
       </td>
       <td>
           <a class="btn btn-warning btn-flat" href="#" onclick="event.preventDefault(); document.getElementById('delete-form').submit();">
                 <i class="fa fa-lg fa-trash"></i>
           </a>

           <form action="{{ route('delete-article') }}" method="POST" id="delete-form" style="display: none;">
                {{csrf_field()}}
                <input type="hidden" value="{{ $article->id }}" name="id">
           </form>
        </td>
   </tr>
@endforeach

My question is how do I tell the javascript to submit exactly that form which is right next to the a href, because right now It would submit the first form which matches the id which is not always in the same td as the clicked a href

EDIT: I know I can try accessing the parent of the clicked href with jquery and then accessing it's child form or use jquery's closes function, but I am looking for something more stable.

I have a table in Laravel 5.4 which is displaying news which have a delete option. The code is the following: news.blade.php:

@foreach($news as $article)
   <tr class="text-center">
       <td>{{ $article->title }}</td>
       <td>{{ $article->created_at }}</td>
       <td>{{ $article->views }}</td>
       <td>
          <a class="btn btn-primary btn-flat" href="#">
             <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
          </a>
       </td>
       <td>
           <a class="btn btn-warning btn-flat" href="#" onclick="event.preventDefault(); document.getElementById('delete-form').submit();">
                 <i class="fa fa-lg fa-trash"></i>
           </a>

           <form action="{{ route('delete-article') }}" method="POST" id="delete-form" style="display: none;">
                {{csrf_field()}}
                <input type="hidden" value="{{ $article->id }}" name="id">
           </form>
        </td>
   </tr>
@endforeach

My question is how do I tell the javascript to submit exactly that form which is right next to the a href, because right now It would submit the first form which matches the id which is not always in the same td as the clicked a href

EDIT: I know I can try accessing the parent of the clicked href with jquery and then accessing it's child form or use jquery's closes function, but I am looking for something more stable.

Share Improve this question edited Aug 10, 2017 at 14:08 Angel Miladinov asked Aug 10, 2017 at 14:03 Angel MiladinovAngel Miladinov 1,6554 gold badges25 silver badges46 bronze badges 1
  • If any of the answers helped you, please mark it to accepted. If you find the solution by yourself, don't hesitate to share it ! – Benjamin Brasseur Commented Aug 10, 2017 at 18:36
Add a ment  | 

4 Answers 4

Reset to default 5

Before doing anything, your route should be (if it's not already done) :
Route::delete(...)->name('delete-article');

I think that you can do something like this :

   <a class="btn btn-warning btn-flat" href="#" onclick="event.preventDefault(); document.getElementById('delete-form-{{ $article->id }}').submit();">
         <i class="fa fa-lg fa-trash"></i>
   </a>

   <form action="{{ route('delete-article') }}" method="POST" id="delete-form-{{ $article->id }}" style="display: none;">
        {{csrf_field()}}
        {{ method_field('DELETE') }}
        <input type="hidden" value="{{ $article->id }}" name="id">
   </form>

Or with Ajax

@foreach($news as $article)
   <tr class="text-center">
       <td>{{ $article->title }}</td>
       <td>{{ $article->created_at }}</td>
       <td>{{ $article->views }}</td>
       <td>
          <a class="btn btn-primary btn-flat" href="#">
             <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
          </a>
       </td>
       <td>
           <a class="btn btn-warning btn-flat" href="#" onclick="callAjax({{ $article->id }})">
                 <i class="fa fa-lg fa-trash"></i>
           </a>
        </td>
   </tr>
@endforeach

<script>
function callAjax(articleId) {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    })

    $.ajax({
        type: 'POST',
        url: '{{ route('delete-article') }}',
        data: {_method: 'DELETE', id: articleId}
    })
    .done(function (data) {
        // DO SOMETHING OR NOT
     }).error(function (err) {
        // DO SOMETHING OR NOT
     });
}

</script>

You will have to specify <meta name="csrf-token" content="{{ csrf_token() }}"> in your document head. (https://laravel./docs/5.4/csrf#csrf-x-csrf-token)

Benjamin Brasseur gives you a way to do it with AJAX. (And I don't think it's "tricky" by the way)

However, with your current javascript, you seem to just submit a hidden form. Why don't you use a real form?

<td>
    <form action="{{ route('delete-article') }}" method="POST">
        {{ csrf_field() }}

        <input type="hidden" value="{{ $article->id }}" name="id" />

        <button type="submit" class="btn btn-warning btn-flat">
             <i class="fa fa-lg fa-trash"></i>
        </button>
    </form>
</td>

If the visual is not same, adjust the style of the <form> (make it inline-block or something) and of the <button> to match your old <a>.

HTML

<tr id="parent-{{ $article->id }}">
  <td>{{ $article->title }}</td>
  <td>{{ $article->created_at }}</td>
  <td>{{ $article->views }}</td>
  <td>
    <a href="{{ route('route', $article->id) }}" id="{{ $article->id }}" data-method="DELETE" class="delete-btn"><i class="fa fa-fw fa-remove"></i></a>
  </td>
</tr>

Add in your head:

<meta name="csrf-token" content="{{ csrf_token() }}">

My script is just in the same file with my blade tempate JS

<script>
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    $(document).on('click', '.delete-btn', function(e) {
        var $this = $(this),
            $id = $(this).attr('id');

        if (confirm('Are you sure you want to delete this post?')) {
            $.post({
                type: $this.data('method'),
                url: $this.attr('href')
            }).done(function (data) {
                $('#parent-' + $id).slideUp(300, function() {
                    $(this).remove();
                });
            }).fail(function (data) {
                console.log(data);  
            });
        }

        e.preventDefault();
    });
    </script>

In your controller

public function destroy($id)
{
        Article::find($id)->delete();

        return response()->json(['success' => 'Article ID: ' . $id . ' has been deleted']);
}

Your route:

Route::delete('/delete/{post}', 'Controller@destroy')->name('delete');

HTML

<a href="#" onclick="deleteStudent()" class="nav-link">
    <span><i class="fa fa-fw fa-trash mr-1"></i> Delete Student</span>
</a>
<form id="deleteStudentForm" action="{{ route( 'students.destroy', $student->id ) }}" method="post">
    @csrf
    @method('DELETE')
</form>

JavaScript

@section('js_after')
    <script>
        function deleteStudent () {
            event.preventDefault();
            if ( confirm( "Do you really want to delete student '{{$student->stu_name}}' ?" ) ) {
                // get delete form
                var deleteForm = document.getElementById( 'deleteStudentForm' );
                // submit delete form
                deleteForm.submit();
            } else {
                return false;
            }
        }
    </script>
@endsection

本文标签: javascriptLaravel submit delete form with the press of a hrefStack Overflow