我在PHP页面中使用jQuery UI Autocomplete来获取位置服务。特别是这个使用Remote JSONP数据源类型。我遇到的问题很奇怪,只有一种方式发生。
以下是发生的事情:
换句话说,如果用户输入Location
,则会传递Location
。如果用户输入Loca
并使用键盘下拉到Location
,则会传递Location
。但是,如果用户键入Loca
并使用鼠标点击Location
,则会传递Loca
。
这是一个插件,所以我会尽我所能解释并显示相关代码。当我说它被传递时,它将被传递给PHP变量$thisVAR
。
我无法弄清楚为什么值会作为输入的段传递而不是分配的完整值。
这是在创建字段时创建js的PHP:
$js .= "$( function(){";
$js .= "$('.error').hide();";
$js .= "var rollbackValue = '';";
$js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').keyup(function(){";
$js .= "rollbackValue = $(this).val().slice(0,-1);";
$js .= "});";
$js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').autocomplete({";
$js .= "source: function( request, response ){";
$js .= "$.ajax({";
$js .= "url: '" . $thisURL . "',";
$js .= "dataType: 'jsonp',";
$js .= "data: {";
$js .= "term: request.term,";
$js .= "dependents: '". $thisVAR . "',";
$js .= "field: '". $config->settings['field_name'] . "_" . $suggestiveFieldArray . "',";
$js .= "fieldSettings: " . json_encode($fieldSettings);
$js .= "},";
$js .= "success: function( data ) {";
if( $fieldSettings['allow_other_countries'] == 'n' ){
$js .= "if (!data || !Object.keys(data).length){";
$js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').prev('.error')";
if( !empty($fieldSettings['custom_error']) ){
$js .= ".html('" . $customError . "')";
}else{
$js .= ".html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + request.term + '</span>`.')";
}
$js .= ".fadeIn('slow', function(){ $(this).delay(2500).fadeOut('slow'); });";
$js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').val(rollbackValue);";
$js .= "} else {";
$js .= " response( data );";
$js .= "}";
}else{
$js .= "response( data );";
}
$js .= "},";
$js .= "minLength: 0";
$js .= "});";
$js .= "}";
$js .= "});";
$js .= "});";
这相当于js中的以下内容(更易于阅读):
$( function(){
$('.error').hide();
var rollbackValue = '';
$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').keyup(function(){
rollbackValue = $(this).val().slice(0,-1);
});
$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').autocomplete({
source: function( request, response ){
$.ajax({
url: '" . $thisURL . "',
dataType: 'jsonp',
data: {
term: request.term,
dependents: '". $thisVAR . "',
field: '". $config->settings['field_name'] . "_" . $suggestiveFieldArray . "',
fieldSettings: " . json_encode($fieldSettings);
},
success: function( data ) {
if ( !data || !Object.keys(data).length ){
$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').prev('.error')
.html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + request.term + '</span>`.')
.fadeIn('slow', function(){ $(this).delay(2500).fadeOut('slow'); });
$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').val(rollbackValue);
} else {
response( data );
}
},
minLength: 0
});
}
});
});
变量$thisVAR
已确定并设置在此上方:
/**
* Determine our variables for this field
*/
$thisVAR = ''; $abbr = '';
if( strpos($suggestiveFieldArray, 'city') !== false ) {
/**
* We need the state and country data
*/
$thisVAR = "$myState|$myCountry";
$abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
}elseif( strpos($suggestiveFieldArray, 'state') !== false ) {
/**
* We need the city and country data
*/
$thisVAR = "$myCity|$myCountry";
$abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
}elseif( strpos($suggestiveFieldArray, 'country') !== false ) {
/**
* We need the city and state data
*/
$thisVAR = "$myCity|$myState";
$abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
}
... $myCity
,$myState
和$myCountry
都是从字段值中提取的。
/**
* Associative Fields Values
*/
if($field['name'] == 'theField_city'){
$myCity = $field['value'];
}elseif($field['name'] == 'theField_state'){
$myState = $field['value'];
}elseif($field['name'] == 'theField_country'){
$myCountry = $field['value'];
}
答案 0 :(得分:0)
肯定有更好的方法可以做到这一点,但我能够通过添加一个单独的js文件来实现我需要的东西,该文件包含一个宣称&#34; global&#34;从ajax请求返回新数据后要在更改事件上修改的变量。我想我只是想用一个文件做太多。 :(
答案 1 :(得分:0)
如果没有示例数据,我只能做一些猜测。为了使其更流畅,我会调整一些id
属性以使用-
而不是_
。次要偏好和需要考虑的事项。
我使用以下数据进行测试,并对您的HTML做了一些假设。如果您要返回我怀疑您的对象,则该对象必须至少包含label
和value
对。
[{
label: "San Jose, CA US",
value: "San Jose",
city: "San Jose",
state: "California",
stateAbbr: "CA",
country: "United States"
}, {
label: "Santa Clara, CA US",
value: "Santa Clara",
city: "Santa Clara",
state: "California",
stateAbbr: "CA",
country: "United States"
}, {
label: "Mountain View, CA US",
value: "Mountain View",
city: "Mountain View",
state: "California",
stateAbbr: "CA",
country: "United States"
},
{
label: "Springfield, OR US",
value: "Springfield",
city: "Springfield",
state: "Oregon",
stateAbbr: "OR",
country: "United States"
},
{
label: "Springfield, NY US",
value: "Springfield",
city: "Springfield",
state: "New York",
stateAbbr: "NY",
country: "United States"
}];
我还建议使用POST与GET并使用JSON与JSONP。如果您发送单个术语或少量数据,您真的只想使用GET。对于大量数据而言,POST更好,而且更安全。
JSONP只有在您的PHP服务器托管在另一个域内或在Web服务器之外的其他API下才有用。由于PHP正在生成JavaScript代码而AJAX正在调用PHP Self,因此我认为没有理由使用JSONP。
在您的自动完成中,您似乎需要以下内容:
我假设如果他们开始输入城市名称并进行选择,则应填写相应的州和国家/地区详细信息。
工作示例:https://jsfiddle.net/Twisty/5r1by1xp/
<强> HTML 强>
<div class="ui-widget">
<ul>
<li>
<div class="error"></div>
<label>City</label>
<input type="text" id="fn-city" data-abbr="n" />
</li>
<li>
<div class="error"></div>
<label>State</label>
<input type="text" id="fn-state" data-abbr="y" style="width: 2em;" />
</li>
<li>
<div class="error"></div>
<label>Country</label>
<input type="text" id="fn-country" data-abbr="n" />
</li>
</ul>
</div>
<强> CSS 强>
.ui-widget ul {
margin: 0;
padding: 0;
list-style: none;
}
.ui-widget ul li label {
display: inline-block;
width: 80px;
}
.ui-widget .error {
font-size: 65%;
color: red;
}
<强>的JavaScript 强>
// Only used for example & jsFiddle
var myData = [{
label: "San Jose, CA US",
value: "San Jose",
city: "San Jose",
state: "California",
stateAbbr: "CA",
country: "United States"
}, {
label: "Santa Clara, CA US",
value: "Santa Clara",
city: "Santa Clara",
state: "California",
stateAbbr: "CA",
country: "United States"
}, {
label: "Mountain View, CA US",
value: "Mountain View",
city: "Mountain View",
state: "California",
stateAbbr: "CA",
country: "United States"
}, {
label: "Springfield, OR US",
value: "Springfield",
city: "Springfield",
state: "Oregon",
stateAbbr: "OR",
country: "United States"
}, {
label: "Springfield, NY US",
value: "Springfield",
city: "Springfield",
state: "New York",
stateAbbr: "NY",
country: "United States"
}];
$(function() {
$('.error').hide();
var rollbackValue = '';
$("[id|='fn']").keyup(function() {
rollbackValue = $(this).val().slice(0, -1);
});
$("[id|='fn']").focus(function() {
$(this).addClass("activeField")
}).blur(function() {
$(this).removeClass("activeField");
}).autocomplete({
source: function(request, response) {
var fnid = $(".activeField").attr("id");
var dep = fnid.slice(fnid.indexOf("-") + 1);
var term = request.term.toLowerCase();
$.ajax({
url: '/echo/json/',
type: "POST",
dataType: 'json',
data: {
json: JSON.stringify(myData),
term: request.term,
dependents: dep,
field: fnid,
fieldSettings: JSON.stringify({
abbreviations: $("#" + fnid).data("abbr")
})
},
success: function(data) {
var results = [];
$.each(data, function(k, v) {
var depResult = v[dep].toLowerCase();
if (depResult.indexOf(term) === 0) {
results.push(v);
}
});
if (results.length == 0) {
console.log("No Results Found.");
$("#" + fnid).parent().find(".error")
.html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + term + '</span>`.')
.fadeIn('slow', function() {
$(this).delay(2500).fadeOut('slow');
});
$("#" + fnid).val(rollbackValue)
''
}
response(results);
},
minLength: 0
});
},
select: function(e, ui) {
$("#fn-city").val(ui.item.city);
$("#fn-state").val(ui.item.stateAbbr);
$("#fn-country").val(ui.item.country);
return false;
}
});
});
我个人不会使用PHP来生成JavaScript本身。它可以完成,如果您使用模板并且大量数据不是静态的,您可能无法远离它。例如,您可以在JS文件中定义和存储各种函数;通过<script>
添加它们,然后从PHP传递给它们:
<强> JS 强>
function makeAutoComplete(fID){
var $field = $("#" + fID);
$field.autocomplete();
}
<强> PHP 强>
$js = "<script src='myfunctions.js'></script>\r\n";
$js .= "<script>\r\n";
$js .= "makeAutoComplete('" . $config->settings['field_name'] . "-" . $suggestiveFieldArray . "')\r\n";
$js .= "</script>\r\n";
通过这种方式,您可以最小化交叉上下文的数量。它还使得故障排除和测试变得更容易。我也将你的PHP脚本分开。可以制作小型PHP脚本,只需将数据发布给他们然后返回数据。
希望有所帮助。