代码之家  ›  专栏  ›  技术社区  ›  ST80

Laravel如何避免在使用QueryBuilder时重新加载页面

  •  0
  • ST80  · 技术社区  · 6 年前

    在我的 laravel -我使用的应用程序 spatie/laravel-query-builder 按某些类别筛选作业列表。

    所以我的代码现在看起来像这样:

    我的控制器:

    public function index(Request $request) {
    
        $regions = Region::all();
        $jobtypes = JobType::all();
        $industries = Industry::all();
    
        $jobs = QueryBuilder::for(Job::class)
            ->allowedFilters([
                AllowedFilter::exact('region', 'region_id'),
                AllowedFilter::exact('jobtype', 'job_type_id'),
                AllowedFilter::exact('industry', 'industry_id')
            ])
            ->get();
    
        return view('job.index', compact('jobs', 'regions', 'jobtypes', 'industries'));
    }
    

    我的刀片视图:

    <form method="GET" id="jobfilter-form" enctype="multipart/form-data" content="{{ csrf_token() }}">
       <div>
        <p>Location</p>
        @foreach ($regions as $region)
        <label for="{{$region->id}}">
            <input type="checkbox" class="chk-filter" name="region" value="{{$region->id}}" />
            @if (in_array($region->id, explode(',', request()->input('filter.region'))))
            checked
            @endif
            {{$region->name}}
        </label>
        @endforeach
      </div>
    
      <div>
        <p>Job type</p>
        @foreach ($jobtypes as $jobtype)
        <label for="{{$jobtype->id}}">
            <input type="checkbox" class="chk-filter" name="jobtype" value="{{$jobtype->id}}" />
            @if (in_array($jobtype->id, explode(',', request()->input('filter.jobtype'))))
            checked
            @endif
            {{$jobtype->name}}
        </label>
        @endforeach
      </div>
    
      <div>
        <p>Industry</p>
        @foreach ($industries as $industry)
        <label for="{{$industry->id}}">
            <input type="checkbox" class="chk-filter" name="industry" value="{{$industry->id}}" />
            @if (in_array($industry->id, explode(',', request()->input('filter.industry'))))
            checked
            @endif
            {{$industry->name}}
        </label>
        @endforeach
      </div>
    
      <div>
        <button type="submit" id="filter">filter</button>
      </div>
    </form>
    

    最后是javascript:

    function getIds(checkboxName) {
      let checkBoxes = document.getElementsByName(checkboxName);
      let ids = Array.prototype.slice
        .call(checkBoxes)
        .filter(ch => ch.checked == true)
        .map(ch => ch.value);
      return ids;
    }
    
    function filterResults() {
      let regionIds = getIds("region");
    
      let jobtypeIds = getIds("jobtype");
    
      let industryIds = getIds("industry");
    
      let href = "filter?";
    
      if (regionIds.length) {
         href += "filter[region_id]=" + regionIds;
      }
    
      if (jobtypeIds.length) {
         href += "&filter[job_type_id]=" + jobtypeIds;
      }
    
      if (industryIds.length) {
        href += "&filter[industry_id]=" + industryIds;
      }
    
      document.location.href = href;
    }
    
    
    $("#jobfilter-form #filter").on("click", e => {
      filterResults();
    });
    

    这基本上工作得很好,但这种解决方案(当然)会在每次单击提交按钮时重新加载页面,并取消选中所有之前选中的复选框。

    所以我的问题是:我能避免页面被重新加载吗?我如何保留选中的复选框?

    另一件事是,我在考虑使用这样的东西:

    $(".chk-filter").on("change", function() {
       if (this.checked) {
         $('#jobfilter-form button[type="submit"]').click();
       }
    });
    

    并隐藏提交按钮。

    有人能帮帮我吗?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Martin Zeitler    6 年前

    当您更新URL并使其导航时,这可能会重新加载页面。最好添加一个额外的路由,它接受这些参数并返回JSON。然后,您可以将web 1.0风格转换为动态形式,该形式使用XHR进行获取,然后相应地操纵DOM。CSRF令牌需要 passed along 使用XHR,但通常不需要表单,因为JS会获取JSON&更新DOM(这将是显示结果的区域)。当从不提交任何表单时,页面将不会重新加载,复选框将保持原样。