0

I am trying to create a form which calls an external template file to format the form but ended up into a typical issue. This is what I was doing. I created a hook menu and called a theme, in the theme declared the template, and in template called the form elements and rendered along with html code. Everything is working fine except the submit button. If I render form directly, submit is working, or if I use drupal_get_form in menu page callback, it works (again template is not getting applied). I'm confused what am I doing wrong. I am a newbie so excuse me if this is a repetitive or stupid question.

Here is my code. My module file named agents.module

<?php
function agents_menu(){
  $items=array();

  $items['myform']=array(
    'title'=>'Form',
    'description'=>'Submit Form into database',
    'page callback'=>'agents_form', 
    'access callback'=>TRUE,
    'access arguments'=>array('access content'),
    'type'=>MENU_CALLBACK,
  );

  return $items;
}

function agents_form(){
  return theme('students');
}

function agents_theme(){
  return array(
    'students' => array(
        'render element' => 'form',
        'template' => 'customTemplate',
    ),
  );
}

function students_form($form, &$form_state){
  $form = array();
  $form['efname'] = array(
    '#type' => 'textfield',
    '#title' => 'First Name',
    '#size' => 28,
    '#maxlength' => 10,
    '#required' => TRUE, 
  );

  $form['elname'] = array(
    '#type' => 'textfield',
    '#title' => 'Last Name',
    '#size' => 28,
    '#maxlength' => 10,
    '#required' => TRUE,
  );
  $form['submit_btn'] = array(
    '#type'=>'submit',
    '#value'=>'Submit',
    '#submit' => 'agents_myForm_submit'
  );
  return $form;
}

function students_form_validate($form, &$form_state){
  dpm($form_state['ename']);
}

function students_form_submit(){
  dpm('into submit');
}

and my customTemplate.tpl.php code looks like this

<?php 
  dpm(drupal_get_form('students_form'));
  $form = drupal_get_form('students_form');
?>
<div class="left_div">
  <?php print render($form['efname']); ?>
  <?php print render($form['elname']); ?>
</div>
<div class="right_div">
  <?php print render($form['submit_btn']); ?>
</div>
<?php
  dpm(render($form['form_build_id']));
  print render($form['form_build_id']);
  print render($form['form_token']);
  print render($form['form_id']);
?>
<?php print drupal_render_children($form);

I am a newbie to drupal, and I was not able to figure out what am I doing wrong. If I directly render the form without rendering submit individually, (i.e. print render($form) ) it works fine. It would be a great savior of the day if someone helps me cross this hurdle.

2 Answers 2

0

You don't want to run your drupal_get_form from inside your template, you want to render it from your page callback. You'll instead declare the theme for your form with $form['#theme'] = 'students' in order to use your template.

function agents_form() {
  $form = drupal_get_form('students_form');
  return render($form);
}


function students_form($form, &$form_state){
  $form = array();
  $form['efname'] = array(
    '#type' => 'textfield',
    '#title' => 'First Name',
    '#size' => 28,
    '#maxlength' => 10,
    '#required' => TRUE,
  );

  $form['elname'] = array(
    '#type' => 'textfield',
    '#title' => 'Last Name',
    '#size' => 28,
    '#maxlength' => 10,
    '#required' => TRUE,
  );
  $form['submit_btn'] = array(
    '#type'=>'submit',
    '#value'=>'Submit',
  );

  $form['#theme'] = 'students';

  return $form;
}

You also had a '#submit' attribute on your submit button element but it would need to be set as an array rather than a string '#submit' => array('agents_myForm_submit'), However I didn't see that submit function defined so I removed it.

Then your customTemplate.tpl.php can be as simple as:

<div class="left_div">
  <?php print render($form['efname']); ?>
  <?php print render($form['elname']); ?>
</div>
<div class="right_div">
  <?php print render($form['submit_btn']); ?>
</div>
<?php print drupal_render_children($form); ?>
5
  • Vola. It worked. U r the man thumbson. I have another questions related to this though. When I submit, and if fails in validation, the formatting is going for a toss and a simple form is getting displayed. How to come over this issue? Commented Feb 19, 2015 at 5:27
  • Are your styles being overridden by the error styles?
    – thumbson
    Commented Feb 19, 2015 at 5:37
  • I am using a custom css for my form which defines the "left_div" and "right_div" and also for labels. Any suggestions? Commented Feb 19, 2015 at 5:46
  • The HTML structure remains the same, at least for me, so I still see the left_div and right_div containers when validation fails. It could be a theme or css issue.
    – thumbson
    Commented Feb 19, 2015 at 15:00
  • Thanks a ton thumbson. I figured the issue is with css. When validation fails it is not calling the attached css. The turn around I figured is to attach the css to module info file and define classes there, which works fine for me. I thank you for helping me figure out my issues. Thanks a ton buddy Commented Feb 19, 2015 at 22:12
0

Your page callback should reference the $form building function directly. In that case that means changing

'page callback'=>'agents_form', 

to

'page callback'=>'students_form', 

Don't worry about wrapping it in a theme() function, it is unnecessary.

Note that the key you use in $items[KEY] determines the path of the form. So once you make the first change suggested here, you should be able to view the form at http://yoursite.com/myform

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.