 form wizard tool form wizards or multistep forms are a process by which the user goes through or can use an arbitrary number of different forms to create a single object or perform a single task traditionally the multistep form is difficult in drupal because there is no easy place to put data in between forms no longer the form wizard tool allows a single entry point to easily set up a wizard of multiple forms provide callbacks to handle data storage and updates between forms and when forms are completed this tool pairs well with the object cache tool for storage the form info array the wizard starts with an array of data that describes all of the forms available to the wizard and sets options for how the wizard will present and control the flow here is an example of the forminfo array as used in the delegator module forminfo array id delegatorpage path admin build pages edit pagename step show trail true show back true show return false next callback delegatorpageaddsubtasknext finish callback delegatorpageaddsubtaskfinish return callback delegatorpageaddsubtaskfinish cancel callback delegatorpageaddsubtaskcancel order array basic t basic settings argument t argument settings access t access control menu t menu settings multiple t task handlers forms array basic array form id delegatorpageformbasic access array form id delegatorpageformaccess menu array form id delegatorpageformmenu argument array form id delegatorpageformargument multiple array form id delegatorpageargumentformmultiple the above array starts with an id which is used to identify the wizard in various places and a path which is needed to redirect to the next step between forms it then creates some settings which control which pieces are displayed in this case it displays a form trail and a back button but not the return button then there are the wizard callbacks which allow the wizard to act appropriately when forms are submitted finally it contains a list of forms and their order so that it knows which forms to use and what order to use them by default note that the keys in the order and list of forms match that key is called the step and is used to identify each individual step of the wizard here is a full list of every item that can be in the form info array id an id for wizard this is used like a hook to automatically name callbacks  as well as a form step s form building function it is also used in trail theming path the path to use when redirecting between forms  step will be replaced with the key for the form return path when a form is complete this is the path to go to this is required if the return button is shown and not using ajax it is also used for the finish button if it is not present and needed the cancel path will also be checked cancel path when a form is canceled this is the path to go to this is required if the cancel is shown and not using ajax show trail if set to true the form trail will be shown like a breadcrumb at the top of each form defaults to false show back if set to true show a back button on each form defaults to false show return if set to true show a return button defaults to false show cancel if set to true show a cancel button defaults to false back text set the text of the back button defaults to t back next text set the text of the next button defaults to t continue return text set the text of the return button defaults to t update and return finish text set the text of the finish button defaults to t finish cancel text set the text of the cancel button defaults to t cancel ajax turn on ajax capabilities using ctools ajaxinc defaults to false modal put the wizard in the modal tool the modal must already be open and called from an ajax button for this to work which is easily accomplished using functions provided by the modal tool ajax render a callback to display the rendered form via ajax this is not required if using the modal tool but is required otherwise since ajax by itself does not know how to render the results params formstate output finish callback the function to call when a form is complete and the finish button has been clicked this function should finalize all data params formstate defaults to forminfo id finish if function exists cancel callback the function to call when a form is canceled by the user this function should clean up any data that is cached params formstate defaults to forminfo id cancel if function exists return callback the function to call when a form is complete and the return button has been clicked this is often the same as the finish callback params formstate defaults to forminfo id return if function exists next callback the function to call when the next button has been clicked this function should take the submitted data and cache it for later use by the finish callback params formstate defaults to forminfo id next if function exists order an optional array of forms keyed by the step which represents the default order the forms will be displayed in if not set the forms array will control the order note that submit callbacks can override the order so that branching logic can be used forms an array of form info arrays keyed by step describing every form available to the wizard if order array isn t set the wizard will use this to set the default order each array contains form id the id of the form as used in the drupal form system this is also the name of the function that represents the form builder defaults to forminfo id stepform include the name of a file to include which contains the code for this form this makes it easy to include the form wizard in another file or set of files this must be the full path of the file so be sure to use drupalgetpath when setting this this can also be an array of files if multiple files need to be included title the title of the form to be optionally set via drupalgettitle this is required when using the modal if formstate title is not set invoking the form wizard your module should create a page callback via hookmenu and this callback should contain an argument for the step the path that leads to this page callback should be the same as the path set in the forminfo array the page callback should set up the forminfo and figure out what the default step should be if no step is provided note that the wizard does not do this for you you must specify a step then invoke the form wizard formstate array ctoolsinclude wizard output ctoolswizardmultistepform forminfo step formstate if using ajax or the modal this part is actually done if not you have one more small step return output  forms and their callbacks each form within the wizard is a complete independent form using drupal s form api system it has a form builder callback as well as submit and validate callbacks and can be form altered the primary difference between these forms and a normal drupal form is that the submit handler should not save any data instead it should make any changes to a cached object usually placed on the formstate and only the finish or return handler should actually save any real data how you handle this is completely up to you the recommended best practice is to use the ctools object cache and a good way to do this is to write a couple of wrapper functions around the cache that look like these example functions get the cached changes to a given task handler function delegatorpagegetpagecache name ctoolsinclude objectcache cache ctoolsobjectcacheget delegatorpage name if cache cache delegatorpageload name cache locked ctoolsobjectcachetest delegatorpage name return cache store changes to a task handler in the object cache function delegatorpagesetpagecache name page ctoolsinclude objectcache cache ctoolsobjectcacheset delegatorpage name page remove an item from the object cache function delegatorpageclearpagecache name ctoolsinclude objectcache ctoolsobjectcacheclear delegatorpage name using these wrappers when performing a getcache operation it defaults to loading the real object it then checks to see if another user has this object cached using the ctoolsobjectcachetest function which automatically sets a lock which can be used to prevent writes later on with this set up the next finish and cancel callbacks are quite simple callback generated when the add page process is finished function delegatorpageaddsubtaskfinish formstate page formstate page create a real object from the cache delegatorpagesave page clear the cache delegatorpageclearpagecache formstate cache name callback generated when the next button is clicked all we do here is store the cache function delegatorpageaddsubtasknext formstate update the cache with changes delegatorpagesetpagecache formstate cache name formstate page callback generated when the cancel button is clicked all we do here is clear the cache function delegatorpageaddsubtaskcancel formstate update the cache with changes delegatorpageclearpagecache formstate cache name all that s needed to tie this together is to understand how the changes made it into the cache in the first place this happened in the various form submit handlers which made changes to formstate page based upon the values set in the form store the values from the basic settings form function delegatorpageformbasicsubmit form formstate if isset formstate page pid empty formstate page import formstate page name formstate values name formstate page admintitle formstate values admintitle formstate page path formstate values path no database operations were made during this submit and that s a very important distinction about this system proper handling of back button when using  show back true the cached data should be assigned to the  defaultvalue form property otherwise when the user goes back to the previous step the forms default values instead of his cached input is used form builder function for wizard function wizardidstep2form form formstate formstate my data mymodulegetcache formstate cache name form example array type radios title t title defaultvalue formstate my data example formstate my data example default options array default t default setting1 t setting1 submit handler to prepare needed values for storing in cache function wizardidstep2formsubmit form formstate formstate my data example formstate values example the data is stored in the my data object on submitting if the user goes back to this step the cached my data is used as the default form value the function mymodulegetcache  is like the cache functions explained above required fields cancel and back buttons if you have required fields in your forms the back and cancel buttons will not work as expected since validation of the form will fail you can add the following code to the top of your form validation to avoid this problem validation handler for step2 form function wizardidstep2formvalidate form formstate if the clicked button is anything but the normal flow if formstate clickedbutton next formstate next drupalgetmessages error formseterror null true return you form validation goes here  wizard for anonymous users if you are creating a wizard which is be used by anonymous users you might run into some issues with drupal s caching for anonymous users you can circumvent this by using hookinit and telling drupal to not cache your wizard pages implementation of hook init function mymoduleinit if the path leads to the wizard if drupalmatchpath get q path to your wizard set cache to false globals conf cache false  