While Gravity Forms has the capability to redirect to a specific URL on submission, and optionally add query parameters to that URL based on form inputs, there’s no built-in method for redirecting customers to unique URLs based on form inputs.
This functionality can be achieved with a little bit of custom code. In this example, the user will be redirected to a particular product within a WooCommerce store:
// Enter the ID of the form at the end of the 'gform_confirmation_ID' filter // In this example, the function will only run on the form with the ID of 1 add_filter( 'gform_confirmation_1', 'fivetwelve_custom_url_confirmation', 10, 4 ); function fivetwelve_custom_url_confirmation( $confirmation, $form, $entry, $ajax ) { if ( isset( $confirmation['redirect'] ) ) { // Set the root URL for the site $url = home_url( '/' ); // Populate an array with our form entries $stats = array( 'product_category' => rgar( $entry, '5' ), 'product_name' => rgar( $entry, '6' ), ); // Create the redirect URL with the form inputs $confirmation = array( 'redirect' => $url . '/' . $stats["product_category"] . '/' . $stats["product_name"] ); } return $confirmation; }
This idea could be used to generate all sorts of unique URLs based on the form inputs. Rather than scrolling through products in a store, the user could submit a form and then be taken directly to the desired product (or category of products).
Using this same technique, it’s also possible to add query parameters to the end of the URL:
// Enter the ID of the form at the end of the 'gform_confirmation_ID' filter // In this example, the function will only run on the form with the ID of 1 add_filter( 'gform_confirmation_1', 'fivetwelve_custom_url_confirmation_queries', 10, 4 ); function fivetwelve_custom_url_confirmation_queries( $confirmation, $form, $entry, $ajax ) { if ( isset( $confirmation['redirect'] ) ) { // Set the root URL for the site $url = home_url( '/' ); // Populate an array with our form entries $stats = array( 'product_category' => rgar( $entry, '5' ), // Assign the value of input 5 to this variable 'product_name' => rgar( $entry, '6' ), // Assign the value of input 6 to this variable 'variable_one' => rgar( $entry, '7' ), // Assign the value of input 7 to this variable 'variable_two' => rgar( $entry, '8' ), // Assign the value of input 8 to this variable ); // Create the redirect URL with the form inputs, and include query parameters $confirmation = array( 'redirect' => $url . '/' . $stats["product_category"] . '/' . $stats["product_name"] . '/?var1=' . $stats["variable_one"] . '/&var2=' . $stats["variable_two"] ); } return $confirmation; }
How might this be used in the real world? Well…
Take the results page even further with (hidden) Live Search
I was running a proof of concept for a client where I wanted to return products in a store based on their category, but then filter those products even further based on additional user input from the form. The solution was to add a hidden input field above the returned products (in my case, two input fields) on the WooCommerce taxonomy archive, and populate the values of those fields with URL query parameters:
<?php /** * The Template for displaying products in a product category. Simply includes the archive template * * This template can be overridden by copying it to yourtheme/woocommerce/taxonomy-product_cat.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ * @package WooCommerce/Templates * @version 1.6.4 */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } // Register and enqueue live search script add_action('wp_enqueue_scripts', 'fivetwelve_live_search_script'); function fivetwelve_live_search_script() { wp_register_script( 'live-search', get_stylesheet_directory_uri() . '/js/live-search.js', array('jquery'), '1.0.0', false ); wp_enqueue_script( 'live-search' ); } // Add the live search inputs above the products add_action( 'woocommerce_before_shop_loop', 'fivetwelve_live_search' ); function fivetwelve_live_search() { ?> <div class="live-search-wrap"> <!-- These filtering fields can be hidden with CSS. They are populated via query strings in the URL, sent from the intake form. --> <form id="live-search" action="" class="styled" method="post"> <fieldset> <!-- Create an input field that looks for the "var1" query parameter in the URL --> <input type="text" class="text-input" id="filterVar1" value="<?php echo $_GET["var1"]; ?>" /> <!-- Display the returned count of elements matching var1 --> <span id="filter-count-var1"></span> <!-- Create an input field that looks for the "var2" query parameter in the URL --> <input type="text" class="text-input" id="filterVar2" value="<?php echo $_GET["var2"]; ?>" /> <!-- Display the returned count of elements matching var2 --> <span id="filter-count-var2"></span> </fieldset> </form> </div><!-- end .live-search-wrap --> <?php } wc_get_template( 'archive-product.php' );
Javascript was used to then to take the values from these two hidden inputs (the values of which matched product categories within WooCommerce), and hide any products that did not meet those conditions. Looking at the .js file, the code is looking for any entries with the matching .product_cat-var1 class, and hiding everything else.
jQuery(document).ready(function($) { $("#filterVar1").keyup(function(){ // Retrieve the input field text and reset the count to zero var filter = $(this).val(), count = 0; // Loop through the product list $(".products .entry.product_cat-var1").each(function(){ // If the list item does not contain the text phrase fade it out if ($(this).text().search(new RegExp(filter, "i")) < 0) { $(this).hide(); // Show the list item if the phrase matches and increase the count by 1 } else { $(this).show(); count++; } }); // Update the count //var numberItems = count; $("#filter-count-var1").text(count+" Results"); }); $("#filterVar1").keyup(); $("#filterVar2").keyup(function(){ // Retrieve the input field text and reset the count to zero var filter = $(this).val(), count = 0; // Loop through the product list $(".products .entry.product_cat-var2").each(function(){ // If the list item does not contain the text phrase fade it out if ($(this).text().search(new RegExp(filter, "i")) < 0) { $(this).hide(); // Show the list item if the phrase matches and increase the count by 1 } else { $(this).show(); count++; } }); // Update the count //var numberItems = count; $("#filter-count-var2").text(count+" Results"); }); $("#filterVar2").keyup(); });
It would also be a good idea to force the product archives to return ALL products (instead of paginating them), as the live search functionality will only affect what is displayed on screen.
// Force archives to show all products add_filter( 'loop_shop_per_page', 'fivetwelve_new_shop_loop', 20 ); function fivetwelve_new_shop_loop( $cols ) { // $cols contains the current number of products per page based on the value stored on Options -> Reading // Return the number of products you wanna show per page. $cols = -1; return $cols; }
The end result allowed me to gather information from the user and, upon submission, redirect them to a particular product category with the results filtered even further based on their form inputs.
Leave a Reply