I would like to create a form for visitor to redeem a physical gift and it’s only limited to first 50 submission. How can I achieve this by using Elementor Pro form only?
Elementor Pro Form
I just started to dig into Elementor Pro form module source code today (v3.6.3 when I am writing this article). The submission module already in stable version but seems like no setting on the form to restrict it’s submission entries. Due to limited api function from them, we need to add some database query function to restrict frontend submission on specific form if maximum entries reached.
Understand that this is an easy job if using some plugins like Fluent Form or Gravity Form. But if you would like to try Elementor Pro Form without installing another plugin, just follow my guide below.
Tutorial Environment Setup
Below are my tutorial required plugins + environment setup:
- Elementor (3.5.6 in this tutorial)
- Elementor Pro (3.6.3 in this tutorial)
- WordPress 5.9.2
- PHP 7.4
- Open LiteSpeed Server
- All custom codes in this tutorial place in theme functions.php
Step 1 Activate Submissions And Create Form
First thing first, please ensure you have activated the Form Submissions in Elementor > Settings > Experiments tab.
Next, simply create a form in Elementor editor. From my example below, I just create a form in popup. I just use email field only for demo purpose. And I will use this email field as the unique identifier, which means one email only can submit once.
Important Notes:
- Please remember that the ID is gonna be unique and I will use gift_email to make this tutorial easier to understand.
- Ensure the Collect Submissions selected in Actions After Submit tab on the form.
Once done decorating your form, click the publish button and you could check this form in frontend as expected.
Step 2 Validation Hook
We can use elementor_pro/forms/validation
action hook to insert our checking logic. This hook will be fired after each field validated.
Before that, we must get the unique form id as a target key or you will be hooking on all forms. Unfortunately, we cannot get the unique form id directly from GUI. You must first create the form, then inspect the form id from the browser developer tools.
You will notice that there is hidden field with form_id in the form element. From my example, 70a319b is the generated unique form id by Elementor. Great! Let’s write some codes now.
<?php
add_action( 'elementor_pro/forms/validation', 'itchycode_restrict_maximum_entries', 10, 2);
function itchycode_restrict_maximum_entries( $record, $ajax_handler ) {
// target my form
$target_form_id = '70a319b';
if( $target_form_id != $record->get_form_settings('id') ) return;
// Here is the target form, let's make some logic
// use $ajax_handler->add_error( $field_id, $message) when you want to fail the submission.
$ajax_handler->add_error( 'gift_email', 'I am so sorry. This form reached maximum submission limit.' );
};
?>
Once you have done this part, you could try to submit the form with a valid email. Congratulation, you just hooked on it and your form is not able to submit now!
Step 3 – Get Total Submissions From Database
Next, we need to come out a function to retrieve the total submissions from database. Elementor Pro has a class (ElementorPro\Modules\Forms\Submissions\Database\Query
) but it’s not really suitable for us to use in this scenario. There is a get_submissions( $args )
function and you could make use of filters parameter to do some searches but it’s using like operator in mysql query and also search values from all fields.
Well, let’s come out with our own function then. Hopefully there will be more helper function provided by Elementor team in the future.
<?php
function get_total_submitted_entries( $form_id, $post_id ) {
// I will use Elementor's class to get the table names
$elementor_submission_query = ElementorPro\Modules\Forms\Submissions\Database\Query::get_instance();
// $elementor_submission_query->get_table_submissions() will return the submissions table name
$q = "
SELECT COUNT(*) FROM `{$elementor_submission_query->get_table_submissions()}` subh
WHERE subh.element_id = '%s' AND subh.post_id = %d
";
$where_values = [$form_id, $post_id];
global $wpdb;
$result = (int) $wpdb->get_var( $wpdb->prepare( $q , $where_values ) );
return $result ;
}
?>
Explanation:
Above function will return number of entries for the specific form. Elementor stores each submission into a table named e_submissions
and marks the post_id + element_id as the identifier. Post_id is the direct post where your form embeded into. Element_id will stores the unique form id.
Sometimes you might have multiple forms in 1 popup or page. That’s why you must query with element_id and post_id fields from database together.
Step 4 – Combines The Code In Validation Hook
Now, we can use the get_total_submitted_entries
function above in the validation action hook.
<?php
function itchycode_restrict_maximum_entries( $record, $ajax_handler ) {
// target my form
$target_form_id = '70a319b';
// define a maximum entries
$max_entries = 3;
// $record->get_form_settings('id') will be able to retrieve the form_id which is 70a319b from my example
if( $target_form_id != $record->get_form_settings('id') ) return;
// $record->get_form_settings('form_post_id') will be able to retrieve the post_id which is 74 from my example
$total_entries = get_total_submitted_entries( $target_form_id, $record->get_form_settings('form_post_id') );
// throw error if already reached maximum entries
if( $max_entries <= $total_entries ) {
$ajax_handler->add_error( 'gift_email', 'I am so sorry. This form reached maximum submission limit.' );
}
};
?>
Test your form now, you should be able to submit the form until reaching the maximum entries.
At this stage, you already successfully restricted the form submission programmatically. What if you want to totally hide this form or display other message if the maximum entries reached? Yup, we can enhance this in next step.
Hide The Form If Maximum Entries Reached (Optional)
Before proceed on this, please note that this will not be able to achieve if the page you rendered the form was cached. We will be using elementor/widget/render_content
filter hook to hide this form.
<?php
add_filter( 'elementor/widget/render_content', 'itchycode_hide_form_if_reach_maximum_entries', 10, 2);
function itchycode_hide_form_if_reach_maximum_entries($widget_content, $widget){
// target my form only
$form_id = "70a319b";
if ( "form" != $widget->get_name() || $form_id != $widget->get_id() ) return $widget_content;
// ElementorPro\Core\Utils::get_current_post_id() can retrieve the post_id which is 74 in my example
$widget_post_id = ElementorPro\Core\Utils::get_current_post_id();
// define a maximum entries
$max_entries = 3;
$total_entries = get_total_submitted_entries($form_id, $widget_post_id);
if( $max_entries <= $total_entries ) {
return "<p>I am so sorry. This form reached maximum submission limit.</p>";
}
return $widget_content;
};
?>
Check in frontend and yeesss! We did it!
Conclusion
I wish this tutorial can help you on your project. If you need some customization on your WordPress website, welcome to drop me message.
I feel that Elementor Pro form is not really powerful and developer friendly in current stage if compare with other form builder. Fluent Form still be my first recommended form plugin.
Anyway, I will write some more tips on Elemetor Pro form like validate unique email so there will be no duplicated submission by same email, how to use Elementor Pro form to claim a WooCommerce coupon code in coming days. Hope you will like it!
Action & Filter hooks used in this tutorial:
elementor/widget/render_content
elementor_pro/forms/validation
Hello,
with which Plugin is it possible to limit the submissions for the form in the elementor editor as you wrote it the first sentences?
Cheers,
Daniel