背景知识:我正在为交易列表(自定义分类法)构建一个自动完成搜索框。我问this question 并且非常有帮助地更好地理解了WordPress和AJAX是如何协同工作的(感谢G.M)!然而,他说我应该使用wp_localize_script
因此,前端无法访问PHP。我知道这个函数,但从未使用过,所以有点不情愿地陷入了困境。
我发现this post 它还对WordPress和AJAX如何协同工作进行了非常有用的解释。我实现了Stephen Harris提供的代码,但每当我在搜索栏中搜索任何内容时,我的控制台中就会出现一个错误:
TypeError: \'["Accountants","Electricians","Painters","Plumbers"]\' is not a valid argument for \'in\' (evaluating \'b-1 in a\')
下面是我的PHP代码:
wp_enqueue_script("autocomplete", get_template_directory_uri() . \'/assets/js/autocomplete.js\', array( \'jquery\', \'jquery-form\', \'json2\' ), false, true );
wp_localize_script("autocomplete", "MyAjax_object", array(
\'ajaxurl\' => admin_url( \'admin-ajax.php\' ),
\'myajax_nonce\' => wp_create_nonce( \'myajax_nonce_val\' ),
\'action\' => \'myajax-submit\'
));
function get_my_suggestions() {
// This function should query the database and get results as an array of rows:
// GET the recieved data: \'term\' (what has been typed by the user)
$term = $_GET[\'term\'];
$trades = get_terms( \'trade\', array( \'fields\' => \'names\' ) );
$tradesList = \'["\' . implode( \'","\', $trades ) . \'"]\';
// echo JSON to page and exit.
$response = $_GET["callback"]."(". json_encode($tradesList) .")";
echo $response;
exit;
}
add_action( \'wp_ajax_myajax-submit\', \'get_my_suggestions\' );
和JavaScript:
$(document).ready(function() {
$(".main-search-field").autocomplete({
source: function( request, response ) {
jQuery.getJSON( MyAjax_object.ajaxurl + "?callback=?&action=myajax-submit", request, function( data ) {
response( jQuery.map( data, function( item ) {
jQuery.each( item, function( i, val ) {
val.label = val.whatever; // build result for autocomplete from suggestion array data
} );
return item;
} ) );
} );
},
minLength: 1,
appendTo: ".search-container"
});
});
有人知道我为什么会出错吗?JavaScript加载良好-它添加到建议列表的标记中,但它是空的。此外,我注意到每当我在输入框中搜索某个对象时,一个类,
ui-autocomplete-loading
将添加到输入框中。不确定这是否重要,但它可能会帮助别人。
感谢您的帮助:)
最合适的回答,由SO网友:gmazzap 整理而成
如果遵循链接Q\\A中的第二种方法,则不需要ajax,只需将术语数组传递给脚本即可。
首先functions.php
(或等效)将脚本排队并通过wp_localize_script
:
add_action( \'wp_enqueue_scripts\', function() {
/* you should check if the page is the one that include the form, you know how,
* E.G.:
*
* if ( ! is_page( \'my-page-with-form\' ) ) return;
*
*/
wp_enqueue_script(
\'my-theme-autocomplete\', // is better to prefix everything in WP
get_template_directory_uri() . \'/assets/js/autocomplete.js\',
// put jquery-ui-autocomplete among dependencies
array( \'jquery\', \'jquery-form\', \'json2\', \'jquery-ui-autocomplete\' ),
NULL,
true
);
wp_localize_script( \'my-theme-autocomplete\', \'MyAjax_object\', array(
\'all_trades\' => implode( \',\', get_terms( \'trade\', array( \'fields\' => \'names\' ) ) )
) );
});
现在
autocomplete.js
文件应包含:
jQuery(document).ready( function($) {
$( \'.main-search-field\' ).autocomplete({
source: MyAjax_object.all_trades.split(\',\'),
minLength: 1
});
});
注意:检查页面是否是包含表单的页面很重要,否则脚本(jquery、jquery form、json2、jquery ui autocomplete和your autocomplete.js)将添加到每个页面上,并且
get_terms
将始终被调用,从而降低页面加载速度,因此请确保仅在需要时使用脚本。
在autocomplete.js
只包含5行代码,不值得为此创建额外的文件,如果您在所有页面上都加载了一个javascript文件(或加载在需要自动完成的页面中),请将代码放在那里,只需确保调整句柄(第一个参数)wp_localize_script
.第一个代码段使用匿名函数(闭包),因此需要PHP 5.3+。
SO网友:sabarnix
你不需要做这部分$tradesList = \'["\' . implode( \'","\', $trades ) . \'"]\';
json\\u encode将数组转换为json。
编辑:
PHP代码
function get_my_suggestions() {
// This function should query the database and get results as an array of rows:
// GET the recieved data: \'term\' (what has been typed by the user)
$term = $_GET[\'term\'];
$trades = array(\'gadha\', \'chagol\', \'patha\');
//$tradesList = \'["\' . implode( \'","\', $trades ) . \'"]\';
// echo JSON to page and exit.
$response = $_GET["callback"]."(". json_encode($trades) .")";
echo $response;
exit;
}
add_action( \'wp_ajax_myajax-submit\', \'get_my_suggestions\' );
javascript
$(document).ready(function() {
$(".main-search-field").autocomplete({
source: function( request, response ) {
jQuery.getJSON( MyAjax_object.ajaxurl + "?callback=?&action=myajax-submit", request, function( data ) {
response( jQuery.map( data, function( item ) {
jQuery.each( item, function( i, val ) {
val.label = val; // the generated array form get_terms do not have a key so pass val to label
} );
return item;
} ) );
} );
},
minLength: 1,
appendTo: ".search-container"
});
});