Hi,

I have been struggling to implement the form api for quite a few days. But I cant seem to get through. I just need to know the basics as in

for a simple form of the type

user - textname for userfield

submit button.

When user enters name and clicks on submit button his name should go to a page where in a php code will print the content of the get or the post array.

Please can someone post a small code desciribing this. It would be of great help for the beginners to build upon. thanks a million in advance

Comments

crashpoint’s picture

hi,

I was searching through this site and it was mentioned on one page that this url has the working example of multipage forms. But the code contains just functions. How do we call them ? Do we need to put them in the form.inc? How is this code used ?

the url was

http://cvs.drupal.org/viewcvs/drupal/contributions/docs/developer/exampl...

joel_guesclin’s picture

Plagiarism, a great force for progress. I hope that the code below will help you. I lifted it out of one of my own modules (not contributed due to licensing issues in one of the components. It involves the three main bits you need for forms. The titles_admin function builds the form, the theme_titles_admin_form function takes care of sticking some of the fields into a table, and the titles_admin_form_submit function takes care of the actions executed after the user presses "Submit".

function titles_admin_form_submit($form_id, $form_values) {
  $edit = $_POST['edit'];

    $result = db_query('DELETE FROM {titles_settings}');
    for ($i = 0; $i < $form_values['titles_count']; $i++) {
      if ($edit["titles_display_name_$i"] != '') {
        if ($edit["titles_weight_$i"] == '') {$edit["titles_weight_$i"] = 0;}
        if ($edit["titles_days_up_$i"] == '') {$edit["titles_days_up_$i"] = 0;}
        db_query("INSERT INTO {titles_settings} (uid, display_name, which_column, weight, days_up) VALUES ('%d', '%s', '%d', '%d', '%d')", $edit["titles_uid_$i"], $edit["titles_display_name_$i"],$edit["titles_which_column_$i"],$edit["titles_weight_$i"], $edit["titles_days_up_$i"]);
        }
      }
    variable_set('titles_sticky_title', $edit["titles_sticky_title"]);
    variable_set('titles_sticky_days_up', $edit["titles_sticky_days_up"]);
    drupal_set_message(t('The configuration has been saved'));

}

function theme_titles_admin_form($form) {

  $header = array(t('User name'), t('Display name'), t('Column'), t('Weight'), t('Days on front'));
  $rows = array();
  $count = $form['titles_count']['#value'];
  $output = form_render($form['titles_count']);
  for ($i = 0; $i < $count; $i++) {
    $row = array();
    $output .= form_render($form['users']["titles_uid_$i"]);
    $row[] = $form['users']['titles_name_'.$i]['#default_value'];
    $row[] = form_render($form['users']['titles_display_name_'.$i]);
    $row[] = form_render($form['users']["titles_which_column_$i"]);
    $row[] = form_render($form['users']["titles_weight_$i"]);
    $row[] = form_render($form['users']["titles_days_up_$i"]);
    $rows[] = $row;

    }
  $output .= theme_table($header, $rows);
  $output .= form_render($form['titles_sticky_title']);
  $output .= form_render($form['titles_sticky_days_up']);
  $output .= form_render($form['titles_press_button']);
  return $output;
}

function titles_admin() {
/* Settings to determine
   - what will be the display name for each user to be published
     (and whether all users will be published or not)
   - whether to place titles for a user in left, middle, or right column
   - order in which users are to be published
*/
  $form = array();
// Set up the form to display settings
  $result = db_query('SELECT u.uid, name, display_name, which_column, weight, days_up FROM {users} u left outer join {titles_settings} t on u.uid=t.uid where u.uid > 0 order by name');
  $count = db_num_rows($result);
  $form['titles_count'] = array(
	'#type' => 'hidden',
	'#value' => $count,
	);
  for ($i = 0; $i < $count; $i++) {
    $user_setting = db_fetch_object($result);
    foreach (array('uid', 'name', 'display_name', 'which_column', 'weight', 'days_up') as $field) {
      switch ($field) {
        case 'uid':
	    $form['users']["titles_uid_$i"] = array(
		'#type' => 'hidden',
		'#value' => $user_setting->uid,
		);
	    break;
        case 'name':
	    $form['users']['titles_'.$field.'_'.$i] = array(
		'#type' => 'textfield',
		'#title' => '',
		'#default_value' => $user_setting->name,
		'#size' => 15,
		'#maxlength' => 90,
		);
	    break;
        case 'display_name':
	    $form['users']['titles_'.$field.'_'.$i] = array(
		'#type' => 'textfield',
		'#title' => '',
		'#default_value' => $user_setting->display_name,
		'#size' => 15,
		'#maxlength' => 90,
		);
	    break;
        case 'which_column':
	    $form['users']['titles_'.$field.'_'.$i] = array(
		'#type' => 'select',
		'#title' => '',
		'#default_value' => $user_setting->which_column,
		'#options' => array(0=>'Left', 1=>'Middle', 2=>'Right'),
		);
            break;
        case 'weight':
	    $form['users']['titles_'.$field.'_'.$i] = array(
		'#type' => 'textfield',
		'#title' => '',
		'#default_value' => $user_setting->weight,
		'#size' => 2,
		'#maxlength' => 2,
		);
            break;
        case 'days_up':
	    $form['users']['titles_'.$field.'_'.$i] = array(
		'#type' => 'textfield',
		'#title' => '',
		'#default_value' => $user_setting->days_up,
		'#size' => 2,
		'#maxlength' => 2,
		);
            break;
       }
     }
   }

   $form['titles_sticky_title'] = array(
	'#type' => 'textfield',
	'#title' => t('Sticky articles title'),
	'#default_value' => variable_get("titles_sticky_title", 'Stop press'),
	'#size' => 100,
	'#maxlength' => 100,
	'#description' => 'Title for the top box containing sticky articles',
	'#attributes' => NULL,
	'#required' => TRUE,
	);
   $form['titles_sticky_days_up'] = array(
	'#type' => 'textfield',
	'#title' => t('Sticky days up'),
	'#default_value' => variable_get("titles_sticky_days_up", '0'),
	'#size' => 2,
	'#maxlength' => 2,
	'#description' => 'Days that sticky articles remain sticky (and therefore displayed in top box)',
	'#attributes' => NULL,
	'#required' => TRUE,
	);
   $form['titles_press_button'] = array(
   	'#type' => 'submit',
	'#value' => t('Update'),
	);
   $output = drupal_get_form('titles_admin_form', $form);
   return $output;
}
crashpoint’s picture

hi joel,

thanks a lot for putting up your code. During this time i was searching and as I have drupal 4.7 installed. And the forms module is present for the 4.6 and cvs version which does not work with 4.7. I could not even activate access control for the same. I got the patch present at
http://drupal.org/node/43346.

Are you running version 4.7? If yes then did u install the patch and then worked out this code? and if not then
as you had said " I lifted it out of one of my own modules (not contributed due to licensing issues in one of the components.". Where do you call these functions ?

How can anyone write a simple form as in ?

page 1 - user (textbox) (button - submit)
page 2 - this page gets the params passed by page 1 and just displays them

In patching also I had this issue that the function forms_validate is written as follows :
-------------------
function forms_validate($form, $edit) {
--- survey.module 2006-06-06 14:52:19.000000000 -0700
+++ survey_new.module 2006-06-06 14:51:08.000000000 -0700
@@ -28,11 +28,11 @@
}
-------------------------

why does the person who has patched the code written the inclusion of survey_new.module in forms_validate? Shouldnt here be the inclusion of some code for forms_validate only? I have been onto these for the last 1 week and m really stuck in these things.

I really appreciate your taking out time to help me out. thanks once again

joel_guesclin’s picture

Sorry I took so long to reply, I've been rather tied up in other things :)

ome of your questions I don't understand, so I will try to explain what the code I've posted does. I'm using a straightforward install of 4.7.0 without any kind of patches. Of course this code won't work in 4.6 because the forms api has changed radically between 4.6 and 4.7. I never use cvs because I take it as given that CVS is unstable and does not necessarily work - no good for a live website IMHO.

1) The "titles_admin" function is called from "titles_menu" which is a Drupal hook that allow your module to add entries into the Drupal menus and also register a page with its path. It's all very standard, I suggest you look at almost any Drupal core module to see an example of a hook_menu function. Anyway, here is mine:

