Laravel Yajra 不接受 post/get 查询请求

Posted

技术标签:

【中文标题】Laravel Yajra 不接受 post/get 查询请求【英文标题】:Laravel Yajra is not accepting post/get request on query 【发布时间】:2021-10-27 03:09:51 【问题描述】:

我正在使用 Yajra 数据表。在我决定过滤结果之前,它工作正常。例如:这就是我对 Yajra(在控制器中)的查询的样子

if ($request->ajax()) 

        $data = product::get(); //SQL QUERY

        return Datatables::of($data)
                ->addIndexColumn()                    
                ->addColumn('action', function($row)
 
                    $btn = '<a href="'.url('product/'.base64_encode($row->id).'').'" class="edit" target="_blank"><i class="fa fa-eye" aria-hidden="true"></i></a> <a href="'.url('/').'/export?product_id='.$row->id.'&productname='.$row->product_name.'"><i class="fa fa-download" aria-hidden="true"></i></a>';

                        return $btn;
                )
                ->rawColumns(['image','discount','dt','action'])
                ->make(true);
    

如您所见,这就是我定义 sql 查询的方式,并且运行良好。

$data = product::get();

但后来我决定过滤结果。我不想显示所有结果,而是在 POST 函数的帮助下根据 where 条件显示一些结果。

所以我用这个替换了之前的查询行

 $data = product::select('*');
    
  //POST request
  if($request->has('vendor_list'))
    $data = $data->where('vendor', $request->vendor_list);
  
       $data = $data->get();

为了检查$request-&gt;vendor_list 是否真的有一些价值,我尝试打印$request-&gt;vendor_list 并且价值正在被打印出来。所以$request-&gt;vendor_list 里面有值。

当我尝试在 where 条件下手动添加值而不是 POST 函数时,它开始工作。像这样

$data = product::select('*');
$data = $data->where('vendor', 'vendor_name'); //MANUALLY typed value
$data = $data->get();

如果我从 GET 或 POST(都尝试过)获得价值,那么不明白为什么 yajra 在 where 条件下不接受价值?

更新

查看文件

<form action="" id="search_formm" method="GET">
    @csrf
    <div class="row">
        <div class="col-md-12">
            <div class="search_box">
                <div id="category_wrap" style="display: none;">
                    <div class="form-group">  
                        <label>Select category</label>
                        <select name="category_list" id="category_list" class="form-control">
                          <option value="">Select</option>
                            @foreach($categories as $category)
                                <option value="$category->category_name" @if(request()->category_list == $category->category_name) selected @endif>$category->category_name</option>
                            @endforeach
                        </select>
                    </div>
                </div>
                <div id="vendor_wrap" style="display: none;">
                    <div class="form-group">  
                        <label>Select Vendor</label>
                        <select name="vendor_list" id="vendor_list" class="form-control">
                          <option value="">Select</option>
                            @foreach($vendors as $vendor)
                                <option value="$vendor->vendor_name" @if(request()->vendor_list == $vendor->vendor_name) selected @endif>$vendor->vendor_name</option>
                            @endforeach
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <input type="submit" id="search-btnn" class="btn btn-primary" value="Search">
                </div>
            </div>
        </div>
    </div>
</form>
    <!--BELOW THIS FORM I AM USING YAJRA SCRIPT AND TABLE TAGS TO PRINT?SHOW ROWS FROM DB-->

控制器功能

