使用两个 table 列在 Laravel 5.5 和 Typeahead.js 中自动完成搜索
Autocomplete Search in Laravel 5.5 with Typeahead.js using two table columns
我有一个如下所示的数据库:
-------------------------------------
| id | FirstName | LastName | Email |
-------------------------------------
| 1 | Test | Customer | null |
| 2 | Some | Name | null |
-------------------------------------
现在我想要的是通过匹配 FirstName 和 LastName 来获取客户的 ID...如果在一行中找到它们,那么就去获取 ID。
我正在使用 Laravel 5.5.28 并尝试了 Typeahead.js 以实现我最初想要的,但出于某种原因,我只能使用 FirstName 或 LastName 中的一列。
这是工作代码(仅适用于 FirstName):
CDN 的
<script src="{{ asset('js/vendor/jquery.min.js') }}"></script>
<script src="{{ asset('js/vendor/popper.min.js') }}"></script>
<script src="{{ asset('js/vendor/bootstrap.min.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.1/bootstrap3-typeahead.min.js"></script>
SearchController.php
public function autocomplete(Request $request)
{
$datas = Customers::select("FirstName")
->where("FirstName", "LIKE","%{$request->input('query')}%")
->get();
$dataModified = array();
foreach ($datas as $data)
{
$dataModified[] = $data->FirstName;
}
return response()->json($dataModified);
}
}
正在获取id "JobsController.php"
public function store(Request $request)
{
$job = new Jobs;
$job->cust_id = Customers::where('FirstName', $request->input('customer_name'))->value('id');
dump($job->cust_id);
}
这是观点:
{!! Form::open(['action' => 'JobsController@store', 'method' => 'POST']) !!}
{{Form::text('customer_name', '', ['class' => 'form-control typeahead', 'placeholder' => 'Type in customer name...'])}}
{{Form::submit('Create Job', ['class' => 'btn btn-primary mt-2'])}}
{!! Form::close() !!}
路线
Route::get('jobs.create', 'SearchController@index')->name('search');
Route::get('autocomplete', 'SearchController@autocomplete')->name('autocomplete');
jQuery
<script type="text/javascript">
var path = "{{ route('autocomplete') }}";
$('input.typeahead').typeahead({
source: function(query, process) {
return $.get(path, { query: query }, function(data) {
return process(data);
});
}
});
</script>
现在一切正常,但仅适用于 FirstName。我想要的是让它适用于全名 (FirstName + LastName)
我设法让它与 FirstName 和 LastName 一起工作,但只是在 "front-end" 上...它没有从数据库中获取 ID。
为了在自动完成建议(开始输入时)中同时包含 FirstName 和 LastName,我做了以下操作:
SearchController.php
public function autocomplete(Request $request)
{
$datas = Customers::select("FirstName", "LastName")
->where("FirstName", "LIKE","%{$request->input('query')}%")
->get();
$dataModified = array();
foreach ($datas as $data)
{
$dataModified[] = $data->FirstName .' '. $data->LastName;
}
return response()->json($dataModified);
}
输入时同时显示名字和姓氏,但返回空值 "id"。
我希望能够在我的查询中同时使用 FirstName 和 LastName 列,这样我只能在 FirstName 和 LastName 匹配时获得 ID。
期待您的想法。
感谢您的宝贵时间。非常感谢。
更新 #1
与此同时,我更改了 SearchController 中的查询,所以我认为这里的代码现在没问题了:
$datas = Customers::select("FirstName", "LastName")
->where(function($q) use($request) {
$q->where("FirstName", "LIKE","%{$request->input('query')}%")
->orWhere("LastName", "LIKE","%{$request->input('query')}%");
})->get();
唯一的问题是我仍然得到 "null" 个 ID。
可能是因为我尝试获取 ID 的方式?
在 JobsController 我有这样的 "store" 方法:
public function store(Request $request)
{
$job = new Jobs;
$job->cust_id = Customers::where('FirstName', $request->input('customer_name'))
->orWhere('LastName', $request->input('customer_name'))
->value('id');
}
这是获取 ID 的正确方法吗?
更新 #2
我担心 $request->input 没有返回正确的格式,这就是我在查询中得到 'null' id 的原因,但我错了,因为一个简单的 dump();显示 $request->input 正在返回预期的字符串。
我真的运行没主意了。也许我应该使用不同的方式来获取 id ?就像在 url ?
中使用 id
非常感谢任何想法和建议。谢谢。
我使用下面的代码工作正常
我的控制器功能
public function Search(Request $request)
{
$data = Account::Join('groups','groups.group_id','=','accounts.group_id')->select("accounts.name","accounts.account_id","groups.group_name")
->where("name","LIKE","%".Input::get('query')."%")
->get()->toArray();
return response()->json($data);
}
我的推特提前打字
var data = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: "{{route('accounts/search')}}",
remote: {
url: "{{url('accounts/search')}}?query=%query",
transform: function(list) {
return $.map(list, function(k,v) { return { id: k.account_id, name: k.name,group:k.group_name }; });
},
wildcard: '%query'
}
});
$('.typeahead').typeahead(null, {
hint: true,
limit:100,
highlight: true,
minLength: 1,
name: 'Accounts',
displayKey: function(k) {
return k.name + " - ("+k.group+")";
},
source: data,
templates: {
empty: [
'<div class="empty-message">',
'<span><strong>Account Not Found</strong></span><br/>',
'<button type="button" class="btn btn-info" id="account_modal">+ Add New Account</button>',
'</div>'
].join('\n'),
}
}).on('typeahead:selected', function (e, suggestion, name) {
$(this).parent().next().val(suggestion.id);
$(this).parent().next().next().remove();
});
所以我终于解决了这个问题。我必须使用 CONCAT "FirstName" 和 "LastName" 才能获得 id,因为如果没有 CONCAT,我的代码会将 $request->input 与两列(FirstName、LastName)进行比较,并且永远不会匹配。
JobsController 中的工作查询:
$field = DB::raw("CONCAT(`FirstName`, ' ', `LastName`)");
$query = $request->input('custName');
$job = new Jobs;
$job->cust_id = Customers::where($field, "LIKE", "%{$query}%")->value('id');
感谢大家的宝贵时间。非常感谢。
我有一个如下所示的数据库:
-------------------------------------
| id | FirstName | LastName | Email |
-------------------------------------
| 1 | Test | Customer | null |
| 2 | Some | Name | null |
-------------------------------------
现在我想要的是通过匹配 FirstName 和 LastName 来获取客户的 ID...如果在一行中找到它们,那么就去获取 ID。
我正在使用 Laravel 5.5.28 并尝试了 Typeahead.js 以实现我最初想要的,但出于某种原因,我只能使用 FirstName 或 LastName 中的一列。
这是工作代码(仅适用于 FirstName):
CDN 的
<script src="{{ asset('js/vendor/jquery.min.js') }}"></script>
<script src="{{ asset('js/vendor/popper.min.js') }}"></script>
<script src="{{ asset('js/vendor/bootstrap.min.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.1/bootstrap3-typeahead.min.js"></script>
SearchController.php
public function autocomplete(Request $request)
{
$datas = Customers::select("FirstName")
->where("FirstName", "LIKE","%{$request->input('query')}%")
->get();
$dataModified = array();
foreach ($datas as $data)
{
$dataModified[] = $data->FirstName;
}
return response()->json($dataModified);
}
}
正在获取id "JobsController.php"
public function store(Request $request)
{
$job = new Jobs;
$job->cust_id = Customers::where('FirstName', $request->input('customer_name'))->value('id');
dump($job->cust_id);
}
这是观点:
{!! Form::open(['action' => 'JobsController@store', 'method' => 'POST']) !!}
{{Form::text('customer_name', '', ['class' => 'form-control typeahead', 'placeholder' => 'Type in customer name...'])}}
{{Form::submit('Create Job', ['class' => 'btn btn-primary mt-2'])}}
{!! Form::close() !!}
路线
Route::get('jobs.create', 'SearchController@index')->name('search');
Route::get('autocomplete', 'SearchController@autocomplete')->name('autocomplete');
jQuery
<script type="text/javascript">
var path = "{{ route('autocomplete') }}";
$('input.typeahead').typeahead({
source: function(query, process) {
return $.get(path, { query: query }, function(data) {
return process(data);
});
}
});
</script>
现在一切正常,但仅适用于 FirstName。我想要的是让它适用于全名 (FirstName + LastName)
我设法让它与 FirstName 和 LastName 一起工作,但只是在 "front-end" 上...它没有从数据库中获取 ID。
为了在自动完成建议(开始输入时)中同时包含 FirstName 和 LastName,我做了以下操作:
SearchController.php
public function autocomplete(Request $request)
{
$datas = Customers::select("FirstName", "LastName")
->where("FirstName", "LIKE","%{$request->input('query')}%")
->get();
$dataModified = array();
foreach ($datas as $data)
{
$dataModified[] = $data->FirstName .' '. $data->LastName;
}
return response()->json($dataModified);
}
输入时同时显示名字和姓氏,但返回空值 "id"。
我希望能够在我的查询中同时使用 FirstName 和 LastName 列,这样我只能在 FirstName 和 LastName 匹配时获得 ID。
期待您的想法。
感谢您的宝贵时间。非常感谢。
更新 #1
与此同时,我更改了 SearchController 中的查询,所以我认为这里的代码现在没问题了:
$datas = Customers::select("FirstName", "LastName")
->where(function($q) use($request) {
$q->where("FirstName", "LIKE","%{$request->input('query')}%")
->orWhere("LastName", "LIKE","%{$request->input('query')}%");
})->get();
唯一的问题是我仍然得到 "null" 个 ID。
可能是因为我尝试获取 ID 的方式?
在 JobsController 我有这样的 "store" 方法:
public function store(Request $request)
{
$job = new Jobs;
$job->cust_id = Customers::where('FirstName', $request->input('customer_name'))
->orWhere('LastName', $request->input('customer_name'))
->value('id');
}
这是获取 ID 的正确方法吗?
更新 #2
我担心 $request->input 没有返回正确的格式,这就是我在查询中得到 'null' id 的原因,但我错了,因为一个简单的 dump();显示 $request->input 正在返回预期的字符串。
我真的运行没主意了。也许我应该使用不同的方式来获取 id ?就像在 url ?
中使用 id非常感谢任何想法和建议。谢谢。
我使用下面的代码工作正常
我的控制器功能
public function Search(Request $request)
{
$data = Account::Join('groups','groups.group_id','=','accounts.group_id')->select("accounts.name","accounts.account_id","groups.group_name")
->where("name","LIKE","%".Input::get('query')."%")
->get()->toArray();
return response()->json($data);
}
我的推特提前打字
var data = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: "{{route('accounts/search')}}",
remote: {
url: "{{url('accounts/search')}}?query=%query",
transform: function(list) {
return $.map(list, function(k,v) { return { id: k.account_id, name: k.name,group:k.group_name }; });
},
wildcard: '%query'
}
});
$('.typeahead').typeahead(null, {
hint: true,
limit:100,
highlight: true,
minLength: 1,
name: 'Accounts',
displayKey: function(k) {
return k.name + " - ("+k.group+")";
},
source: data,
templates: {
empty: [
'<div class="empty-message">',
'<span><strong>Account Not Found</strong></span><br/>',
'<button type="button" class="btn btn-info" id="account_modal">+ Add New Account</button>',
'</div>'
].join('\n'),
}
}).on('typeahead:selected', function (e, suggestion, name) {
$(this).parent().next().val(suggestion.id);
$(this).parent().next().next().remove();
});
所以我终于解决了这个问题。我必须使用 CONCAT "FirstName" 和 "LastName" 才能获得 id,因为如果没有 CONCAT,我的代码会将 $request->input 与两列(FirstName、LastName)进行比较,并且永远不会匹配。
JobsController 中的工作查询:
$field = DB::raw("CONCAT(`FirstName`, ' ', `LastName`)");
$query = $request->input('custName');
$job = new Jobs;
$job->cust_id = Customers::where($field, "LIKE", "%{$query}%")->value('id');
感谢大家的宝贵时间。非常感谢。