How to develop custom forms for Drupal's admin users? - drupal

which will be the best way to develop custom forms for drupal, for admin's part of the system?
thank you in advance!

First thing, you need a location to access your form from, preferably in the "admin/*" namespace if the form is only meant for administration.
If you're just showing a form, you could directly use drupal_get_form as page callback (but you could use any function to generate the HTML code, even mix with theme functions)
Also, you need to know which permission(s) is required to access the form.
By default, I used "access administration pages" but you probably should use something more specific, depending on what you intend the form for.
Let's say the path is "admin/build/something", you need to use hook_menu to register that path:
/**
* Implementation of hook_menu().
*/
function modulename_menu(){
return array(
'admin/build/something' => array(
'title' => 'Example Admin Form',
'description' => 'Admin form introduced by the MODULENAME module',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'drupal_get_form',
'access arguments' => array('access administration pages'),
),
);
}
Now, to actually display a page: the value provided in "page arguments" was the name
of the function that drupal_get_form expects to provide the form structure
(which must be an associative array):
/**
* Form Structure
*/
function modulename_form_something(&$form_state){
$form = array();
$form['myfield'] = array(
'#title' => 'My Field',
'#description' => 'This is a basic text input field',
'#type' => 'textfield',
'#default_value' => $form_state['values']['myfield'],
);
//
// Here you can add more elements in the form
//
return $form;
}
Here is more informations about the Forms API, which you can use to make some pretty complex forms easily.
Now your form is displayed at "/admin/build/something", but you probably want to do soemthing with these data as well; by default, the validate and submit functions are named the same as the form structure function, with "_validate" and "_submit" respectively (however you can override this with #validate and #submit in the form structure).
For example, let's say the string "no" is not a valid value, everything else is accepted.
/**
* Form validation
*/
function modulename_form_something_validate($form, &$form_state){
if ($form_state['values']['myfield'] == 'no'){
form_set_error('myfield', '"<b>no</b>" is not a valid answer, try again.');
}
}
The validation is called first, however you should only check if data are alright in that function. If you need to perform actions when the form is received, do it in the "submit" handler instead because validate may be called several times while submit is called only once.
/**
* Form submission
*/
function modulename_form_something_submit(&$form, &$form_state){
//
// Here you can perform whatever action that form is made for.
//
drupal_set_message( 'The form has been sent. "myfield" has the following value: '.$form_state['values']['myfield'] );
}
Let's summarize, here's the whole modulename.module file:
<?php
/**
* Implementation of hook_menu().
*/
function modulename_menu(){
return array(
'admin/build/something' => array(
'title' => 'Example Admin Form',
'description' => 'Admin form introduced by the MODULENAME module',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'drupal_get_form',
'page arguments' => 'modulename_form_something',
'access arguments' => array('access administration pages'),
),
);
}
/**
* Form Structure
*/
function modulename_form_something(&$form_state){
$form = array();
$form['myfield'] = array(
'#title' => 'My Field',
'#description' => 'This is a basic text input field',
'#type' => 'textfield',
'#default_value' => $form_state['values']['myfield'],
);
//
// Here you can add more elements in the form
//
return $form;
}
/**
* Form validation
*/
function modulename_form_something_validate($form, &$form_state){
if ($form_state['values']['myfield'] == 'no'){
form_set_error('myfield', '"<b>no</b>" is not a valid answer, try again.');
}
}
/**
* Form submission
*/
function modulename_form_something_submit(&$form, &$form_state){
//
// Here you can perform whatever action that form is made for.
//
drupal_set_message( 'The form has been sent. "myfield" has the following value: '.$form_state['values']['myfield'] );
}
Don't forget you also need a .info file for being able to install the module:
Source of modulename.info:
; $Id
name = Admin Form
description = This module adds an admin form
package = Example Module
core = "6.x"
version = "6.x-0.1-dev"

The Drupal form api system will help you make any form you need. If you need to store settings, system_settings_form is a nice shortcut.
The only difference when making admin forms, is to remember to set some sort of permission required, and to place the form somewhere in the /admin/ section of the site. There really isn't anything special about admin forms.

Unless I'm misunderstanding your question, I think you can avoid the hassle of Forms API by using the Webform module.
No code required, nice UI and built in statistics tools.
http://drupal.org/project/webform
Watch a couple tutorial videos and you'll be making just about any form in no time.

Related

simple example form in drupal 7 with everything configured correctly shows "Page not found"..Why..?

I have installed drupal 7 and have been trying to create a custom form. The below code which am trying has been taken from http://drupal.org/node/717722 and I have not made any changes except for .info file.
here is the my_module.info
name = My module
description = Module for form api tutorial
core = 7.x
Below is the my_module.module
<?php
/**
* This function defines the URL to the page created etc.
* See http://api.drupal.org/api/function/hook_menu/6
*/
function my_module_menu() {
$items = array();
$items['my_module/form'] = array(
'title' => t('My form'),
'page callback' => 'my_module_form',
'access arguments' => array('access content'),
'description' => t('My form'),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* This function gets called in the browser address bar for:
* "http://yourhost/my_module/form" or
* "http://yourhost/?q=my_module/form". It will generate
* a page with this form on it.
*/
function my_module_form() {
// This form calls the form builder function via the
// drupal_get_form() function which takes the name of this form builder
// function as an argument. It returns the results to display the form.
return drupal_get_form('my_module_my_form');
}
/**
* This function is called the "form builder". It builds the form.
* Notice, it takes one argument, the $form_state
*/
function my_module_my_form($form_state) {
// This is the first form element. It's a textfield with a label, "Name"
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
);
return $form;
}
?>
I have placed these two files in a *my_module* folder and placed it in sites/all/modules
After that, I enabled the module from the modules page without any errors or warnings.
Now, when I try to access this for using the url, localhost/d7/?q=my_module/form
I get a "Page not found " error..!! Why..?? What am I missing..?
Its not only for this module but also for this examples for developers module http://drupal.org/project/examples. It shows the same error.
You should write:
$items['my_module']
Where my_module is module name.
And you need to create page-my_module_my_form.tpl.php file at
sites/all/theme/your_theme/template/page-my_module_my_form.tpl.php
and in this file add code like this:
<?php
if (isset($form['submission_info']) || isset($form['navigation'])) {
print drupal_render($form['navigation']);
print drupal_render($form['submission_info']);
}
print drupal_render($form['submitted']);
?>
<?php print drupal_render_children($form); ?>
and try to run with
localhost/d7/my_module
I hope this will be useful to you
I know this is late, but I do believe that you need to have the $form variable passed into your form, like so : function my_module_my_form($form_state, $form)... That way you actually have a form variable to house your form data.

Drupal 7 - Confirm email address

I have added some extra fields to the standard 'create account' page; notably a 'confirm email' field.
How do hook into the validation so that I can add some custom validation rules of my own (e.g. to check the two emails match)?
I have found hook_user_presave, but am unsure on how to code it or where I should put it.
Any and all help appreciated.
I would advise installing the LoginToboggan module, it actually has the option for that exact functionality out of the box and has a bunch of other useful options as well.
If you want to do it yourself though you'd probably be better off implementing hook_form_FORM_ID_alter() and adding a validation function directly to the registration form:
function mymodule_form_user_register_form_alter(&$form, &$form_state, $form_id) {
$form['#validate'][] = 'mymodule_user_register_form_validate';
}
function mymodule_user_register_form_validate(&$form, &$form_state) {
if ($form_state['values']['first_email'] != $form_state['values']['second_email']) {
form_set_error('second_email', 'The email addresses much match.');
}
}
Make sure you clear Drupal's cache once you've implemented the form alter function so Drupal registers it correctly.
Hope that helps.
Here is the example solution for Drupal 7:
/**
* Implements hook_menu().
* Note: You can define your own menu callback optionally.
*/
function foo_menu() {
$items['foo-signup'] = array(
'title' => 'Create new account',
'page callback' => 'drupal_get_form',
'page arguments' => array('user_register_form'),
'access callback' => 'user_register_access',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function foo_form_user_register_form_alter(&$form, &$form_state, $form_id) {
$form['account']['mail_confirm'] = array(
'#type' => 'textfield',
'#title' => t('Confirm e-mail address'),
'#maxlength' => EMAIL_MAX_LENGTH,
'#description' => t('Please confirm your e-mail address.'),
'#required' => TRUE,
);
$form['#validate'][] = 'foo_user_register_form_validate';
}
/**
* Implements validation callback.
*/
function foo_user_register_form_validate(&$form, &$form_state) {
if ($form_state['values']['mail'] != $form_state['values']['mail_confirm']) {
form_set_error('mail_confirm', 'The email addresses must match.');
}
}

trouble customizing a page.tpl.php for Drupal 7 page callback to serve a form over AJAX

I am creating a custom module. I want to implement a form that can be used as a block, and used in a query dialog (loaded with an ajax request). I have created the block no problem. I have also created the page callback function no problem.
So, I can load the form in a block and I can pull up the jquery dialog and it will get the form with an ajax request. But, It loads the form and the full page template complete with header and footer etc....
What I want to do is use a different page template when getting the ajax call so that all I get is the form. But, everything I've seen online seems to be a mix between drupal 6 and 7 and I haven't gotten anything to work.
here's my latest try:
in menu hook
$items['mymodule/get_form_ajax'] = array(
'title' => 'Ajax Form',
'type' => MENU_CALLBACK,
'page callback' => 'get_form_ajax',
'access arguments' => array('access content'),
);
Then I have the callback:
function get_form_ajax() {
$form = drupal_get_form('request_form');
$build['items'] = array(
'#theme' => 'request_form',
'#items' => $form,
);
return $build;
}
And then I have the theme registered this way:
function mymodule_theme($existing, $type, $theme, $path){
return array(
'request_form' => array(
'template' => 'request_form',
'render element' => 'form',
)
);
}
Anyway, this totally doesn't work. It just renders an empty page in the dialog. Any help will be appreciated.
Since you're making an AJAX call there's no need to let the page build as normal, you can simply print the rendered form out directly and call drupal_exit():
function get_form_ajax() {
$form = drupal_get_form('request_form');
echo render($form);
drupal_exit();
}
This will give you a nice clean form that inherits the styles from the page it's being loaded into, and still keeps the form tokens/cache in-tact.

How do i get the data?(Drupal 6.x)

I have this form which accepts user’s input. What I like to do is, base on that user input, I’d like to retrieve data and display it back to user.
So far, I have implemented hook_menu and registered respective url of the form, and implemented a submit function referred by “#submit” attribute of submit button. I’ve also implemented data retrieval code and works great.
Here’s my problem – I don’t know how to display retrieved data. I’ve tried several approaches in an attempt to find the solution.
First, with theme function, hoping that printing the return value of it would display the data. Second, setting “#action” element of form array with newly registered url, as I thought using the same url as form would only cause drupal to return that form instead and not my data. So, I creates a static variable and stores all the retrieved data in it;this is done inside submit function by the way. When I checked this variable inside menu callback, this variable is not set.
To summarize my problem, form has different access url than form submit, such as
Form url – http://....?q=mymodule/form
Submit url (value of ”#action”) – http://....?q=mymodule/execute
, and the data I’ve set inside submit function to static variable is not available in menu callback. How do I make the data available?
Here’s part of my code -
static $retrieved_data;
function mymodule_menu() {
$command = array();
$command['mymodule/form'] = array(
'title' => 'user input',
'page callback' => 'response',
'page arguments' => array('form'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$command['mymodule/execute'] = array(
'title' => 'Search',
'page callback' => 'response',
'page arguments' => array('execute'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $command;
}
function _response($paRequest){
switch($paRequest){
case "form":
return drupal_get_form("_myform");
break;
case "execute":
return $retrieved_data;
break;
}
}
function _myform(&$form_state) {
$form['#action'] = url($base_path)."?mymodule/execute";
.....
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('_data_retrieve'),
);
return $form;
}
function _data_retrieve($form, &$form_state){
/*data retrieval code*/
........................
$retrieved_data = db_fetch_object($result);
}
Thanks a bunch
Your method seems a bit complicated there. When I make systems with a form, I tend to do it this way. In your MYMODULE_menu() I would change the 'page arguments' => array('form'), to 'page arguments' => array('NAME_OF_FORM_FUNCTION'), where NAME_OF_FORM_FUNCTION would be _myform in this case. I would rename it to MYMODULE_MYFORMNAME.
then create a function:
MYMODULE_MYFORMNAME_SUBMIT($form, &$state) {
// Enter code here to save the data from the form that is stored in $state
// to the database with an SQL query or a node_save($node) if you are
// creating a node.
}
After that you can retrieve the data from the database in your _data_retrieve function and call that on the page where you want to retrieve the data.

hook_form_submit not being called

I'm trying to submit a form and use hook_form_submit.
The problem is the form is displayed via ajax and this results in hook_form_submit not being called.
$items['ajaxgetform/%'] = array(
'page callback' => 'ajaxgetform',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
function ajaxgetform($form_id) {
drupal_get_form($form_id);
return drupal_json($panel);
}
function_myform_form($form_state) {
$form['myform'] = array(
'#title' => 'myform value',
'#type' => 'textfield',
'#default_value' => 'myform default value'
);
$form['#action'] = url('myurl');
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'submit'
);
$form['#ajaxsubmit'] = TRUE;
return $form;
}
hook_form_alter() does get called.
Below doesn't get called?
function myform_form_submit($form, $form_state) {
// ...
}
I'm not sure if this is a common problem, but i've been stuck for hours trying to make it work.
If I remove $form['#action'] = url('myurl'); myform_form_submit() gets called. However I get a white screen with jason script.
There is no hook_form_submit(). Instead, you register submit handlers with $form['#submit']. So, if you want to call myform_form_submit() when the form gets submitted, add:
$form['#submit'][] = 'myform_form_submit';
to myform_form(). Take a look at the 5.x to 6.x form changes and the Forms API reference for more info.
Is your form displayed on the page at myurl ? In order for a form submission to be processed, the form as to be displayed (using drupal_get_form()) on the page used as action.
You may also try to se the form #redirect to the landing page URL instead of its #action. This way, the form is submitted to its generating URL but the user is redirected to your destination page after processing.

Resources