0

I'm on wordpress and I created a search filter shortcode which user can select province and show towns on another html select base on province and when user select town, in another html select it must be billboard(s) in each of these three stages when form submitted result must be related billboard(s) base on selects.

provinces are the parent taxonomy

towns are the child of province taxonomy

billboard(s) are the posts

note that admin may just check the town(child) tax or may check both province(parent) and town(child) on each post; It must works well on both ways.

In my code I create basic search ajax that till now just can select posts(billboard) and it show that post with ajax or search in input that post

this is my code so far:

<?php

/**
 * functions template
 * 
 * @package Environmental Ads
 */

function en_ads_scripts()
{
    wp_enqueue_style('en_ads_css', get_theme_file_uri() . '/assets/css/en-ads.css');
    wp_enqueue_script('en_ads_ajax_filter_search', get_theme_file_uri() . '/assets/js/en-ads.js', array(), '1.0', true);
    wp_localize_script('en_ads_ajax_filter_search', 'ajax_url', admin_url('admin-ajax.php')); //en_ads_ajax_filter_search must be like en-ads.js and used in it
}

// Shortcode: [en_ads_shortcode]
add_shortcode('en_ads_shortcode', 'en_ads_search_structure');
function en_ads_search_structure()
{
    en_ads_scripts();

    ob_start(); ?>

    <div id="post-ajax-filter-search">
        <form action="" method="get">
            <input type="text" name="search" id="ajax-input-search" placeholder="">
            <div class="search-option__list">
                <?php
                $searchFieldsQuery = get_posts(array(
                    'post_type' => 'en-ads',
                    'post_status' => 'publish',
                    'order' => 'ASC',
                    'posts_per_page' => -1,
                ));
                if ($searchFieldsQuery) {
                ?>
                    <div class="search-option__item">
                        <label for="enProvince" class="search-option__item--label"> Province</label>
                        <select name="enProvince" id="enProvince" class="search-option__item--select">
                            <option value="">All Province</option>
                            <?php //must query Province Here?>
                            <?php wp_reset_query(); ?>
                        </select>
                    </div>
                    <div class="search-option__item">
                        <label for="enTown" class="search-option__item--label">Town</label>
                        <select name="enTown" id="enTown" class="search-option__item--select">
                            <option value="">All Towns</option>
                            <?php //must query towns that related to province ?>
                            <?php wp_reset_query(); ?>
                        </select>
                    </div>
                    <div class="search-option__item">
                        <label for="billboard" class="search-option__item--label">Billboard</label>
                        <select name="billboard" id="billboard" class="search-option__item--select">
                            <option value="">All Billboards</option>
                            <?php foreach ($searchFieldsQuery as $sfq) { 
//this query should show the posts that related to province and town taxonomy
?>
                                <option value="<?php echo $sfq->post_title; ?>"><?php echo $sfq->post_title; ?></option>
                            <?php } ?>
                            <?php wp_reset_query(); ?>
                        </select>
                    </div>
                <?php } ?>
            </div>

            <input type="submit" id="ajax-submit" name="submit" value="search">
        </form>
        <ul id="ajax_filter_search_results"></ul>
    </div>
<?php
    return ob_get_clean();
}

// Ajax Callback
add_action('wp_ajax_en_ads_ajax_filter_search', 'en_ads_ajax_filter_search_callback'); //wp_ajax_{js action}
add_action('wp_ajax_nopriv_en_ads_ajax_filter_search', 'en_ads_ajax_filter_search_callback'); //wp_ajax_nopriv_{js action}

function en_ads_ajax_filter_search_callback()
{
    header("Content-Type: application/json");

    $meta_query = array('relation' => 'AND');

    if (isset($_GET['enProvince'])) {
        $enProvince = sanitize_text_field($_GET['enProvince']);
        $meta_query[] = array(
            'key' => 'f_standby_rating_kva',
            'value' => $enProvince,
            'compare' => '='
        );
    }
    if (isset($_GET['enTown'])) {
        $enTown = sanitize_text_field($_GET['enTown']);
        $meta_query[] = array(
            'key' => 'f_prime_rating_kva',
            'value' => $enTown,
            'compare' => '='
        );
    }
    $args = array(
        'post_type' => 'en-ads',
        'posts_per_page' => -1,
        'meta_query' => $meta_query
    );
    if (isset($_GET['search'])) {
        $search = sanitize_text_field($_GET['search']);
        $search_query = new WP_Query(array(
            'post_type' => 'en-ads',
            'posts_per_page' => -1,
            'meta_query' => $meta_query,
            's' => $search
        ));
    } else {
        $search_query = new WP_Query($args);
    }

    if ($search_query->have_posts()) {

        $result = array();

        while ($search_query->have_posts()) {
            $search_query->the_post();

            $result[] = array(
                "id" => get_the_ID(),
                "billboard" => get_the_title(),
                "permalink" => get_permalink(),
                "enProvince" => 'must get the exact billboard province to use in js',
                "enTown" => 'must get the exact billboard town to use in js',
                "poster" => wp_get_attachment_url(get_post_thumbnail_id(get_the_ID()), 'full')
            );
        }
        wp_reset_query();

        echo json_encode($result);
    } else {
        // no posts found
    }
    wp_die();
}

