我有一个带有文本输入和选择选项框的表单。文本字段使用自动建议,允许用户从列表中选择选项。一旦从自动建议中选择了一个值,选择选项框就会填充依赖于选择的选项。
我正在努力改变代码,使第二个框是一个文本输入,以及,以免限制用户的选择(即两个字段应该允许自由文本条目,如果用户不想从可用的选择中进行选择)。
我想我已经盯着这段代码太久了,希望能得到一些帮助。显然,需要在loadCountry
, populateSelect
和loadcountrySelect
功能中进行更改。
我使用PHP, jQuery和jQuery UI自动完成。
如果您能提供任何帮助,我将非常感激!
脚本:
<script src="../../scripts/jquery-1.6.4.js"></script>
<script src="../../scripts/jqueryui/ui/jquery.ui.core.js"></script>
<script src="../../scripts/jquery.ui.widget.js"></script>
<script src="../../scripts/jquery.ui.position.js"></script>
<script src="../../scripts/jquery.ui.autocomplete.js"></script>
<script type="text/javascript">
$(document).ready(function() {
function ord(chr) {
return chr.charCodeAt(0);
}
function chr(num) {
return String.fromCharCode(num);
}
function quote(str) {
return '"' + escape(str.replace('"', "'")) + '"';
}
String.prototype.titleCase = function () {
var chars = [" ", "-"];
var ths = String(this).toLowerCase();
for (j in chars){
var car = chars[j];
var str = "";
var words = ths.split(car);
for(i in words){
str += car + words[i].substr(0,1).toUpperCase() + words[i].substr(1);
}
ths = str.substr(1);
}
return ths;
}
function incrementTerm(term) {
for (var i = term.length - 1; i >= 0; i--){
var code = term.charCodeAt(i);
if (code < ord('Z'))
return term.substring(0, i) + chr(code + 1);
}
return '{}'
}
function parseLineSeperated(data){
data = data.split("'n");
data.pop(); // Trim blank element after ending newline
var out = []
for (i in data){
out.push(data[i].titleCase());
}
return out;
}
function guess(value){
var oldValue = $('.continent_autocomplete').val();
if (oldValue == value)
return;
$('.continent_autocomplete').val(value);
$('.continent_autocomplete').caret(oldValue.length, value.length);
}
function clearGuess(){
var field = $('.continent_autocomplete');
field.val(field.val().substring(0, field.caret().start));
}
function loadcontinent(request, response) {
var startTerm = request.term.toUpperCase();
var endTerm = incrementTerm(startTerm);
$.ajax({
url: '/db/continent.php?startkey='+startTerm+'&endkey='+endTerm,
success: function(data) {
var items = parseLineSeperated(data);
response(items);
},
error: function(req, str, exc) {
alert(str);
}
});
}
function loadcountry(handler) {
var continent = $('.continent_autocomplete').val().toUpperCase();
$.ajax({
url: '/db/country.php?key=' + continent,
success: function(data) {
handler(parseLineSeperated(data));
},
error: function(req, str, exc) {
alert(str);
}
});
}
function populateSelect(select, options) {
select.html('');
if (options.length) {
enableSelect();
for (i in options){
var option = options[i];
select.append($('<option></option>').val(option).html(option));
}
} else {
disableSelect('Country');
}
}
function loadcountrySelect(continentObj){
disableSelect('Loading...');
loadcountry(function(options){
populateSelect($('.country_autocomplete'), options);
});
}
function disableSelect(message){
var select = $('.country_autocomplete');
select.html("<option>" + message + "</option>");
select.attr('disabled', true);
}
function enableSelect(){
var select = $('.country_autocomplete');
select.attr('disabled', false);
}
populateSelect($(".country_autocomplete"), []);
$("input.continent_autocomplete").autocomplete({
source: loadcontinent,
select: function(event, ui){
$("input.continent_autocomplete").val(ui.item.value);
loadcountrySelect(event.target);
}
});
$("input.continent_autocomplete").keyup(function (event){
var code = (event.keyCode ? event.keyCode : event.which);
if (code == 8) { // Backspace
clearGuess();
}
event.target.value = event.target.value.titleCase();
loadcountrySelect(event.target);
});
});
</script>
HTML:
<div id="continent_name">
<label> Continent Name:</label>
<input type="text" id="continent_name" name="continent_name" class="continent_autocomplete" />
</div>
<div id="country">
<label> Country:</label>
<input type="text" id="country_autocomplete" name="country_autocomplete" class="country_autocomplete" />
</div>
continent.php
<?php
$db_host = 'XXX';
$db_user = 'XXX';
$db_password = 'XXX';
$db_name = 'XXX';
$db = new mysqli($db_host , $db_user ,$db_password, $db_name);
if(!$db) {
echo 'There was a problem connecting to the database';
} else {
if(isset($_GET['startkey'])) {
$mysearchString = $db->real_escape_string($_GET['startkey']);
if(strlen($mysearchString) >0) {
$query = $db->query("SELECT DISTINCTROW Continent
FROM locations
WHERE Continent
LIKE '$mysearchString%'
LIMIT 10");
if($query) {
while ($result = $query ->fetch_object()) {
print ucwords(strtolower($result->Continent))."'n";
}
} else {
echo 'ERROR: There was a problem with the query.';
}
} else {
}
} else {
echo 'Access denied.';
}
}
?>
country.php
<?php
$db_host = 'XXX';
$db_user = 'XXX';
$db_password = 'XXX';
$db_name = 'XXX';
$db = new mysqli($db_host , $db_user ,$db_password, $db_name);
if(!$db) {
echo 'There was a problem connecting to the database';
} else {
if(isset($_GET['key'])) {
$mysearchString = $db->real_escape_string($_GET['key']);
if(strlen($mysearchString) >0) {
$query = $db->query("SELECT Continent,Country,Abbrev
FROM locations
WHERE Continent
LIKE '$mysearchString%'
ORDER BY Country
LIMIT 20");
if($query) {
while ($result = $query ->fetch_object()) {
print ucwords(strtolower($result->Country))."/".
ucwords(strtolower(strtok($result->Abbrev,";")))."'n";
}
} else {
echo 'ERROR: There was a problem with the query.';
}
} else {
}
} else {
echo 'Access denied.';
}
}
?>
您将需要修改PHP以使其最佳工作(过滤发生在服务器上)。我将更新您的PHP,以便它查询数据库的两个参数(一个为国家,一个为大陆):
$continent = $db->real_escape_string($_GET['continent']);
$country = $db->real_escape_string($_GET['country']);
$query = $db->query("SELECT Continent,Country,Abbrev
FROM locations
WHERE Continent ='$continent' and Country like '$country%'
ORDER BY Country
LIMIT 20");
请谨慎服用;我不懂PHP)
基本上,传递一个大陆(在第一个input
中选择)以及国家搜索字符串(在第二个输入中键入)。
接下来,您需要将自动完成小部件应用到第二个input
。比如:
$("#country_autocomplete").autocomplete({
source: function (request, response) {
var continent = $("#continent_autocomplete").val()
, country = request.term;
$.ajax({
url: '/db/country.php?continent=' + continent + "&country=" + country,
success: function(data) {
response(parseLineSeperated(data));
},
error: function(req, str, exc) {
alert(str);
}
});
}
});
只是为了一些润色,当#continent_autocomplete
改变时,你可能想要清除#country_autocomplete
。您可以为自动完成的change
事件添加一个事件处理程序:
$("input.continent_autocomplete").autocomplete({
source: loadcontinent,
change: function () {
$("#country_autocomplete).val('');
}
});
最后,您将需要删除与填充国家select
有关的任何代码,因为您不再需要它。
像Google一样的jQuery插件Autocomplete支持这样的功能:
autocomplete.php (agly style,整个逻辑放在一个地方——只是为了展示原理)
if(!empty($_GET['foo_name']) && !empty($_GET['bar_number'])) {
$sql = 'SELECT ... FROM ... WHERE';
$db = new MySQLi(...);
$db->query($sql);
$numbers = [];
while($row = $result->fetch_assoc()){
$numbers[] = $row['bar_number'];
}
}
echo json_encode($numbers);
autocomplete.html
<link href="/components/autocompletelikegoogle/jquery.autocomplete.css" media="screen" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/components/autocompletelikegoogle/jquery.autocomplete.js"></script>
<script type="text/javascript" src="/js/autocomplete.js"></script>
<input type="text" name="foo_name" id="foo-name" value="">
<input type="text" name="bar_number" id="bar-number" value="">
autocomplete.js
$(function() {
$("#foo").autocomplete({
minLength: 3,
limit: 5,
source : [{
url:"/my/ajax/controller/foo?data[foo_name]=%QUERY%",
type:'remote'
}],
});
});
$(function() {
$("#bar").autocomplete({
minLength: 3,
limit: 5,
appendMethod:'replace',
source : [
function(query, add) {
fooName = $('#foo-name').val();
$.getJSON("/my/ajax/controller/bar?data[bar_number]=" + query + "&data[foo_name]=" + fooName, function(response) {
add(response);
})
}],
});
});