submit | Eric's Drupal Blog

Content tagged with: submit

Eric's picture

Programmatically submit a webform using drupal_execute()

In this snippet, I'll show you how you can submit a webform programmatically using drupal_execute(). The first thing you'll need to do is figure out what the $form_state data looks like when the webform is submitted, so you can recreate that structure and pass it into drupal_execute().

One way to accomplish this is to add a validation/submit handler to the form using hook_form_alter() and then output the contents of the submitted data (using krumo, print_r, etc).

The following code will prepend a validation handler to the webform $form, so we can dump the submitted data to the screen:

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
 
 
// define node id of webform
 
$webform_node_id = 146;
 
 
// check for form id of webform
 
if ($form_id == 'webform_client_form_' . $webform_node_id) {
 
   
// prepend a validation callback to the form
   
array_unshift($form['#validate'],
     
'_MYMODULE_form_alter_webform_' . $webform_node_id . '_validate');
 
  }
 
}
?>

And here is the validation handler which will dump the submitted data to the screen. NOTE: krumo() is available from the devel module; you could use print_r() as well:

<?php
function _MYMODULE_form_alter_webform_146_validate($form, &$form_state) {
 
// debug
 
krumo($form_state);
  die;
}
?>

Now, if I populate the webform with some data:

And submit the form, I will get the following debug output:

You'll need to mirror the structure of the submitted data when creating your $form_state variable, which will be passed into drupal_execute().

In the following function, I show how you can submit a webform programmatically. There is even additional code in there which loads a user's previously submitted data, if you care.

<?php
function MYMODULE_some_function() {

 
// define webform node id
 
$webform_node_id = 146;

 
// define user submitting the webform
 
$user_id = 2;

 
// load webform node
 
if ($node = node_load($webform_node_id)) {

   
// load module include file, per loading previously submitted webform data
   
module_load_include('inc', 'webform', 'webform_report');

   
// get submissions for user
   
$submissions = webform_get_submissions($node->nid, NULL, $user_id);

   
// get submission data ($submission) and submission id ($sid)
   
if (FALSE !== ($sid = key($submissions))) {
     
$submission = $submissions[$sid];
    }
    else {
     
$submission = NULL;
     
$sid = NULL;
    }

   
// create array of $form_state data
    // NOTE: be sure to use the debug output as a guide to make this array match!
   
$form_state = array(
     
'submitted' => true,
     
'values' => array(
       
'submission' => $submission,
       
'submitted' => array(
         
'test_field_1' => 'abc',
         
'test_field_2' => '123',
         
'test_field_3' => 'def',
        ),
       
'details' => array(
         
'email_subject' => $node->webform['email_subject'],
         
'email_from_name' => $node->webform['email_from_name'],
         
'email_from_address' => $node->webform['email_from_address'],
         
'nid' => $webform_node_id,
         
'sid' => $sid,
        ),
       
'op' => t('Submit'),
       
'submit' => t('Submit'),
       
'form_id' => 'webform_client_form_'. $webform_node_id,
      ),
    );

   
// Saves the webform data submited prior to login.
   
drupal_execute('webform_client_form_'. $webform_node_id, $form_state, $node, $submission, TRUE, FALSE);
   
  }

}
?>

gradient spacer
Eric's picture

Making a synchronous AJAX call using jQuery

I recently was tasked with tracking when a user submitted a form, but in this case, the form was submitted to an external site. Normally, if the form was being submitted locally I could have added a form_alter hook function and modify the submit handlers. The following code snippet will explain how you can add a javascript submit event on the form, and using a synchronous AJAX call, execute server side code before the user leaves the site.

First, I setup a page callback used by the AJAX call to execute my inserted code.

<?php
// define the menu callback item
function MYMODULE_menu() {
 
$items = array();
   
 
$items[] = array(
   
'path' => 'MYAJAXPATH',
   
'title' => NULL,
   
'callback' => '_MYAJAXPATH_callback',
   
'access' => true,
   
'type' => MENU_CALLBACK,
  );
   
  return
$items;
}

// define the menu callback function
function _MYAJAXPATH_callback() {
 
// here, you could add any code you'd like (modify session data, execute some SQL, etc).
   
  // I added the die statement to prevent the theme layer from being executed
 
die;
}
?>

Make sure the page callback works by browsing to it. If you don't output any HTML in your callback function, you should just get a blank page.

Next, you'll need to attach a submit handler to the form and make the synchronous AJAX call.

<?php
$(document).ready(function(){
  $(
'form#FORM-ID-THAT-SUBMITS-EXTERNAL').submit(function(){
    $.
ajax({
     
type: "GET",
     
url: "/MYAJAXPATH",
     
cache: false,
     
async: false,
    });
  });
});
?>

I added a few properties to the AJAX request object to enable this functionality: cache set to false ensures the page request will not be pulled from your browser cache & async set to false will ensure the form is not submitted until the AJAX request is done. jQuery's default AJAX calls are set to asynchronous, which does not guarantee the request will be made before the form is submitted.

gradient spacer
Eric's picture

Add additional functionality to a system form when it's submitted

This code snippet will should you how to add additional functionality to a system form when it's submitted. You can do this in Drupal 5.x using a form_alter hook to modify the submit handlers on the form object. In my example, I'll show you how to add your own function that will executed when the contact form is submitted.

<?php
function MYMODULE_form_alter($form_id, &$form) {
 
// check for the form ID you'd like to alter
 
if ($form_id == 'contact_mail_page') {
   
// modify the "#submit" form property by prepending another submit handler array
   
$form['#submit'] = array_merge(
      array(
'_MYMODULE_contant_mail_page_submit' => array()),
     
$form['#submit']
    );
  }
}
?>

Now, when the contact form is submitted, you're submit handler will be processed as well. You'll need to define a function with the same name.

<?php
function _MYMODULE_contant_mail_page_submit($form_id, $form_values) {
 
// do whatever you'd like here and it will be executed when the contact form is submitted
}
?>

gradient spacer
Eric's picture

Replacing a submit button with an image using CSS

I just created a new image to replace the generic submit button appearance, when I remembered the submit buttons are type submit, not type image. I decided to use some quick CSS instead. The trick is adding a background image to the submit button, and then *hiding* the button text by adding padding-top CSS that is greater than the height of the image, and adding "overflow: hidden" to ensure the text does not get pushed outside the button...

form#MYFORMID #edit-submit {
  height: 22px;
  width: 73px;
  background: url('images/button_submit.jpg') no-repeat;
  border: none;
  overfow: hidden;
  padding-top: 25px;
}

gradient spacer
Eric's picture

Adding a javascript confirm box to a custom form using jQuery

In a module I was developing recently, I needed to add a javascript confirm popup before allowing the user to submit the form. Here is an excerpt from my code to show you how to add the jQuery

<?php
function MYMODULE_main() {
 
$page_contents  = "";
 
// ...code...
 
$page_contents .= drupal_get_form('MYMODULE_form');
 
// ...code...
 
return $page_contents;
}

function
MYMODULE_form() {
 
$form = array();
 
// ...code...
 
$js = "
    $(document).ready(function(){
      $('#"
. str_replace('_','-',__FUNCTION__) . "').submit(function(){
        if (confirm('Are you sure?')) {
          return true;
        } else {
          return false;
        }
      );
    });
  "
;
 
drupal_add_js($js, 'inline');
 
// ...code...
 
return $form;
}
?>

gradient spacer Syndicate content