Wordpress 过滤多个下拉分类以通过 ajax 显示自定义字段
Posted
技术标签:
【中文标题】Wordpress 过滤多个下拉分类以通过 ajax 显示自定义字段【英文标题】:Wordpress Filter multiple drop-down taxonomies to display custom field via ajax 【发布时间】:2016-12-21 22:39:55 【问题描述】:我目前有一个名为 newcpt
的自定义帖子类型。这有 2 个分类法,region
和 city
。
在地区我有regiona
和regionb
,在城市我有citya
和cityb
。
我目前正在使用 wp_dropdown_categories 获取regiona
的下拉列表。是否有一种快速或简单的解决方案来显示第二个下拉列表,该下拉列表仅在它也有 regiona
作为分类时显示。
例如。我有一个testpost
的帖子,它在regiona
和citya
中,当从下拉列表中选择regiona
时,我希望第二个下拉列表填充该地区的城市,所以在这种情况下@987654335 @
一旦还选择了一个城市,它将从该cpt 中获取所有帖子,并在同一页面上使用匹配的分类法。非常感谢任何提示或有用的链接!
【问题讨论】:
你说的是前端过滤器,比如小部件或类似的,对吧?所以我访问your.site 并首先查看您的 Region-Drop-Down。选择 Region 后,我可能还会看到 city-Dropdown,对吧? 正确。因此,在位置页面上,您会看到一个下拉列表。选择下拉菜单后,第二个下拉菜单会显示过滤选项,并且带有此选项的帖子会在下方过滤。一旦出现第三个下拉菜单,它就会记录下面的实际帖子 好的,您可以通过 php 在服务器端或通过 javascript 在客户端执行此操作。如果您想依赖 php 和 wp_dropdown_categories,最好在每次更改下拉菜单时重新加载页面。因此,您可以使用所选区域的信息在服务器端构建第二个下拉菜单。你知道我的意思吗? 有没有办法确保页面没有重新加载,重要的是页面加载,然后用户将永远不会看到刷新。有没有其他办法解决这个问题 使用较少的 Javascript 和一些 PHP,您将生成大量 html。这可不是什么好主意。我认为最好的方法是留下``` wp_dropdown_categories ```并通过PHP生成带有所有信息的JSON-Object,然后使用JavaScript / AngularJS在浏览器中呈现下拉菜单。 【参考方案1】:很难弄清楚你现实世界的问题,但我会尽力而为:
让我想象一下您要归档的内容:
jQuery(document).ready(function($)
"use strict";
var parentSelectBox = $("#parent-select-box");
parentSelectBox.change(function(e)
e.preventDefault();
var childForm = $("#child-select-box"), parentTermID = parentSelectBox.val();
var terms =
"1": [
id: 11, name: "Child Term 1.1",
id: 12, name: "Child Term 1.2"
],
"3": [
id: 21, name: "Child Term 2.1",
id: 22, name: "Child Term 2.2"
]
;
childForm.empty(); // Remove all old options.
childForm.append('<option disabled selected>--Select a child term--</option>');
if (terms.hasOwnProperty(parentTermID))
var childTerms = terms[parentTermID];
$.each(childTerms, function() // Add new options.
childForm.append('<option value="' + this.id + '">' + this.name + '</option>');
);
else
console.log('There are no child terms.');
);
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="parent-from" class="form parent" method="post">
<select id="parent-select-box" name="parent-term">
<option disabled selected>--Select a parent term--</option>
<option value="1">Parent Term 1</option>
<option value="2">Parent Term 2</option>
</select>
</form>
<form id="child-form" class="form child" method="get">
<select id="child-select-box" name="child-term">
<option disabled selected>--Select a child term--</option>
<option value="3">Default Child Term 3</option>
<option value="4">Default Child Term 4</option>
</select>
</form>
如您所见,在第一个选择框中选择 Parent Term 1
后,在第二个选择框中,子术语(Child Term 1.1
和 Child Term 1.2
)会自动填充。如果您选择了Parent Term 2
,您将在控制台上看到There are no child terms.
。
但它是纯 HTML/JS,我们必须将其合并到 WordPress 中:
首先,我想你知道如何使用 AJAX 在 WordPress 中检索数据。
第一个选择框是为第二个选择框检索数据的过滤器。我们将基于父选择框的.change()
事件使用AJAX:
jQuery(document).ready(function($)
"use strict";
var parentSelectBox = $("#parent-select-box");
parentSelectBox.change(function(e) // .change()
e.preventDefault();
var parentTermID = parentSelectBox.val();
//
// Some code with AJAX to get child terms base on `parentTermID` here.
//
// Now, suppose `terms` is AJAX response.
if ($.isEmptyObject(terms)) // There're no child terms.
// Do something...
else
// Append them to the second select box.
);
);
对于第二个选择框,我不知道您文档的 DOM 结构,但我认为我们不需要 AJAX。将GET
方法与.change()
事件一起使用:
jQuery(document).ready(function($)
"use strict";
var childForm = $("#child-form"),
childSelectBox = $("#child-select-box");
childSelectBox.change(function(e)
e.preventDefault();
childForm.submit();
);
);
现在,在用户选择子术语后,子表单将自动提交,并通过GET
方法将child-term
附加到URL。我们将使用此值和pre_get_posts
操作来过滤帖子结果:
add_action('pre_get_posts', function(\WP_Query $query)
// If you're using main query, remember to check `$query->is_main_query()` as well.
if ( isset($_GET['child-term']) && !empty($_GET['child-term']) )
$query->query_vars['tax_query'] = [
[
'field' => 'term_id',
'terms' => absint($_GET['child-term']),
'taxonomy' => 'city'
]
];
);
您可能需要查看taxonomy parameters 了解更多信息。
【讨论】:
【参考方案2】:FacetWP 做你想做的事,但甚至可能比你所布置的更好 - 基于分类过滤器的数据集的 AJAX 更新。您将同时拥有显示地区和城市的下拉菜单,用户可以切换他们需要的内容。如果你想做依赖下拉的概念,你可以make a custom facet。
用法很简单 - 以下是如何将其与 WP_query 一起使用:
<?php
// 1- Setup WP_query variable to get all your content
// Logic here is descending alphabetical of all content
// FacetWP handles granular search winnowing
// Note the facetwp array item
$args = array(
'posts_per_page' => 9999,
'post_type' => array('new-cpt', 'work-featured'),
'orderby' => 'rand',
'facetwp' => true, // so we can hook into facetwp via functions.php
);
$the_query = new WP_Query( $args );
// 2- Setup new loop
if($the_query->have_posts())
while($the_query->have_posts()) :
$the_query->the_post();
// do your thing
endwhile;
wp_reset_postdata();
?>
在wp-admin
中设置分类后,您可以将分类过滤器直接输出到您的代码中(可能是边栏或任何您需要的地方):
<?php echo facetwp_display( 'facet', 'region' ); ?>
<?php echo facetwp_display( 'facet', 'cities' ); ?>
另一个注意事项 - 由于您使用的是自定义帖子类型,因此您必须 add a custom filter to your functions.php file:
// Adding in custom filter for FacetWP to detect custom WP_Query on facet page
function my_facetwp_is_main_query( $is_main_query, $query )
if ( isset( $query->query_vars['facetwp'] ) )
$is_main_query = true;
return $is_main_query;
add_filter( 'facetwp_is_main_query', 'my_facetwp_is_main_query', 10, 2 );
【讨论】:
在我支付那 79 美元之前,我会使用我的 JavaScript 解决方案 -.- 可能在更大的用例中,这个插件会变得非常方便,但对于那个小任务,我认为它不值得它 我听到了,但我的收费是 125 美元/小时 - 这个插件为我解决了大约一天的工作,很容易物有所值,但 YMMV。【参考方案3】:我认为最好的解决方案是使用 PHP 生成数据集并使用例如 AngularJS 在客户端站点上显示。
JavaScript
angular
.module('app', [])
.controller('controller', [
'$scope',
'$attrs',
function ($scope, $attrs)
$scope.data=JSON.parse($attrs.selects);
$scope.region = ;
$scope.city = ;
$scope.loadCitys = function ()
$scope.region = JSON.parse($scope.region);
;
$scope.loadPosts = function ()
$scope.city = JSON.parse($scope.city);
;
]);
和 HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://code.angularjs.org/1.5.8/angular.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="controller" data-selects='["name":"Region 1","citys":["name":"City 1","posts":["title":"Post 1","id":1,"title":"Post 2","id":2]],"name":"Region 2","citys":["name":"City 2","posts":["title":"Post 3","id":3,"title":"Post 4","id":4],"name":"City 3","posts":["title":"Post 5","id":5,"title":"Post 6","id":6]]]'>
<div>
Region: region.name <br>
City: city.name
</div>
<select ng-model="region" ng-change="loadCitys()">
<option ng-repeat="tregion in data" value="tregion">tregion.name</option>
</select>
<select ng-model="city" ng-change="loadPosts()">
<option ng-repeat="tcity in region.citys" value="tcity">tcity.name</option>
</select>
<select ng-model="post">
<option ng-repeat="tpost in city.posts" value="tpost">tpost.title</option>
</select>
<script src="script.js"></script>
</body>
</html>
活生生的例子:https://plnkr.co/edit/gyzCxMpn9luAcGsLZHYD
(你必须完成它)
【讨论】:
这是一个荒谬的答案——他要求基于 WordPress 的解决方案。 您不能合法地要求此人删除 WordPress 的整个主题层并用 WP-API 和 Angular 替换它。这不是一个明智的解决方案。以上是关于Wordpress 过滤多个下拉分类以通过 ajax 显示自定义字段的主要内容,如果未能解决你的问题,请参考以下文章
使用 Ajax 的带有自定义分类法的 Wordpress 多个自定义帖子类型过滤器 - 所有新创建的帖子都不会在响应中显示