Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
This tutorial, for beginning and intermediate Drupal programmers, includes basic and some advanced features of the Form API (example: multistep forms). Intermediate programmers may want to skip down to code sample #8. The tutorial includes the ability to copy and paste the following code snippets into a module for viewing and experimenting.
First, learn how to get the code snippets working. For an existing Drupal 6 site:
- Create a new directory in sites/all/modules and name it 'my_module'
- Create a file named my_module.info in the my_module directory with the following contents:
- Create a file and name it 'my_module.module'. Cut and paste the first code sample into the my_module.module file (note that it's preferable to omit the closing
?>
tag) - Enable the "My module" module on the administer/site building/modules page.
- Type the following in the browser address bar: http://yoursite_site_url/?q=my_module/form or http://yoursite_site_url/my_module/form depending on your configuration.
- For each code sample in the tutorial, completely replace the code in my_module.module with the new code snippet and type the following in the browser address bar: http://yoursite_site_url/?q=my_module/form or http://yoursite_site_url/my_module/form depending on your configuration.
name = My module
description = Module for form api tutorial
core = 6.x
Note: Throughout the sample code are explanation comments.
This code uses drupal “hooks”, from the drupal API.
Comments
various comments on this good tutorial
Comments on the tutorial
If you are a newbie to Drupal, (like me) you probably want to know the following things about this tutorial:
There is a discussion on why the closing “?>” may be omitted here: http://ca.php.net/basic-syntax.instruction-separation
On example 1
The 'name' key has no special meaning and any value may be used. This key value is used to generate ids and names in the generated html.
'textfield' is just the Drupal way of saying a html text input.
Drupal caches some information on modules menus. For example, if you want to change my_module_menu to give a new title to the form, you will have to disable and enable your module before refreshing to see this change.
Wrapping Titles and descriptions in t() is not required as of v6: http://drupal.org/node/140311
More info on menu here: http://drupal.org/node/102338
More info on form API here: http://api.drupal.org/api/file/developer/topics/forms_api.html/6
Where is the 'description' value used?
On example 6
Note that the validation, as expressed, allows an empty value for the 'year_of_birth' field.
The example introduces the 'value' key for $form_state other keys are documented here: http://drupal.org/node/144132
Drupal has functions to help form designers and date_validate is one out of the bunch: http://api.drupal.org/api/group/form_api/6
It would probably be a good thing to express the error message in terms of the field title (i.e. $form['year_of_birth']['#title']).
The '#validate' property may be used to explicitly register form validation handlers to forms and buttons: http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...
The '#element_validate' may be used to explicitly register element validation handlers to any element: http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...
The difference between '#validate' and '#element_validate' is described here: http://drupal.org/node/169815
On example 7
The '#submit' property may be used to explicitly register form submit handler to forms and buttons: http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...
On example 9
The example introduces the 'storage' key for $form_state see: http://drupal.org/node/144132
I’m not so sure it is a good design decision to move the field validations in the form validation in this case.
menu item to form page
A few readers had some problems finding the correct url to the new form.
if you enter this snippet of code on top of the module, you will get a new menu entry, from where you can reach the form. (I adapted the code on: http://drupal.org/node/206761 a bit to fit this tutorial. Search on that page for: Add the page to hook_menu).
After reloading/refreshing the admin -> modules the menu-item will show up.
Hope it's useful for someone
VinceW
-=[ Your Information Matters ]=-
-=[ Your Information Matters ]=-
Great Tutorial
Thank you, this is a really good tutorial. Keep up the good work:)
Christian
Set the Menu
I found this more by mistake.
Create a menu item in admin/build/menu with the path set to "my_module/form" (Leaving out the quotation marks)
Job Done.
Pip Pip
tutorial #9 issue
hi! great tutorial, but I'm having an problem which I think is related to the fact that I'm calling the form using the node/add method? If this is so, can it be explained?
I get this error when I use the drupal_get_form() method:
warning: array_merge_recursive() [function.array-merge-recursive]: Argument #2 is not an array in /home/web/active/drupal-6.10/modules/node/node.pages.inc on line 134.
My module can be viewed here:
http://home.imprison.me.uk/t/test1.module.txt
Any tips?
Cheers!
Using this tutorial to create a form for a CCK node type?
If I want to take this tutorial and add on additional functionality so that the form and its elements maps to a CCK type with fields like 'first name', 'last name' and 'year of birth', which when submitted, will create a new node of the cck type, injecting the values from the form into the new node?
Building on this, if I have CCK field types which have particular widgets attached (eg: tags, which have the autocomplete functionality), how would I expose this in my form?
Thanks!
structure of CCK data types
There's a lot more to CCK than meets the eye.
I've been working with some CCK fields, and a couple
var_dump($form);
var_dump($form_state);
show more complexity than I was expecting!
Here's the best documentation I've been able to find (note how little of it is drupal.org!):
CCK 2 Documentation | groups.drupal.org
What is the Content Construction Kit? A View from the Database. | Lullabot
CCK Documentation Resources | CCK API
API reference | CCK API
Database abstraction layer | CCK API
Unraveling the mysteries of the cck (and the cck docs) | The Empowerment
Updating CCK Modules from 5.x to 6.x | drupal.org
Multistep forms refuse to set default values of checkboxes
Here's a workaround in a multistep node form:
It's really not recursive, but it works well enough for the standard node forms (I don;t think I've seen too many node forms with nested fieldsets)
Sean Robertson | @seanr1978 on twitter
seanr@webolutionary.com
Do not translate in hook_menu
The documentation of hook_menu (http://api.drupal.org/api/function/hook_menu/6) says that the title and description property must be untranslated. So you should remove the t() function in your example.
Code example 10
Is the expression $form_state['clicked_button'][#id] == 'edit-next' correct? Should it actually be: $form_state['clicked_button'][#id] == 'next' or $form_state['clicked_button'][#value] == 'Next >>' ? I'm confused.
Unable to insert data from first page into a database
I have a form based on the above tutorial. I've managed to get it working with all the code. But when I try to submit the data to a database, it only inserts the data from the second page.
the code snippet I have is:
What do i do to make sure the first page field values are submitted and passed to the database as well.
Unable to insert data from first page into a database
As soon as i asked the question I solved it! I had to state the page one values using
so the database query becomes
And it worked. Seems a long way around though.
what if i want to show rows
sorry for interubtion...
iam alittle bit new in drupal world ..the tutorial and ur comment is more than helpful and make me understand alot how i can create a form and deals woth apis of drupal.
i have a question : what about if i want to select all data from the test table..?
i tried by replacing ur sql statement by:
sure no change :D...i guess that is because i have to fetch the rows that return and return in the form ?? but i tried but no change too :(
if any ideas i'll be greatfull
thanks in advance
sorry for interubtion... iam
sorry for interubtion...
iam alittle bit new in drupal world ..the tutorial and ur comment is more than helpful and make me understand alot how i can create a form and deals woth apis of drupal.
i have a question : what about if i want to select all data from the test table..?
i tried by replacing ur sql statement by:
sure no change :D...i guess that is because i have to fetch the rows that return and return in the form ?? but i tried but no change too :(
if any ideas i'll be greatfull
thanks in advance
Replace standard registration form with this?
This is great! I've been scouring the entire web looking for a solution like this. What I would like to do is replace the standard registration form with this solution. I have a very long registration page I need to break down into steps. Logically, I would expect to be able to create all my custom fields in the standard registration form via User Management\Profiles (so they're added to the database) and then build a substitute form in this module. Linking to this from the 'create new account,' the user profile should be viewable and editable like normal, right?
If so, I can follow the example jkiwanuka has provided above, but I'm weak with the mySQL. I do not understand the VALUES portion of the script.
thanks!
How do you get Theme Variables [Solved]
$tempSetting = theme_get_setting('theme_setting_name');
$tempSetting = variable_get('theme_setting_name');
$tempSetting = theme('get_setting', 'theme_setting_name')
This will return a NULL if called in a module but not if called from the theme:
To answer my own question:
$settings = theme_get_setting('theme_name');
$tempSetting = settings['theme_setting_name'];
Change path of this form
Hello,
I want to change the path to this form.
For example:
http://yoursite_site_url/my_module/form
New path:
http://yoursite_site_url/contact/my_module/form
1) Is this possible?
2) If yes, how can I do it?
It all depends on how you
It all depends on how you define the menu item or items and what other menu items there are already defined. For your example let's assume that if you type
http://yoursite_site_url/contact
in your browser you get the contact page or something else that makes sense.This will produce a normal menu (probably in Navigation) that will be labeled MyModule and will go to a page and call function mymodule_overview:
You can also attach a couple of menu tabs to the MyModule page by adding this inside the above function:
There have to be at least two tabs before any will show up. In the above example, the List tab does the same thing as the normal menu item MyModule, and then the Add tab goes to a page for adding whatever and calls the function mymodule_add. The page for adding is also available at
http://yoursite_site_url/mymodule/add
.If you just want to add a form tab to the contact page, then the path would be
http://yoursite_site_url/contact/form
and the code to create that menu (path) is:If on the other hand you want a tab on the contact page that says MyModule and then several tabs on the MyModule page and one of them should be form, then:
You can attach menu tabs to all sorts of existing pages this way. 'user/1/list' would show up on the profile page of User 1, for example. Play with it and see what you can do. One last note: there can only be one MENU_DEFAULT_LOCAL_TASK per page.
Does not work
I have tried and tried but cannot get the My module to show up in modules.
Anyone else having the same problem?
How can this tutorial be
How can this tutorial be modified for drupal 7
Can not generate a form
I followed all the steps here
But when I typed in
"http://yourhost/my_module/form" or
"http://yourhost/?q=my_module/form"
Just nothing happened. I didn't get a page with the form on it. I
just couldn't figure out why. Anyone can help?
Thanks
Here's a sequence that has
Here's a sequence that has helped me in troubleshooting:
1.Can I enable my module? If not, there is something wrong with my module.
2. Is my menu showing up? If not, the problem is with the code creating the menu item. Check spelling etc. until it works.
3. In the menu callback routine, add "Hello world!" to $output and return $output instead of creating the form. When I choose the menu item, do I see "hello, world"? If not, check spelling and code details. Once that is working, then
4. Put in the actual call to drupal_get_form in place of "hello world", make a simple form, maybe just a Submit button in the form function. Don't forget to return $form. Try it again until this much works.
5. Create a submit function and by changing it make sure you can either rebuild the form or finish and go elsewhere. Play with just a few fields until it does what you want.
Now you can add more fields of different sorts and work toward your actual functionality.
Drupal 7 version
Here is my version of the final step's code for Drupal 7. A couple things to point out: I used the drupal_build_form instead of drupal_get_form because the latter resets the form_state array.
I also used the #value attribute with an isset() instead of #default_value because the latter only works the first time you load the form, otherwise the default settings of Drupal forms keeps values that the user inputs which causes headaches.
Lastly, I used the form_state['input'] index instead of ['values'] because the 'input' index is essentially the post array values from this is form and that behavior was what I am used to when programming php forms. I just couldn't get the 'values' index to do what it needed to do. Anyway, feel free to make suggestions because I am still very much learning this as I go.
Many Thanks
multistep form works great for me. bundles of thanks
why must we create a module to test the code?
Hello, I am new to the form API and would like to test/experiment.
My question is, why is a new module necessary to use the form API?
Is it possible to use the form API on a php-enabled "page" content node without creating a module?
I ask because our drupal install is "locked down" and I don't have sufficient privileges to add a module.
Thanks in advance,
dw
Blank page when module installed
Hey everyone. I'm new to building modules and I've been working it from several angles but keep returning to the same problem. I've created the my_module.info file, copied the basic form code into a my_module.module file, and can see the option to enable my_module in my module page. Trouble is, once I enable my_module, the returned page is blank. Any page on my site I try to access is similarly blank.
Sorry if this question is redundant, I couldn't find any other help out there, but I'm sure I'm just missing it. Anyone have a fix for me?
Thanks!
-JB
Awesome tutorials
Its really cool tutorial, you can do most of things related to form.
awesome man.
keep posting