cck witch - multi-page cck forms for drupal

the blessing and curse of cck is the ability to quickly create very complex node types within drupal. it doesn't take very long before the input form for a complex node type has become unmanageably long, requiring your user to do a lot of scrolling to get to the bottom of the form. the obvious solution is to break your form into multiple pages, but there is no easy way to do this. there do exist two proposed solutions to this, the cck wizard module and a drupal handbook entry. however, the well-intentioned cck wizard module doesn't seem to work, and the example code in the drupal handbook becomes tedious to repeat for each content type. to fill the void, i bring you cck witch

cck witch is based on the same premise as the handbook entry : the most natural way to divide a cck form into pages is to use field groups. from there, however, cck witch diverges, taking a relatively lazy, yet effective approach to the problem of multi page forms: on every page we render the entire form, but then simply hide the fields and errors that do not belong to the current step. it also offers an additional feature : when the form is complete and the node is rendered, an individual edit link is provided for each step - allowing the user to update the information only for a particular page in the form, without having to step through the entire wizard again.

if you've now read enough to be curious to see the goods, then please, be my guest and skip straight to the live demo.

the demo

in the demo, you will walk through a three step multi page cck form that invites you to specify your dream house. before proceeding to the next step in the form, the user must complete the required fields on the previous steps. on all steps other than the first step, the user may go back and edit their data for the previous step.

when the form is complete and the node is viewed, we add an edit link inside each field group. clicking this link allows the user to edit only the fields within that group, rather than requiring the user to step through the entire form again.

disclaimer

be warned, this is a pre-alpha release. also, this wizardly wonder is not meant for the drupal novitiate. before using it you must

  • patch drupal core, adding 4 lines to the form_set_error function.
  • override two form related theme functions
  • follow a simple set of conventions when configuring your cck content type

manual

step zero - download cck witch

get your copy of this pre-alpha release here

step one - patch drupal core

in forms.inc replace the form_set_error with the following method. this exposes an option to remove errors from the list. it also stops drupal from adding form errors to the drupal message list. do not perform this step without also performing step two. if you do, all form errors will mysteriously vanish.

function form_set_error($name = NULL, $message = '', $remove = FALSE) {
  static $form = array();
 
  if(!$remove) {
    // Set a form error
    if (isset($name) && !isset($form[$name])) {
      $form[$name] = $message;
    }
  }
  else {
    // Remove a form error
    if (isset($name) && isset($form[$name])) {
      unset($form[$name]); 
    }
  }
 
  return $form;
}

step two - override two form theme functions

next, you need to override the theme function for a form element to display the form error messages inline in your form, instead of in a big blob of messags at the top. this is a nice thing to do regardless of whether or not you want multi page cck forms. do this by overriding theme_form_element method and then adding the following in the location of your choice. (right at the bottom, immediately before the closing div will do fine.)
  if($element['#parents']) {
    $form_element_error = form_get_error($element);
  }

  if ($form_element_error && $element['#type'] != 'radio') {
    $output .=' <div class="form-error">' . $form_element_error . "</div>\n"; 
  }
and, if you want all the buttons at the bottom of the form to line up nicely, override the theme_node_form method with the following
function theme_node_form($form) {
  $output = "\n<div class=\"node-form \">\n";
  $output .= "  <div class=\"standard\">\n";
  $output .= drupal_render($form);
  $output .= "  </div>\n";
  $output .= "</div>\n";
  return $output;
}

step three - configure your cck content type

when configuring your cck content type, create one group per page. you must name the groups "step 1", "step 2", etc. also, you must visit the display fields tab and submit the form there. you don't have to change anything, just submit the form. (this is clearly a cck bug, but we'll just work around it for now.)

see below for an example configuration:

step four - configure cck witch

finally, visit admin -> content -> multi-page form settings and set the number of pages for each cck content type. the cck witch module will only interact with those content types where the number of pages is greater than one.

future improvements

  • currently, cck witch presumes that your content type does not include a body field. complex cck node types rarely do. handling the body field is easy, it's just not obvious to me which page the body should appear on.
  • if there are other, non-cck options on your form (for example, the administrative meta tags or menu settings) these currently appear on all pages of the form. you can set them whenever you please. possibly, these should all be moved to an implied final page in the flow?

I recently installed this

I recently installed this module, and I love it! It's exactly what I needed. However, I wanted to force the author to "preview" their post (it's an application form) before submitting. When i enable forced preview in drupal, it disables the "next" button :-( (well, on the first page), so I doubt it will work on any pages either. Any clues on a workaround?

thanks!

do you have any plans to

do you have any plans to update your approach for drupal 6.x. I am excited to hear from you.

Hi, This would be a great

Hi,

This would be a great addition to drupal (hopefully also drupal 5!)
Please build a *.dev version on drupal.org so from there it can grow!
Thanks for considering.
greetings,
Martijn

This really would be a boon

This really would be a boon for my social networking site. the amount of detail needed over and above of the more run of the mill site makes my forms miles long!

Please release this ASAP... pretty please!

Mouse

Hey there, is there any

Hey there, is there any progress with this module, it vertainly deserves to be released as a full module on D.O!!
Patchak

Nice module! Two quick

Nice module! Two quick questions:

1. How do I show the steps in increasing order? Currently they display step 3, then 2, then 1 on the node view (e.g. http://www.johnandcailin.com/house/483)
2. How do I modify the group label name to show something other than Step 1, Step 2, like Bedroom Details, on the demo form?

Thanks!

1. to set the order of the

1. to set the order of the steps (groups) set the weight for the group at administer -> content types -> house -> manage fields.

2. ahh, this is a dirty little secret of cckwitch. you must initially name your steps "step 1", "step 2", etc, or the module won't work. after you've done that though, you may go back and rename your group to whatever you want. just go to administer -> content types -> house -> manage fields -> configure link for the group and then change the label.

Looks great, looking forward

Looks great, looking forward to seeing a post-alpha version. It's not that I am afraid of patching the core, but side effects drive me nuts, especially when I eventually forget what they are due to.

Greetings

Any idea when post-alpha

Any idea when post-alpha goes live?

The functionality in itself

The functionality in itself is great, but it's a real shame you require your users to patch drupal core. Another road you can take, is altering $_SESSION['messages']['error']. You can check the array and remove all $wrongstep . t(" field is required.") strings. It might not be very clean, but at least a lot cleaner than patching core.

yes, i did ponder that

yes, i did ponder that approach. it seemed a little awkward to try and pull out the data from $_SESSION since at the point it's pretty much unstructured data. it seemed more elegant to pull out the data from the structured array of errors.

i do take your point though. perhaps it's worth a bit of grunge to not require a core patch. i will give this some further thought.

Any joy with the session

Any joy with the session approach - cck witch looks great but I really don't want to touch the core.

Thanks!

Wonderful solution. Thank

Wonderful solution. Thank you!

I am lookng forward to find this on d.o. The sooner the better. Remember the sixth lesson in Eric S Raymond's The Cathedral and the Bazaar: "Release early. Release often. And listen to your customers." .

Please note, this entry has been closed to new comments.