function productList(Request $request)
    if ($request->ajax()) 

        $data = product::select('*');

        if($request->has('category_name'))
            $data = $data->where('category', $request->category_name);
        

        if($request->has('vendor_list'))
            $data = $data->where('vendor', $request->vendor_list);
        

         $data = $data->get();

        return Datatables::of($data)
                ->addIndexColumn()
                ->addColumn('image', function($row)
                    if(!empty($row->product_image))
                        $image = '<a href="'.asset('dashboard_assets/images/'.$row->product_image).'" target="_blank"><img src="'.asset('dashboard_assets/images/'.$row->product_image).'" ></a>';
                    else
                        $image = 'NA';
                    

                     return $image;
             )
                ->addColumn('dt', function($row)
 
                    $date = date("m/y", strtotime($row->created_at));

                     return $date;
             )
             ->addColumn('discount', function($row)
                
                if(!empty($row->product_discount))
                    $discount = $row->product_discount.'%';
                else
                    $discount = 'NA';
                

                 return $discount;
         )
                ->addColumn('action', function($row)
 
                    $btn = '<a href="'.url('product/'.base64_encode($row->id).'').'" class="edit" target="_blank"><i class="fa fa-eye" aria-hidden="true"></i></a> <a href="'.url('/').'/export?product_id='.$row->id.'&productname='.$row->product_name.'"><i class="fa fa-download" aria-hidden="true"></i></a>';

                        return $btn;
                )
                ->rawColumns(['image','discount','dt','action'])
                ->make(true);
    

    return view('products');

【问题讨论】:

您检查的是 $request->has('vendor'),而不是 vendor_list. @CuongLeNgoc 是的,我知道。我收到了多个 POST 值。即使我删除 if 条件仍然 Yajra 不允许我在 where 条件下使用任何 php 变量或 Post $request。 @CuongLeNgoc 即使在 php 变量中使用存储 $request-&gt;vendor_list 值并在像 $data = $data-&gt;where('vendor', $vendor); 这样的地方使用该变量,它仍然不起作用。似乎 yajra 只接受引用中的手动值,而不是变量(在 where 条件下)。 尝试 $data = product::where('vendor', $request->vendor_list); return Datatables::of($data) ->addIndexColumn() 所以不需要调用 get 因为数据表句柄 你能发布你得到的错误吗? 【参考方案1】:

这样试试

if($request->has('vendor_list'))
    $data = $data->whereRaw("`vendor` = '".$request->vendor_list."'");

【讨论】:

先生,我已经试过了。问题是,如果条件永远不会成立,因为 yajra 会忽略每个 $request-&gt;anyname 和 php 变量。它只接受手动输入的值,不接受 php 变量。 您能否在发送 POST 请求时提及您的 javascript 或 jQuery 代码 嗨,我没有用 JS 发送 POST 请求。我用简单的 laravel 形式发送。无需任何 JS 参与的默认表单提交。【参考方案2】:

据我了解,您正在尝试使用 yajra 数据表实现 lazy loadingreal-time searching。对于初学者,您不必使用get(),因为它不会实现延迟加载。 Yajra-datatable 足够聪明,可以将它与按列名搜索一起使用。

但是,您仍然需要手动进行搜索,请关注this。这是非常直接的实现。

