4.7.x form.inc drupal_get_form($form_id, &$form, $callback = NULL)
5.x form.inc drupal_get_form($form_id)
6.x form.inc drupal_get_form($form_id)
7.x form.inc drupal_get_form($form_id)

Returns a renderable form array for a given form ID.

This function should be used instead of drupal_build_form() when $form_state is not needed (i.e., when initially rendering the form) and is often used as a menu callback.


$form_id: The unique string identifying the desired form. If a function with that name exists, it is called to build the form array. Modules that need to generate the same form (or very similar forms) using different $form_ids can implement hook_forms(), which maps different $form_id values to the proper form constructor function. Examples may be found in node_forms(), and search_forms(). hook_forms() can also be used to define forms in classes.

...: Any additional arguments are passed on to the functions called by drupal_get_form(), including the unique form constructor function. For example, the node_edit form requires that a node object is passed in here when it is called. These are available to implementations of hook_form_alter() and hook_form_FORM_ID_alter() as the array $form_state['build_info']['args'].

Return value

The form array.

See also


Related topics

47 calls to drupal_get_form()
authorize.php in ./authorize.php
Administrative script for running authorized file operations.
block_admin_display in modules/block/block.admin.inc
Menu callback for admin/structure/block.
book_outline in modules/book/book.pages.inc
Menu callback: Shows the outline form for a single node.
comment_admin in modules/comment/comment.admin.inc
Menu callback; present an administrative comment listing.
comment_confirm_delete_page in modules/comment/comment.admin.inc
Page callback for comment deletions.

... See full list

34 string references to 'drupal_get_form'
aggregator_menu in modules/aggregator/aggregator.module
Implements hook_menu().
ajax_forms_test_menu in modules/simpletest/tests/ajax_forms_test.module
Implements hook_menu().
batch_test_menu in modules/simpletest/tests/batch_test.module
Implement hook_menu().
block_menu in modules/block/block.module
Implements hook_menu().
book_menu in modules/book/book.module
Implements hook_menu().

... See full list


includes/form.inc, line 123
Functions for form and batch generation and processing.


function drupal_get_form($form_id) {
  $form_state = array();

  $args = func_get_args();
  // Remove $form_id from the arguments.
  $form_state['build_info']['args'] = $args;

  return drupal_build_form($form_id, $form_state);


In drupal 7 drupal_get_form() return Form API array for HTML output drupal_render() to be called. See http://drupal.org/node/224333#unrendered

$form_id can not start with an underscore. My function was called something like _mymodule_form. The form was rendered but the submit function was not called. Renaming it to mymodule_form, it works fine.

It is possible to call drupal_get_form('some_form', $arg1, $arg2);
which will pass the arguments $arg1 and $arg2 (or however many arguments you pass) to the function some_form() like this:

some_form($form, &$form_state, $arg1, $arg2);

the function that does the work for this is drupal_retrieve_form()

Yes,that is possible,I tried in D7 and it works!!! :)

Embedding a node creation form has gotten more complex as you need to use form_load_include. If you don't do this (and only include node.pages.inc via module_load_include) ajax on 'add another' fields will break with 500 errors.

global $user;
$node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => 'FOO', 'language' => LANGUAGE_NONE);
 $form_state['build_info']['args'] = array($node);
 form_load_include($form_state, 'inc', 'node', 'node.pages');
 return drupal_build_form('FOO_node_form', $form_state);

Thanks, that saved me a lot of screaming at the monitor. I was getting quite hoarse. In my case, the problem was with embedding the form for another entity type in a page, but the same solution applies.

For ECK entity forms, the following worked for me (copying out of eck.entity.inc). Replace ENTITY_TYPE and BUNDLE with the relevant machine names:

$entity = entity_create('ENTITY_TYPE', array('type' => 'BUNDLE');
drupal_get_form('eck__entity__form_add_ENTITYTYPE_BUNDLE', $entity);

I am grateful to you for this information.

at the risk of repeating what's already been said... THANK YOU for that hint about form_load_include ! saved my sorry ass, that did!

I registered a custom route and was trying to show a node form like following:

global $user;
module_load_include('inc', 'node', 'node.pages');
$node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => 'foo', 'language' => LANGUAGE_NONE);
return drupal_get_form('foo_node_form', $node);

