skip to Main Content

So, I have a problem with wordpress’s AJAX handler.
This is my form here:

form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter" name="filter">
            <input type="hidden" name="action" value="myfilter">
            <?php
                if( $terms = get_terms( array( 'taxonomy' => 'category', 'orderby' => 'name' ) ) ) :

                    echo '<div class="d-flex justify-content-center">';

                    foreach ( $terms as $term ) :
                        if($first) : echo '<label><input type="radio" class="radio-formular" value="' . $term->term_id . '" name="categoryfilter" onclick="this.form.submit();" checked>' . $term->name.'</label>'; // ID of the category 
                        else : echo '<label><input type="radio" class="radio-formular" value="' . $term->term_id . '" name="categoryfilter">' . $term->name. '</label>'; // ID of the category as the value
                        endif;

                    endforeach;
                echo '</div>';
            endif;
        ?>

        <button id="sbm">Apply</button>


    </form>

and I want that, when I select one of the radios, the form will submit and be handled by the next piece of code :

<script type="text/javascript">
    jQuery(function($){
    $('#filter').submit(function(e){
        var filter = $('#filter');
        $.ajax({
            url:filter.attr('action'),
            data:filter.serialize(), // form data
            type:filter.attr('method'), // POST
            beforeSend:function(xhr){
                //filter.find('button').text('Processing...'); // changing the button label
            },
            success:function(data){
                //filter.find('button').text('Apply filter'); // changing the button label back
                $('#response').html(data); // insert data
            }
        });
        return false;
    });
});


</script>

Both the snippets are in the same file.

functions.php

add_action('wp_ajax_myfilter', 'misha_filter_function'); // wp_ajax_{ACTION HERE} 
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');

function misha_filter_function(){
    $args = array(
        'orderby' => 'date', // we will sort posts by date
        'order' => $_POST['date'] // ASC or DESC
    );

    // for taxonomies / categories
    if( isset( $_POST['categoryfilter'] ) && $_POST['categoryfilter'] != '0' )
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'category',
                'field' => 'id',
                'terms' => $_POST['categoryfilter']
            )
        );


    // if you want to use multiple checkboxed, just duplicate the above 5 lines for each checkbox

    $query = new WP_Query( $args );

    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post();
            echo '<div class="container-apartament m-3 text-center">';
                echo '<img src="'. wp_get_attachment_url(get_post_thumbnail_id($query->post->ID),'full') .'">';
                echo '<div class="mt-2 mb-2 card-body">';
                    echo '<h4>' . $query->post->post_title . '</h4>';
                    echo '<a href="#myModal-'. $query->post->ID . '" class="band-text-inner"><img src="wp-content/uploads/2020/03/house-plan.png"> Plan </a>';
                    echo '<p class="card-price">'. get_field("price") .'€ no VAT</p>';
                    echo '<p class="card-yield">'. get_field("yield") .' NET <span class="text-mic-card">yield/yr: '. (string)0.05*get_field("price")*1000 .' € </span></p>';
                    echo '<a href="'. get_permalink() .'" class="invest-now">Invest Now </a>';
                echo '</div>';
            echo '</div>';
        endwhile;
        wp_reset_postdata();
    else :
        echo 'No posts found';
    endif;

    die();
}

The problem is: Submitting the form via button works as expected, but when I set an onclick event on the radio buttons, it gets stuck in admin-ajax.php instead of returning the values. Where is the mistake? I’m struggling with this since lunch and I can’t seem to find a solution.
I tried preventDefault(), as I saw in another post here, but it stops the form from submitting and I get no response at all.
Sorry for my bad english and / or ambiguous explanation, and thanks in advance!

2

Answers


  1. Chosen as BEST ANSWER

    I found a workaround for this guys. I managed to add an onclick event that triggers the click on the button that makes everything work. Still, there's a reason why submitting the form via fields wasn't possible, and if I find it I will post here.


  2. Here is a snippet that is a skeleton of what I believe you are attempting:

    • preventing the form from actually submitting (so that a new page is not loaded)
    • doing something other than the default when the form is submitted (for the example it is simply logging to the console, but it could just as easily be an Ajax request)
    • triggering the non-default action when the form values change
    jQuery(function($) {
      $('#mainForm').on('submit', function(event) {
        event.preventDefault()
        // Do whatever you want to happen when the form "submits" here, such as your ajax request
        // in the current context "this" refers to the form html object, not the jquery object
        console.info('Running submit action. Form data:', $(this).serialize())
      }).on('change', function(event){
        // trigger a submit anytime something in the form sends a 'change' action. 
        //You could also filter this to specific items in the form if you wanted
        console.warn('form changed')
        // use jquery to trigger the submit event
        // in the current context "this" refers to the form html object, not the jquery object
        // note that if you do `this.submit()` the form will submit and the submit handler won't be called
        $(this).trigger('submit')
      })
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <form action="https://postman-echo.com/get" id="mainForm">
      <label><input type="radio" name="radioChoice" value="a"/>a</label>
      <label><input type="radio" name="radioChoice" value="b"/>b</label>
    </form>

    Notice that the form is triggering the submit event when the value of the radio buttons change, but it does not load a new page. To see the difference, try editing the snippet so that instead of triggering submit with query, you instead call .submit() on the form DOM object (call this.submit() in the change handler). Calling submit on the DOM object bypasses the jQuery event handlers.

    Triggering the submit event on every change works fine if your form has only radio buttons, but if you have fields that can change very fast (like text inputs), you probably don’t want to trigger so many events, so you can use something to debounce or throttle the submit action.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search