And this is my js:

$ = jQuery;

var pafs = $("#post-ajax-filter-search");
var pafsForm = pafs.find("form");

pafsForm.submit(function (e) {
  e.preventDefault();

  if (pafsForm.find("#ajax-input-search").val().length !== 0) {
    var search = pafsForm.find("#ajax-input-search").val();
  }
  if (pafsForm.find("#billboard").val().length !== 0) {
    var search = pafsForm.find("#billboard").val();
  }
  if (pafsForm.find("#enProvince").val().length !== 0) {
    var enProvince = pafsForm.find("#enProvince").val();
  }
  if (pafsForm.find("#enTown").val().length !== 0) {
    var enTown = pafsForm.find("#enTown").val();
  }
  var data = {
    action: "en_ads_ajax_filter_search",
    search: search,
    enProvince: enProvince,
    enTown: enTown,
  };
  console.log(data);
  $.ajax({
    url: ajax_url,
    data: data,
    success: function (response) {
      pafs.find("ul").empty();
      //console.log(response);
      if (response) {
        for (var i = 0; i < response.length; i++) {
          var html = ` 
                    <li id="ad-${response[i].id}" class="ad-item">
                        <a href="${response[i].permalink}" title="${response[i].billboard}" class="ad-item__image--link">
                            <img src="${response[i].poster}" alt="${response[i].billboard}" class="ad-item__image--img">
                        </a>
                        <div class="ad-item__info">
                            <h4 class="ad-item__info--billboard">Billboard: ${response[i].billboard}</h4>
                            <p class="ad-item__info--province">Province: ${response[i].enProvince}</p>
                            <p class="ad-item__info--town">Town: ${response[i].enTown}</p>
                            <a href="${response[i].permalink}" title="${response[i].billboard}" class="ad-item__info--more">
                            more Info                            <i class="fas fa-angle-left" aria-hidden="true"></i>
                            </a>
                        </div>
                    </li>
                    `;
          pafs.find("#ajax_filter_search_results").append(html);
        }
      }
      //   else {
      //     var html = `
      //             <li class='no-result'>Billboard Not Found</li>
      //             `;
      //     pafs.find("ul").append(html);
      //   }
    },
    error: function (jqXHR, exception) {
      pafs.find("#ajax_filter_search_results").empty();
      if (jqXHR.status === 0) {
        var errorText = "error";
      } else if (jqXHR.status == 404) {
        var errorText = "error";
      } else if (jqXHR.status == 500) {
        var errorText = "error";
      } else if (exception === "parsererror") {
        var errorText = "error";
      } else if (exception === "timeout") {
        var errorText = "Time out error";
      } else if (exception === "abort") {
        var errorText = "error";
      } else {
        var errorText = "error";
      }
      var html = `
      <li class='no-result'>${errorText}</li>
      `;
      pafs.find("#ajax_filter_search_results").append(html);
    },
  });
});
4
  • Are you asking how to do it? Or is the code shared not working? You didn't ask a question! I also see you've misused wp_reset_query ( that function should only be sued with query_posts, aka never, did you meant o use wp_reset_postdata()? ) Also the calls to wp_reset_query in your shortcode are completely unnecessary as the code never sets the current post and does not use query_posts so there is nothing to reset
    – Tom J Nowell
    Commented Aug 7, 2023 at 13:23
  • Hi and thanks for your repley. I want three steps of ajax select box search that not happend now. I comment in my php where should each select box query. As my code, user just can search in billboards (select box3). I don't know how to complete my code to do what I said at my question.
    – Alipvd
    Commented Aug 7, 2023 at 13:32
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Commented Aug 7, 2023 at 16:11
  • In first div class search-option__item I should get the parent taxonomy. In second I should get child related to the selected parent taxonomy. and in third I sould get posts base on selected option on first and second. in each stage user can retrieve posts related to selected options.
    – Alipvd
    Commented Aug 8, 2023 at 7:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.