此外,如果您计划连接多个数据库表,或者您的数据库表的列名与数据表的列名不匹配,请确保正确映射两个列名。您可以在此处找到参考。

    <script type="text/javascript">
    $(function () 
    
    var table = $('.yajra-datatable').DataTable(
        processing: true,
        serverSide: true,
        ajax: " route('product.list') ", //or you can use the url with the parameters like /product/1 or prodcut?vendor=1
        columns: [
            data: 'DT_RowIndex', name: 'DT_RowIndex',
            data: 'name', name: 'name',
            data: 'vendor', name: 'vendor',
            data: 'data_table_column', name: 'db_table_column',
            .
            .
            
                data: 'action', 
                name: 'action', 
                orderable: false, 
                searchable: false
            ,
        ]
    ); 

这就是你所要做的。其余的(搜索/排序)将由 yajra-datables 处理。

现在,如果您有任何参数必须通过 url/request 传递,然后获取它们。并检查它们是否为空。

   $vendor = $request->vendor;
   $data = null;
   if(is_null($vendor)) 
      $data = Product::query();
    else 
      $data = Product::where('vendor', $vendor);
   
   
   return $data->....

因为,如果供应商是 null,那么 laravel 会检查数据库中是否有等于 nullvendor。没有什么是匹配的,它返回一个空对象。也许这就是为什么您没有收到任何错误,但也没有收到任何数据的原因。

【讨论】:

您好,先生,我尝试了您的解决方案。这就是我所做的,$v = $request-&gt;vendor_list;if(is_null($v)) $data = product::get(); else $data = product::where('vendor', $v); 它总是在if 条件下,而不是在else 条件下。我试图打印$v 的值,它是打印值。所以$v 有价值。但问题是,Yajra 忽略了每个 php 变量。它甚至不考虑php var。这是主要问题。哪里有 php var,Yajra 认为它什么都不是。 你能告诉我你想用请求参数做什么吗?它是查询字符串还是 url 变量?这个问题什么时候来?首次加载页面或在数据表中搜索或排序数据时? 我有一个字段很少的表单。表单的action 为空,表示表单在同一页面上提交。当我提交时,我得到了 POST/GET(尝试了两个)值。我使用$request-&gt;form_field_name 获取它们。所有值都是字符串类型。当我尝试在控制器中使用echo 打印时(在 yajara 启动之前),它就是打印值。但在 yajra 内部,它被 yajra 忽略了。 就像 yajra 说的: I won't be accepting any POST/GET values or any PHP variable. If you want me to use any value then type manually, do not store in variable or simillar. 在我看来,您可能以非传统方式使用 yajra,可能不是 yajra 的用途。 Yajra 旨在处理(搜索/排序/分页)表中(或其版本)中的数据。但是,我可能又错了。如果您有任何可共享的源代码链接,请分享。还请使用视图(使用表单和您希望 yajra 显示数据的位置)和完整的控制器方法更新帖子。 您好,我已按照您的要求使用viewcontroller 更新了我的帖子。请检查【参考方案3】:

您更改 product::get(); 是对的,因为它返回您所有项目的集合,而不是“SQL”(雄辩的)实例。所以所有过滤都不是在 SQL 查询级别完成的。

如果您的输入 vendor_list 是与 products.vendor 列值中的值完全匹配的字符串:

你可以试试

    if(request()->has('vendor_list'))
        $data = $data->where('vendor', $request->input('vendor_list'));
    //if vendor_list is an array
    // $data = $data->whereIn('vendor', $request->input('vendor_list'));
    

    //here you should apply some pagination to your query, based on the frontend datatable page parameter.
    $data = $data->get();

但是由于您的输入被命名为vendor_list:您是在发回一个数组吗?如果是这样,您应该使用$data-&gt;whereIn('vendor', $request-&gt;input('vendor_list'))。如果它是供应商值的字符串列表供应商,例如vendor1,vendor2...,则将其分解然后whereIn 等。

【讨论】:

您好,先生,遗憾的是if 条件永远不会成立。即使查询变量有值,它也总是转到else 请转储$request-&gt;input('vendor_list') 以确保它包含可以与列值匹配的字符串。我猜你的问题来自输入格式。 您也可以转储request()-&gt;all() 之类的内容来仔细检查输入格式吗? 我尝试存储一个查询值并使用request()-&gt;all() 执行dump 并收到此array(1) ["vendor_list"]=&gt; string(4) "Elmo" 。我在 yajara 代码开始之前做了dumb(控制器功能的第一行。虽然它打印了提到的数组,但 yajra 表在警报invalid json response 中给出了错误,并将显示行存储在表中。当我删除dump 时,表行开始出现再次。 好的,所以输入看起来是正确的。 Elmo 值将与您的数据库中的某些内容匹配?您可以尝试转储 request()-&gt;has('vendor_list') 吗?因为如果有效负载是您唯一转储的,它应该返回 true。

以上是关于Laravel Yajra 不接受 post/get 查询请求的主要内容,如果未能解决你的问题,请参考以下文章

yajra/laravel-datatables 搜索不适用于 laravel 5.4

Laravel 8 Yajra DataTable 在同一页面刷新

yajra/laravel-datatables 搜索不适用于 laravel 5.7

yajra / laravel-datatables搜索不适用于laravel 5.4

laravel Yajra Datatable

如何在 yajra 数据表 laravel 中添加操作列