1

I've got a form layout in which form elements are separated between 2 divs: one with float: left, the other with float: right. I have to keep it that way.

Is it fine to place form elements in different containers? Could I get any troubles with form validation or submitting?

What's the best way to do it, via hook_form_alter(), or something else?

P.S. I'm not developing a custom module, but a theme. Here is an example of the form HTML; it's not precisely what it's going to be, but it gives an idea.

<div class="custom-holder">
    <div class="custom-box">         
        <div>                               
            <input type="text" id="name" />
            <label for="name">First name:</label>
        </div>
    </div>
    <div class="custom-block">
        <div>
            <input type="text" id="surname" />  
            <label for="surname">Surname:</label>
        </div>
    <div>
</div>
3
  • Need more info here. What's the form you are trying to alter? Some forms have to be altered with a hook, whereas others can be changed with configuration settings. For example node forms can be managed with Display Suite or webforms with some well targeted CSS?
    – Angry Dan
    Commented May 22, 2013 at 19:34
  • It's going to be a "contact us" form. Commented May 22, 2013 at 19:52
  • I'd use the webform module for starters, it's almost always better to be customising your CSS to the markup than the other way around, so I'd be looking a using webform fieldset elements to split the output up and go from there with some well targeted CSS rules.
    – Angry Dan
    Commented May 23, 2013 at 8:55

1 Answer 1

1

I can't comment yet so I'll try to be broad. First, there are not any disadvantages to customizing your output html, the form process and validation will work just fine as long as you're not adding form tags to your html that you are hoping Drupal will also process.

You don't need hook_form_alter if you only want to modify the html. You can use, in your template.php file, hook_theme().

The first thing you would need is the id of the form. You can get this via viewing source or using the devel and devel themer modules.

Once you have your form id, within template.php:

/**
 * Implementation of hook_theme
 */
function yourthemename_theme($existing, $type, $theme, $path) {
  return array(
    'user_login' => array( // to modify user_login form, for example
      'render element' => 'form'
      )
  );
}
/**
 * Theme function
 */
function yourthemename_user_login($variables) {
  $user = drupal_render($variables['form']['name']); // use the devel module:kpr($variables), or print_r($variables) to look at the $variables['form'] element
  $pass = drupal_render($variables['form']['pass']);
  $remainder = drupal_render_children($variables['form']);
  // put the user field and pass field inside a custom div
  $output = '<div class="custom-block">' . $user . $pass . '</div>';
  $output .= $remainder;
  return $output;
}

Take a look at drupal_render() and drupal_render_children() but, basically, when you call drupal_render it 'renders' the element and remembers that it was already rendered. You use that with as many elements as you need to but always remember to render the children as well so that all of your hidden fields and drupal form stuff doesn't get left out.

Alternatively, I don't think I've come across a Drupal form I couldn't wrangle with some well-targeted CSS, if you'd rather go that way.

3
  • Thanks, that was helpful, drupal_render() and drupal_render_children() seem the ways of dealing with forms that I've overlooked, going to try them. Commented May 23, 2013 at 12:07
  • By the way, won't the form tag itself be omitted in your example function ? Commented May 23, 2013 at 12:19
  • No, it will still be rendered. Drupal is rendering an array of elements; when you use drupal_render() on a specific element, you are just telling the render engine that you are taking care of that part (including it manually), so don't include it. When you call drupal_render_children(), Drupal will render everything else in that form array ($variables['form']) and put everything inside the form tag Commented May 23, 2013 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.