【问题标题】:Laravel submit delete form with the press of a hrefLaravel 使用 href 提交删除表单
【发布时间】:2018-01-18 20:04:20
【问题描述】:

我在 Laravel 5.4 中有一个表格,它显示具有删除选项的新闻。 代码如下: 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

我的问题是我如何告诉 javascript 准确提交紧邻 a href 的表单,因为现在它会提交第一个与 id 匹配的表单,而该 id 并不总是与单击的 td 相同一个href

编辑: 我知道我可以尝试使用 jquery 访问单击的 href 的父级,然后访问它的子窗体或使用 jquery 的关闭功能,但我正在寻找更稳定的东西。

【问题讨论】:

  • 如果任何答案对您有帮助,请将其标记为已接受。如果您自己找到解决方案,请不要犹豫分享!

标签: javascript jquery forms laravel


【解决方案1】:

在做任何事情之前,您的路线应该是(如果尚未完成):
Route::delete(...)-&gt;name('delete-article');

我认为你可以这样做:

   <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>

或者使用 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>

您必须在文档头中指定&lt;meta name="csrf-token" content="{{ csrf_token() }}"&gt;。 (https://laravel.com/docs/5.4/csrf#csrf-x-csrf-token)

【讨论】:

  • 我也想过这种方法,但我又在寻找更稳定的方法。 (如果可能)
  • 你说的更稳定是什么意思?
  • 也许您可以使用 Ajax 而不是每次都指定表单。我编辑我的答案。
  • 这个方法看起来很棘手。这是一种作弊和黑客入侵
  • @TheAngelM97 看看我的回答。 Ajax 听起来像是在欺骗你?为什么?
【解决方案2】:

Benjamin Brasseur 为您提供了一种使用 AJAX 的方法。 (顺便说一句,我认为这并不“棘手”)

但是,使用您当前的 javascript,您似乎只是提交了一个隐藏的表单。为什么不使用真实的表格?

<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>

如果视觉效果不同,请调整 &lt;form&gt; 的样式(使其成为 inline-block 或其他内容)和 &lt;button&gt; 的样式以匹配您的旧 &lt;a&gt;

【讨论】:

    【解决方案3】:

    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>
    

    在你的脑海中添加:

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

    我的脚本与我的刀片模板在同一个文件中 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>
    

    在你的控制器中

    public function destroy($id)
    {
            Article::find($id)->delete();
    
            return response()->json(['success' => 'Article ID: ' . $id . ' has been deleted']);
    }
    

    您的路线:

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

    【讨论】:

      【解决方案4】:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-19
        • 2018-11-12
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 2021-01-13
        • 2015-02-05
        • 2020-03-25
        相关资源
        最近更新 更多