Gravity Forms uses JavaScript to handle conditional logic (showing/hiding fields). If you load a form via AJAX into a modal, you must re-initialize Gravity Forms' scripts:
Google's reCAPTCHA expects a normal form submission in many configurations. When using AJAX, you must ensure the reCAPTCHA token is included in your AJAX data and that you initialize reCAPTCHA on the new content if the form is dynamically loaded.
if ( empty( $result['is_valid'] ) ) { // Validation failed. Get the validation HTML. ob_start(); GFFormDisplay::get_form( $form_id, true, true ); $validation_html = ob_get_clean();
This custom approach gives you complete control. You can close modal popups, play success sounds, trigger analytics events, or animate a custom thank-you message—all without ever leaving the page. Even with a solid understanding, AJAX and Gravity Forms can present challenges.
// Tell Gravity Forms to process the submission but not to output anything $_POST['gform_submit'] = $form_id; $result = GFFormDisplay::process_form( $form_id, $form );
var formData = $form.serializeArray(); // Get all form data formData.push({ name: 'action', value: 'my_gf_submit_form' }); // Add action for admin-ajax formData.push({ name: 'security', value: my_ajax_obj.nonce }); formData.push({ name: 'form_id', value: formId });
In the early days of the web, submitting a form was a dramatic event. You filled out your name, email, and message, clicked "Submit," and then... the screen went white. The browser churned, the page reloaded, and you found yourself either staring at a "Thank You" message at the top of a freshly rendered page or, more frustratingly, back at the same form, squinting to see which red error message had appeared.
function my_gf_ajax_submit_handler() { // Verify nonce if ( ! wp_verify_nonce( $_POST['security'], 'gf_ajax_nonce' ) ) { wp_die('Security check failed'); } $form_id = intval( $_POST['form_id'] ); $form = GFAPI::get_form( $form_id );