and my file upload widget was not working. As soon as I was trying to upload a file, the upload widget itself was disappearing!

Then I google and found your solution which worked like magic! Thanks so much! it would be really great if there was a quick explaination! The code works but I didn't really learn much! Thanks in advance!

thank you very very much :)

i spend all day to get things works with my drupal_get_form function.

Finally with your code it worked.

If its a node, you dont need to create the node object by hand, you could use:

$content_type = 'the_content_type';
module_load_include('inc', 'node', 'node.pages');
$form = node_add($content_type);

I confirm. This worked for me.

This worked for me, thanks a lot!

I confirm that it works

Maybe it's a bug that you can't do this with a simple node_add('NODETYPE') call when ajax is in the game. This is a huge pain for those who get stuck on this.
Anyway, thank you very much for this snippet.

Hi, I want to thank you very much cause ajax is working properly.
Thanks for sharing.

function mymodule_menu(){

  $items['abc'] = array(
    'type' => MENU_CALLBACK,
    'page callback' => 'drupal_get_form',
    'page arguments' => array('add_component_form'),
    'access arguments' => array('access content')

  return $items;

function add_component_form($form, &$form_state){
  $arg1 = $form_state['build_info']['args'][0];

When path 'abc/def' is requested, the $arg1 will be 'def'.

I have used this code and it does not work for me:-
function test_menu(){
$items = array();
$items['test'] = array(
'title' => 'Form validation with ajax',
'description' => 'testing form validation and ajax dropdown with ajax',
'access callback' => 'user_access',
'access arguments' => array( 'validate ajax form' ),
'page callback' => 'drupal_get_form',
'page arguments'=> array( 'validate_ajax_form', 'product_form' )
return $items;

* implements hook_form
function validate_ajax_form( $form, &$form_state ){

$product_groups = array('' => 'Select product group');
$form['product_group_id'] = array(
'#type' => 'select',
'#options' => $product_groups
return $form;

function product_form( $form, &$form_state ){

$form['name'] = array(
'#type' => 'textfield',
'#default_value' => $name
return $form;

But it does not print two forms individually.


$product_groups = array('' => 'Select product group');
$form['product_group_id'] = array(
'#type' => 'select',
'#options' => $product_groups


$product_groups = array('' => 'Select product group');
$form['product_group_id'] = array(
'#type' => 'select',
'#options' => $product_groups[''];

I am calling drupa_get_form() as below, and it returns just 'Array' instead of returning the form array.

$output = drupal_get_form('my_function', arg1);
return $output;

Please help me with this....

How are you displaying the returned array from drupal_get_form()? If you're using kpr() or dsm() in the Devel module, your returned result may be too large to display with Krumo.

return drupal_render($output);

Use \Drupal::formBuilder()->getForm('Drupal\mymodule\MyModuleForm');

More info at https://www.drupal.org/node/2117411

grateful for the assistance as well. I was including user_profile_form in a block to enable file_uploads for a certain class of users. Absolutely have to include user.pages.inc in the form_state data in order for ajax to refresh the form after file upload or remove!!

$block['subject'] = t('');
$account = user_load( $user->uid );
$form_state['build_info']['args'] = array( $account );
form_load_include($form_state, 'inc', 'user', 'user.pages');

$block['content'] = drupal_build_form('user_profile_form', $form_state);
return $block;

In truth one must render the form. corrected block_view snippet:

$block['subject'] = t('');
$account = user_load( $user->uid );
$form_state['build_info']['args'] = array( $account );
form_load_include($form_state, 'inc', 'user', 'user.pages');
$block['content'] = drupal_render( drupal_build_form('user_profile_form', $form_state) );
return $block;

'#ajax' is not working when render form using drupal_render(drupal_get_form($form)).