function titles_menu($may_cache) {
  $items = array();

  if ($may_cache) {
    $items[] = array('path' => 'titles', 'title' => t(''),
      'callback' => 'titles_page',
      'access' => user_access('access content'),
      'type' => MENU_SUGGESTED_ITEM);
    $items[] = array('path' => 'admin/settings/titles', 'title' => t('titles'),
                     'callback' => 'titles_admin',
                     'access' => user_access('administer titles'));
    }
  else {
//    titles_set_head();
    }
  return $items;
}

You can see there are two "items": one of these creates the "titles" URL and makes it refer to the "titles_page" function (we won't go into what that does...). The other creates the "admin/settings/titles" URL and points it to the "titles_admin" function. Notice also that this is where access to the function is controlled. You use the "hook_perm" function to create the permissions which you can then manage in access control.

2) The "titles_admin" function actually builds and displays the form (it does this right at the end by calling the "drupal_get_form" function. Notice that at the end of this function we create a "submit" button.

3) The "theme_titles_admin_form" function is called automatically by "drupal_get_form" (notice that the form id is also "titles_admin_form"). I do this because the formatting is a little more complex - I have a table of multiple rows. But in your very simple case you don't need this function at all, you can let it work automatically.

4) The processing after the user hits the "submit" button is handled in the "titles_admin_form_submit" function - again notice the way it matches the form id.

And you don't need to worry about anything else! Drupal is wonderful!

If you can't see how this works, then I suggest copying it into your module and changing bits and pieces like labels, form item types, and so on, and see the effect you get.