You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中通过AJAX获取输入框值用于控制器查询Where子句的问题

解决Laravel DataTable AJAX传值到控制器进行Where查询的问题

我看了你的代码,发现几个关键问题导致筛选功能没生效,下面是修正后的代码和详细说明:

一、修正AJAX部分的问题

你的AJAX代码有两个核心问题:一是没有携带CSRF令牌(Laravel会直接拒绝无令牌的POST请求),二是直接用静态对象传递data只会在初始化时获取一次输入框的值,后续输入内容变化不会同步到请求里。改成函数返回data就能实时获取最新输入值:

$(function() {
  $('#data-table').DataTable({
    "processing": true,
    "serverSide": true,
    "ajax":{
      "url": "{{ route('item_data_table') }}",
      "dataType": "json",
      "type": "POST",
      // 用函数返回data,每次请求都会重新获取输入框的最新值
      "data": function(d) {
        d._token = "{{ csrf_token() }}";
        // 参数名改成更直观的categoryname,方便控制器识别维护
        d.categoryname = $("input[name=categoryname]").val();
      }
    },
    // 你的其他DataTable配置项...
  });
});

二、修正控制器的查询逻辑

控制器里存在变量误用、筛选后未更新统计数等问题,修正后的代码如下:

use Illuminate\Http\Request;
use App\Models\MItem; // 确保正确引入模型

public function dataTable(Request $request) {
  $columns = [
    1 => 'id',
    2 => 'item_name',
    3 => 'item_category_name',
    4 => 'item_detail_category_name',
  ];

  // 用Request对象获取参数,更符合Laravel的规范写法
  $categoryname = $request->input('categoryname');
  $totalData = MItem::count();
  $totalFiltered = $totalData;

  $limit = $request->length;
  $start = $request->start;
  // 给排序字段和方向加默认值,避免前端请求参数异常时控制器报错
  $order = $columns[$request->order[0]['column']] ?? 'id';
  $dir = $request->order[0]['dir'] ?? 'asc';

  // 初始化查询构造器
  $query = MItem::select(
      'm_item.id', 
      'm_item.item_name', 
      'm_item_category.item_category_name', 
      'm_item_detail_category.item_detail_category_name'
    )
    // 关联查询时显式加上=号,语法更清晰规范
    ->join('m_item_category', 'm_item.item_category_id', '=', 'm_item_category.id')
    ->join('m_item_detail_category', 'm_item.item_category_detail_id', '=', 'm_item_detail_category.id');

  // 处理筛选条件:仅当categoryname不为空时添加where子句
  if(!empty($categoryname)) {
    // 修正你之前误用的$userID变量,替换为正确的$categoryname
    $query->where('m_item_category.item_category_name', 'like', "%{$categoryname}%");
    
    // 筛选后必须更新totalFiltered,否则分页组件会显示错误的结果数量
    $totalFiltered = $query->count();
  }

  // 执行分页和排序查询
  $items = $query->offset($start)
    ->limit($limit)
    ->orderBy($order, $dir)
    ->get();

  $data = [];
  // 把查询结果组装成DataTable要求的格式
  foreach($items as $item) {
    $data[] = [
      $item->id,
      $item->item_name,
      $item->item_category_name,
      $item->item_detail_category_name,
      // 这里可以添加其他需要显示的列
    ];
  }

  // 返回DataTable要求的标准JSON响应格式
  return response()->json([
    "draw" => intval($request->draw),
    "recordsTotal" => intval($totalData),
    "recordsFiltered" => intval($totalFiltered),
    "data" => $data
  ]);
}

关键修正点说明

  1. AJAX实时传值:用函数返回data,确保每次请求都能拿到输入框的最新内容,而不是初始化时的旧值
  2. CSRF令牌:必须携带_token参数,否则Laravel的CSRF保护机制会直接拒绝你的POST请求
  3. 变量误用修正:你之前在Where子句里用了未定义的$userID,替换为正确的$categoryname是解决问题的核心
  4. 更新过滤统计数:筛选后重新计算$totalFiltered,保证分页组件显示正确的结果数量
  5. 参数安全处理:给排序字段和方向加默认值,避免前端请求异常导致控制器报错

内容的提问来源于stack exchange,提问作者andil01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:55:29