我认为这个问题涉及.split()方法。当字符与名称的开头或名称的末尾匹配时,这似乎不起作用。
在这里查看JSFiddle:http://jsfiddle.net/5uebxvex/
作为参考,我使用Northwind数据库中的Employees表。例如,其中一名员工是Andrew Fuller
。如果您首先输入andr
,它会显示相关结果,但不会通过在结果中添加粗体,斜体和下划线HTML格式来修改结果的外观。但是,如果您首先键入与字符串中间某处匹配的字母(例如drew
),则会显示正确的结果和添加HTML格式。另外,您可以从下面的PHP中看到,您可以输入人员的全名,如rew ful
,它将显示正确匹配的员工。但是,一旦在空格后添加字符,它将停止添加格式。我真的不确定原因。
除了这个问题之外,我还注意到如果您快速输入输入文本字段,它通常会为您带来相同结果的倍数。例如,在文本字段中非常快速地键入andrew
。或者尝试快速在文本字段中输入uller
。它将带来独特的结果,直到你到达有时会带来多倍相同结果的结束。
这里发生了什么?有人可以解释这个问题是什么吗?
这里是PHP - northwind.php :(问题不在PHP中 - 请检查上面的JSFiddle)
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$db_user = 'user';
$db_pass = 'pass';
$db_name = 'name';
$db_host = 'host';
$conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
if ($conn->connection_error) { die('Connection error: '. $conn->connection_error); }
$data = $_GET ? $_GET : $_POST;
if (strlen($data['name']) > 0) {
$sql = '
SELECT
CONCAT(FirstName, " ", LastName) AS name,
EmployeeID AS id
FROM
Employees
WHERE
FirstName LIKE "%'. $data['name'] .'%"
OR
LastName LIKE "%'. $data['name'] .'%"
OR
CONCAT(FirstName, " ", LastName) LIKE "%'. $data['name'] .'%"
';
$result = $conn->query($sql) OR die('Query error: '. mysqli_error($conn));
if ($result->num_rows > 0) {
$json = array();
while ($row = $result->fetch_assoc()) {
$json[] = array('id' => $row['id'], 'name' => $row['name']);
}
print json_encode($json);
}
else { print '[]'; }
}
?>
查看上面的JSFiddle以了解其余代码。提前感谢您对上述问题的见解。
答案 0 :(得分:2)
你必须修剪JavaScript上的字符串,Typehead的值才能拆分你从结果中得到的字符串,参见一个有效的例子。
http://jsfiddle.net/5uebxvex/3/
你必须在PHP上修剪你的字符串。
当你在MySQL上搜索重新时,查询会检查每个名字的开头是什么,然后重新填充空格等等。
因此,当您在MySQL上传递完整(空格)时,您将检查任何以重新(空格)完整(空格)之后的任何内容开头的任何内容我很确定你插入它们时会修剪你的所有名字。
所以请将您的代码更新为:
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$db_user = 'user';
$db_pass = 'pass';
$db_name = 'name';
$db_host = 'host';
$conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
if ($conn->connection_error) { die('Connection error: '. $conn->connection_error); }
$data = $_GET ? $_GET : $_POST;
if (strlen($data['name']) > 0) {
$name = trim($data['name']);
$sql = '
SELECT
CONCAT(FirstName, " ", LastName) AS name,
EmployeeID AS id
FROM
Employees
WHERE
FirstName LIKE "%'. $name .'%"
OR
LastName LIKE "%'. $name .'%"
OR
CONCAT(FirstName, " ", LastName) LIKE "%'. $data['name'] .'%"
';
$result = $conn->query($sql) OR die('Query error: '. mysqli_error($conn));
if ($result->num_rows > 0) {
$json = array();
while ($row = $result->fetch_assoc()) {
$json[] = array('id' => $row['id'], 'name' => $row['name']);
}
print json_encode($json);
}
else { print '[]'; }
}
?>
但是使用Like来比较字符串并不是那么有效,而不是使用MySQL全文搜索功能。
https://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
您必须将包含文本的字段设为全文索引,并且您可以执行以下查询:
SELECT * FROM `peoples` WHERE MATCH (firstname) AGAINST ('*andrew*' IN BOOLEAN MODE);
答案 1 :(得分:2)
请在此处找到完整的代码: http://jsfiddle.net
问题:匹配的子字符串的外观未更改。匹配的子字符串应由<span class="highlight">
封装。
解决方案:由于搜索子字符串时区分大小写,会发生这种情况。这可以通过以下代码修复:
$(response).each(function(i, e) {
q = $('#typeahead').val();
//Find substring,encapsulate each substring with span.highlight.
var match = e.name.replace(new RegExp(q,"i"), function(m){
return "<span class='highlight'>"+m+"</span>"
});
$('#list').append('<li class="employeeID-'+ e.id +'">'+ match +'</li>');
});
问题:如果我们输入的查询在字符串中间的某处(员工姓名)开始,则看起来预期结果不会被返回。例如:如果我们输入drew
,则Andrew Fuller
将无法在响应数据中使用。
我认为问题在于服务器代码。 CMIIW。 我简要地查看了您的PHP代码,但无法找到问题所在的位置。我目前无法测试您的PHP代码。
由于先前的AJAX请求仍处于活动状态,因此出现此问题。如果我们快速输入'ann',那么将有3个Anne Dodsworth和2个Andrew Fuller。
您需要使用xhr.abort()
中止之前的AJAX请求。 xhr
是之前的AJAX请求(保存在变量中)。
请在此处找到完整的代码: http://jsfiddle.net
答案 2 :(得分:1)
您是否考虑过区分大小写与不区分大小写的搜索?如果你用'Andr'填充字段,它会突出显示,如果你搜索'andr'就不会。为什么?因为'安德鲁'和'安德鲁'不一样。 a和A是不同的字符,因此不匹配。显然,您的数据库忽略了这一事实并进行了不区分大小写的搜索(https://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html:“默认字符集和排序规则是latin1和latin1_swedish_ci,因此非二进制字符串比较默认情况下不区分大小写。”)而且你的.split函数也可以区分小写和大写。因此,如果您查找input-field的值,则它与您从ajax-call返回的值不同。你现在要做的是以下几点:
以下剪辑已经有效,但以小写形式显示所有内容,证明这是一个案例问题。
$(document).ready(function() {
$('#typeahead').on({
input: function() {
$('#list li').remove();
$.ajax({
url: 'http://smpl-php.com/jquery/test/northwind.php',
method: 'post',
data: { 'name': $('#typeahead').val() },
dataType: 'json',
success: function(response) {
$(response).each(function(i, e) {
var match = e.name.toLowerCase()
.split($('#typeahead').val().toLowerCase())
.join('<span class="highlight">'+ $('#typeahead').val() +'</span>');
$('#list').append('<li class="employeeID-'+ e.id +'">'+ match +'</li>');
});
},
error: function(error) {}
});
}
});
});
.highlight {
font-weight: bold;
text-decoration: underline;
font-style: italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="typeahead" type="text" />
<ul id="list"></ul>