Good morning,

I'm relatively new to Drupal and working on my first module.

I've successfully created a new form for my module:

function timeoff_form(&$node) { 

	
	$form['info'] = array(
    '#type' => 'fieldset',
    '#title' => t('Employee Info')
  );
  
  $form['info']['employee_name'] = array(
    '#type'=> 'markup',
    '#value' => t('<div class="form-item"><label for="edit-date_submitted">Employee Name: <div class="container-inline"><div class="form-item">' . $user->name . '</div></div></label></div>'),
  ); 
  
  $form['info']['date_submitted'] = array(
    '#type'=> 'markup',
    '#value' => t('<div class="form-item"><label for="edit-date_submitted">Date Submitted: <div class="container-inline"><div class="form-item">' . date("l, F d, Y") . '</div></div></label></div>'),
  ); 
  
  $form['info']['clock_number'] = array(
    '#type'=> 'textfield',
    '#title' => t('Clock #'),
    '#required' => TRUE,
    '#maxlength' => 20
  ); 
  
  $form['info']['department'] = array(
    '#type'=> 'textfield',
    '#title' => t('Department'),
    '#required' => TRUE,
    '#maxlength' => 40
  ); 

  $form['request_info1'] = array(
    '#type' => 'fieldset',
    '#title' => t('Request #1'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  
  $form['request_info1']['dates_out1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Date(s) to be out'),
    '#required' => TRUE,
    '#size' => 25,
    '#maxlength' => 100
  ); 
  
  $form['request_info1']['times_out1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Time(s) to be out'),
    '#required' => TRUE,
    '#size' => 25,
    '#maxlength' => 100
  ); 
  
  $form['request_info1']['reasons1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Reason(s)'),
    '#required' => TRUE,
    '#size' => 60,
    '#maxlength' => 250
  ); 

  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit For Approval'));
  return $form;
}

The problem that I'm having is that I'd like to be able to modify the layout of the form. I want to be able to $form['request_info1']['dates_out1'] and $form['request_info1']['times_out1'] fields next to one another instead of on top of one another.

What is the best way to do this using the new 4.7 forms API?

I've read the Forms API quickstart guide, but I couldn't get my page working without putting the form in the "hook_form" function (the quickstart guide uses "test_page" to hold the form). What am I missing here? What is the correct way to apply a theme to a form using the new 4.7 forms API?

Thanks in advance,
-mike

Comments

casey’s picture

You can add the #theme property coupled to a callback function.

$form['info'] = array(
    '#type' => 'fieldset',
    '#title' => t('Employee Info'),
    '#theme' => 'timeoff_form'
  );

function theme_timeoff_form(&$form) {
  //..
  return $output;
}

or to a part of the form:

  $form['request_info1'] = array(
    '#type' => 'fieldset',
    '#title' => t('Request #1'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#theme' => 'timeoff_form_request_info1'
  );
ultimike’s picture

Casey,

Thanks for your quick reply - but I'm not sure how to implement this correctly.

Ideally, I'd like the theme to control the layout of several form fields. Using #theme seems like it would only allow me to theme a single field at a time. Does that make sense? How could I theme several fields at once?

For example:

$form['request_info1'] = array(
    '#type' => 'fieldset',
    '#title' => t('Request #1'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  
  $form['request_info1']['dates_out1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Date(s) to be out'),
    '#required' => TRUE,
    '#size' => 25,
    '#maxlength' => 100
  ); 
  
  $form['request_info1']['times_out1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Time(s) to be out'),
    '#required' => TRUE,
    '#size' => 25,
    '#maxlength' => 100
  ); 
  
  $form['request_info1']['reasons1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Reason(s)'),
    '#required' => TRUE,
    '#size' => 60,
    '#maxlength' => 250
  ); 

In the above code, I'd like to be able to place "dates_out1" and "times_out1" next to one another using either tables or CSS positioning. How should I apply the #theme in these case?

Here's my proposed theme code:

function theme_request_info1($form) {
  $output = '';
  $output .= form_render($form['request_info1']);
  $output .= '<br/><br/>';
  $output .= '<table><tr><td>';
  $output .= form_render($form['request_info1']['dates_out']);
  $output .= '</td><td>';
  $output .= form_render($form['request_info1']['times_out']);
  $output .= '</td></tr><tr><td>';
  $output .= form_render($form['request_info1']['reasons']);
  $output .= '</td></tr></table>';
  $output .= form_render($form);
  return $output;
}

What am I missing here?

Thanks,
-mike

high1memo’s picture

I needed to do the exact same thing, creating a submit form for my own module, but change the way the fields appear, make them side by side etc.

From what I saw there were many ways, including themeing etc, but in the end I went for what seemed to be the easiest way for me, using prefix and suffix parramerers and not using any theme functions, everything in the hook_form like you originally did:

  $form['request_info1']['dates_out1'] = array(
    '#type'=> 'textfield',
    '#title' => t('Date(s) to be out'),
    '#required' => TRUE,
    '#size' => 25,
    '#maxlength' => 100
    '#prefix'			=> "<div class='DateOut'>",
    '#suffix'			=> "</div>",
  );
 

and in your css set dateout to have float:left;
for your reasons, you want to clear:left etc.

mtinay’s picture

your theme function should be:

function theme_request_info1($form) {
$output = '';
$output .= form_render($form['request_info1']);
$output .= '<br/><br/>';
$output .= '<table><tr><td>';
$output .= form_render($form['dates_out']);
$output .= '</td><td>';
$output .= form_render($form['times_out']);
$output .= '</td></tr><tr><td>';
$output .= form_render($form['reasons']);
$output .= '</td></tr></table>';
$output .= form_render($form);
return $output;
}