Calculated Fields Form Blog

Tips and cases of use for a successful WordPress website with calculated forms.

Blog / Implementing a posts filter using the Calculated Fields Form plugin

Implementing a posts filter using the Calculated Fields Form plugin

The adaptability of the "Calculated Fields Form" plugin allows to use it for replacing even basic WordPress features, like a search box for filtering the website's posts, pages or custom post types (as the WooCommerce products)


This article describes a particular case of use, emulate a search box for filtering the WooCommerce products, but improving the user's experience loading these products dynamically.

Emulate a search box with the "Calculated Fields Form" plugin requires to execute server side code to load those products that meet the users' criteria, therefore, would be used the SERVER SIDE EQUATIONS add-on, distributed with the Developer and Platinum versions of the plugin.

Form's fields

To filter the WooCommerce products would be used a "Single Line Text" field (fieldname1), and two "Currency" fields (fieldname2 and fieldname3) for loading the products in the price range. In addition, the form would include a "Calculated" field (fieldname4) to call the server side equation, and a "HTML Content" field (fieldname5) where showing the resulting products.

Enter a DIV tag with the unique id: products_here into the "content" attribute of the "HTML Content" field (fieldname5) for displaying the resulting products:

<div id="products_here"></div>

HTML Content Field

The equation associated to the calculated field will do:

  • First, will clear the products from the previous DIV tag,
  • Second, it will call the server side equation, named: get_products, passing as parameter the fields for filtering: feildname1, fieldname2, and fieldname3
  • Finally, will display the resulting products inside the DIV tag with the id: products_here

    (function(){
        jQuery('#products_here').html('');
        var products = SERVER_SIDE('get_products', fieldname1, fieldname2, fieldname3);
        jQuery('#products_here').html(products);
    })()
    

Calculated Field

Server side equation

The server side equation is the hard part of this project.

To implement the server side equation it is required to active the SERVER SIDE EQUATIONS add-on first.

  • Go to the settings page of the plugin through the menu option: "Calculated Fields Form"
  • Tick the "CFF - Server Side Equations" checkbox.
  • And press the "Activate/Deactivate addons"

Add-ons Area

The previous action will display a new section in the settings page of the plugin for entering the server side equation code:

$GLOBALS['SERVER_SIDE_EQUATIONS']['get_products'] = function($text, $from, $to){
    $text = sanitize_text_field($text);
    $from = @floatval($from);
    $to = @floatval($to);
    $products = '';

    if(!empty($text) || !empty($from) || !empty($to))
    {
        WC()->init();
        $args = array(
            'post_type' => array('product', 'product_variation'),
            'post_status' => 'publish',
            'meta_query'  => array(
                array(
                    'key' => '_price',
                    'value' => array($from, PHP_INT_MAX),
                    'compare' => 'BETWEEN',
                    'type'    => 'DECIMAL(10,2)'
                )
            )
        );

        if(!empty($text)) $args['s'] = $text;
        if(!empty($to)) $args['meta_query'][0]['value'][1] = $to;
        $query = new WP_Query( $args );

        if($query->have_posts())
        {
            foreach($query->posts as $post)
            {
                $product_obj = wc_get_product($post->ID);
                $products .= '
                <div class="product">
                    <div class="product-cover">'.
                    get_the_post_thumbnail($post->ID).'</div>
                    <div class="product-title">
                    <a href="'.esc_attr($product_obj->get_permalink()).'">'.
                    $product_obj->get_title().'</a></div>
                    <div class="product-price">'.
                    $product_obj->get_price_html().'</div>
                    <div class="add-to-cart">
                    <a href="'.esc_attr($product_obj->add_to_cart_url()).'">'.
                    $product_obj->add_to_cart_text().'</a></div>
                </div>
                ';
            }
        }
        else
        {
            $products = 'There are no products that satisfy the search criteria.';
        }
    }   

    return $products;
};

Server Side Equation

A maxim in the software development is: never trust in the information entered by the users, to comply with this maxim the first block in the server side equation sanitizes the information received from the public form:

$text = sanitize_text_field($text);
$from = @floatval($from);
$to = @floatval($to);

and initializes the variable to return by the equation:

$products = '';

The server side equation should to initialize WooCommerce too, before calling the wc_get_product function, or any other WooCommerce function:

WC()->init();

For filtering the products based on the information received from the public website, the server side equation uses the WordPress class: WP_Query to prevent execute the SQL queries directly.

$args = array(
    'post_type' => array('product', 'product_variation'),
    'post_status' => 'publish',
    'meta_query'  => array(
        array(
            'key' => '_price',
            'value' => array($from, PHP_INT_MAX),
            'compare' => 'BETWEEN',
            'type'    => 'DECIMAL(10,2)'
        )
    )
);

if(!empty($text)) $args['s'] = $text;
if(!empty($to)) $args['meta_query'][0]['value'][1] = $to;
$query = new WP_Query( $args );

The rest of the equation is very straightforward, it walk through the list of items returned by the query, and populates the $products variable initialized at beginning:

if($query->have_posts())
{
    foreach($query->posts as $post)
    {
        $product_obj = wc_get_product($post->ID);
        $products .= '
        <div class="product">
            <div class="product-cover">'.
            get_the_post_thumbnail($post->ID).'</div>
            <div class="product-title">
            <a href="'.esc_attr($product_obj->get_permalink()).'">'.
            $product_obj->get_title().'</a></div>
            <div class="product-price">'.
            $product_obj->get_price_html().'</div>
            <div class="add-to-cart">
            <a href="'.esc_attr($product_obj->add_to_cart_url()).'">'.
            $product_obj->add_to_cart_text().'</a></div>
        </div>
        ';
    }
}
else
{
    $products = 'There are no products that satisfy the search criteria.';
}

Public form

Public Form