Wordpress过滤多个下拉分类法以通过ajax显示自定义字段

时间:2016-08-15 17:30:01

标签: php ajax wordpress custom-post-type taxonomy

我目前有一个名为newcpt的自定义帖子类型。这有2个分类,regioncity。 在区域中,我有regionaregionb,而在城市,我有cityacityb

我目前正在使用wp_dropdown_categories来获取regiona的下拉列表。是否有快速或简单的解决方案来显示第二个下拉列表,只有在regiona作为分类法时才会显示。

所以举个例子。我的帖子testpost位于regiona以及citya,当从下拉菜单中选择regiona时,我希望第二个下拉菜单填充城市区域,所以在这种情况下citya

一旦城市也被选中,它将从该cpt中获取同一页面上匹配的分类法的所有帖子。任何提示或有用的链接都非常感谢!!

3 个答案:

答案 0 :(得分:1)

我认为最好的解决方案是使用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

(你必须敲定它)

答案 1 :(得分:1)

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 );

答案 2 :(得分: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.1Child 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();
  });
});

现在,在用户选择子字词后,系统会自动提交子表单,并通过child-term方法将GET附加到网址。我们将使用此值与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了解更多信息。