0

I have my AJAX post category filter working fine on my site, thanks to the generous posts of folks like yourselves. What I can't seem to find is how to do something in the AJAX/jQuery script if the selected value is empty.

Here's my script:

$(function(){
  var event_change = $('#event-change');
  $( ".select" ).selectCF({
    change: function(){
      var value = $(this).val();
      var text = $(this).children('option:selected').html();
  
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'html',
            data: {
              action: 'repfilter',
              category: $(this).children('option:selected').data('slug'),
            },
            success:function(res){
                $('#response').html(res).addClass('open');
            }
        });
    }
  });
})

You'll see I used addClass('open') at the end to open the response div. It works exactly as I want it to. Now I need to be able to removeClass('open') if the dropdown option selected value is empty, the "Select an Option" option. Am I missing something obvious?

Any help is greatly appreciated!

2
  • I think you want an if around the $.ajax: only call that if text is not empty, else do the .removeClass('open').
    – Rup
    May 20, 2021 at 23:50
  • You probably also want to cache the AJAX responses too, so you don't keep reloading the result from the server if the user keeps switching between two options.
    – Rup
    May 20, 2021 at 23:51

2 Answers 2

1

Unfortunately, the answers given did not work. I was only looking at the jQuery portion, but the issue was in the functions filter, which I did not include in my original post. However, you did push me in the direction I needed, so thank you for that!

The problem was, I was always getting a response from the AJAX function. A null response would not clear the previous responses, so my content drawer would never close after being open. What I ended up doing was modifying the function that returned the results by creating an empty template part. That way, the empty select input would return an empty div.

Here's the full code, in case you were wondering:

FUNCTIONS.PHP ============

add_action('wp_ajax_repfilter', 'repfilter'); // wp_ajax_{ACTION HERE} 
add_action('wp_ajax_nopriv_repfilter', 'repfilter');
 
function repfilter() {
  $catSlug = $_POST['category'];

  $ajaxreps = new WP_Query([
    'post_type' => 'sales_reps',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'tax_query' => array(
        array (
            'taxonomy' => 'State',
            'field' => 'slug',
            'terms' => $catSlug,
        )
    ),
    'orderby' => 'title', 
    'order' => 'ASC',
  ]);
  $response = '';

  if($catSlug == '') {  // This was the key! If the dropdown selection is empty, return this empty template file.
      $response .= get_template_part('template_parts/null-item');
  } else {
      if($ajaxreps->have_posts()) {
        while($ajaxreps->have_posts()) : $ajaxreps->the_post();
          $response .= get_template_part('template_parts/rep-item');
        endwhile;
      } else {
        $response = 'Sorry. There are no sales reps in your area.';
      }
  }

  echo $response;
  exit;
}

And the jQuery ==================

$(function(){
  var event_change = $('#event-change');
  $( ".select" ).selectCF({
    change: function(){
      var value = $(this).val();
      var text = $(this).children('option:selected').html();

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'html',
            data: {
              action: 'repfilter',
              category: $(this).children('option:selected').data('slug'),
            },
            success:function(res){
                $('#response').html(res);
                if($(".repItem").length == 0) { // And this little piece checks if the results have a div present, which it would not if the empty template file was returned, and removes the "open" class.
                    $('#response').removeClass('open');
                } else {
                    $('#response').addClass('open');
                }
            }
        });
    }
  });
})

So that fixed it. See the comments in the code samples. I'm sure it's not a very elegant solution, but it worked.

0

I think you just need to call removeClass first and only call addClass when you have a result you can use:

$(function(){
  var event_change = $('#event-change');
  $( ".select" ).selectCF({
    change: function(){
      var value = $(this).val();
      var text = $(this).children('option:selected').html();

      // Remove the open class from the container when the user changes a selection
      $('#response').removeClass('open');
  
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'html',
            data: {
              action: 'repfilter',
              category: $(this).children('option:selected').data('slug'),
            },
            success:function(res){
                if ( ! res ) {
                    return;
                }

                $('#response').html(res).addClass('open');
            }
        });
    }
  });
})

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.