I read through the documentation and it talks about what the module can do. I cannot find anything on how to actually do it. Is there a getting started or tutorial that can help me get moving forward?

Thanks,

-Jeff

Comments

vm’s picture

documentation link on the project page? = http://drupal.org/node/350241

herteljp@yahoo.com’s picture

Been there. I must be missing something. I must be missing something in the process. Do I have to create some type of template file on the web server or is there suppose to be some type of layout screen for me to specify the fields?

Thanks,

-Jeff

vm’s picture

It is important to note, however, that this module does nothing on its own. You must refer to one of the included themes from PHP code in order for there to be any effect.

the above quoted from the 1st page of documentation

jamesmcd’s picture

I would have to agree that it is a bit confusing knowing where to start. It may well say:

It is important to note, however, that this module does nothing on its own. You must refer to one of the included themes from PHP code in order for there to be any effect.

However I am at a loss as to where the PHP code is placed.. is it in the teplate.php file?

If this is simple, then please excuse my ignorance and point me in the right direction..

Is there any other documentation.. screencasts etc that could shed better light on the process?

Many thanks

gribnif’s picture

Code is usually written directly in the .module or .inc files of your module, as it is an extension to Forms API. There's nothing, technically, to keep you from using it in a .tpl file, but Forms API code isn't normally used there.

There is no layout screen, because the purpose of the theme is to let you enter the row/column numbers of form elements directly in your PHP code. That would be difficult to do graphically, though Lullabot (I think?) has been working on a Javascript-based forms creator which could, in theory, be made to work with form_panel in the future.

I've been meaning to add some more concrete code examples, but haven't gotten around to it yet. In the meantime, here's a basic example I just whipped up. It is a modification to the code in modules/user/user.admin.inc:

function user_admin_access_form(&$form_state, $edit, $submit) {
  $form = array('#theme' => 'form_panel_table');
  $form['aid'] = array(
    '#type' => 'value',
    '#value' => $edit['aid'],
  );
  $form['status'] = array(
    '#type' => 'radios',
    '#title' => t('Access type'),
    '#default_value' => isset($edit['status']) ? $edit['status'] : 0,
    '#options' => array('1' => t('Allow'), '0' => t('Deny')),
    '#weight' => 2001,
  );
  $type_options = array('user' => t('Username'), 'mail' => t('E-mail'), 'host' => t('Host'));
  $form['type'] = array(
    '#type' => 'radios',
    '#title' => t('Rule type'),
    '#default_value' => (isset($type_options[$edit['type']]) ? $edit['type'] : 'user'),
    '#options' => $type_options,
    '#weight' => 2002,
  );
  $form['mask'] = array(
    '#type' => 'textfield',
    '#title' => t('Mask'),
    '#size' => 30,
    '#maxlength' => 64,
    '#default_value' => $edit['mask'],
    '#description' => '%: '. t('Matches any number of characters, even zero characters') .'.<br />_: '. t('Matches exactly one character.'),
    '#required' => TRUE,
    '#weight' => 3001,
  );
  $form['submit'] = array('#type' => 'submit', '#value' => $submit, '#weight' => 9000);
  $form['#submit'] = array('user_admin_access_form_submit');

  return $form;
}

If you compare this to the original source, you'll see that all I had to do was add three #weights and a #theme to get the radio buttons to appear side-by-side in a table--no separate theme function or inline HTML needed.

aharown07’s picture

I'm also wrestling with how to use the module. Are you saying core hacks are necessary? If a ...tpl.php option is possible, that sounds wiser, but creating templates for overrides is still a difficult concept for me so any hints on what to name the file, where to put it, etc. would be much appreciated.
Once I have that working, I can probably just plug values in here and there and see what happens until I understand what to do.

gribnif’s picture

@aharown07: I'm not saying you have to modify core. The example I gave is just that, an example of how a part of core *could* be modified to use form_panel.

Form_panel is aimed toward module and core developers, not people who are strictly theme developers. Code that uses form_panel is generally part of a .module file. It is added to functions like [modulename]_[nodetype]_form(), which use PHP code to generate forms. If you are using .tpl.php files to modify the appearance of forms, then form_panel is probably not going to help.

Assuming you are developing at the Forms API level, not the theme level, then perhaps it would help if you were to describe what form you would like to put into a table. If you post some source code, that would help even more.

aharown07’s picture

Ah. I get it now. Thanks.
Suggestion: someone might want to mention in a prominent place on the module home page "This module is for module developers" or something along those lines. I stumbled onto it in search of something I could install, enable, then manipulate standard Drupal forms or other people's module forms.

For others looking for that sort of thing, Form Defaults is the closest thing I've found, though it has limitations.

gribnif’s picture

Status: Active » Fixed

I have made the suggested change to the homepage.

I'm leaving this topic open until I do some more sample code.

gribnif’s picture

Status: Fixed » Active

Meant to not change the status. Changing it back.

srwright’s picture

I tried submitting an issue but now it seems to be gone... anyways, has anyone been able to get this working with fieldsets? If so, can you please tell me how?

Thanks

P.S. Gribnif, any chance of seeing the code that generated the screenshot?

gribnif’s picture

@srwright: The other ticket is not missing, you're just not seeing it because I closed it. Closed tickets aren't shown, by default; you have to change the selections at the top of the Issues page. See #455272: Does not work in fieldsets.

The code to generate the form in the screenshot is part of a complex, custom module, and not something that would serve well as an example. I do plan to come up with some better examples, but have not yet had the time.

Mike_Waters’s picture

anyways, has anyone been able to get this working with fieldsets? If so, can you please tell me how?

Rather than give the form the '#theme' => 'form_panel_table' attribute, give it to the fieldset, and give the items inside the fieldset a #weight.
Actually, they can be nested; you can give the $form the '#theme' => 'form_panel_table' attribute, as well as each fieldset, as long as you assign a #weight (or #form_panel_row/col) attribute to the fieldset(s). It will create a nested table structure, with the form encapsulated in a table, each fieldset encapsulated in tr/tds, and the items inside the fieldset encapsulated in another table.
ex, nesting:

	$form = array('#theme' => 'form_panel_table');
	$form['header'] = array(
		'#type' => 'fieldset',
		'#tree' => TRUE,
		'#title' => t('this is a fieldset'),
		'#theme' => 'form_panel_table',
		'#weight' => 2001,
	);
	$form['header']['name'] = array(
		'#type' => 'textfield',
		'#title' => t('Your name'),
		'#description' => t('Please type your name here.'),
		'#weight' => 2001,
	);
	$form['header']['type'] = array(
		'#type' => 'select',
		'#weight' => 2002,
	);
	$form['header']['submit'] = array(
		'#type' => 'submit',
		'#weight' => 2003,
	);

This will create a structure like this:

<form method="post" action="/">
<table class="form-panel">
    <thead/>
    <tbody>
      <tr class="form-panel-row">
        <td class="form-panel-cell">
          <fieldset>
            <legend>this is a fieldset</legend>
              <table class="form-panel">
                <thead/>
                <tbody>
                  <tr class="form-panel-row">
                    <td class="form-panel-cell">
                      <label>Your name: </label>
                      <input type="text" />
                      <div class="description">Please type your name here.</div>
                    </td>
                    <td class="form-panel-cell">
                      <select ...... />
                    </td>
                    <td class="form-panel-cell">
                      <input type="submit ...... />
                    </td>
                  </tr>
                </tbody>
              </table>
            </fieldset>
          </td>
        </tr>
      </tbody>
  </table>
</form>

To not nest (i.e. the only tables are inside fieldsets), remove the #theme attribute from the $form and remove the #weight attribute from each fieldset.

Maintainer: Thanks for this great module! I can't tell you how many hours I have spent on form layout. Throw cross-browser compatibility into the mix, and it gets real hairy real fast.

beckyjohnson’s picture

So, I am mainly a theme developer, but if I am understanding this correctly, I need to build a basic module for this form code to go in, right? So, basically a .info file and a .module file with the code on it that makes it work with form panels?

Also, does this work with conditional fields? I am using the Conditional fields module and it would suck it the two modules didn't play well together....
Thanks,
Rebecca

Mike_Waters’s picture

Yes, generally, forms are defined inside custom modules; if you are not comfortable with this, you should check out the Webform module; it allows you to create forms in a designer, as full-on nodes. This is useful in some cases, however being nodes you can't just stick them anywhere on the page without using some other contrib module such as Panels or Views, and they have addressable URLs and some additional overhead that you may not want/need. Plus I don't think it works with Form Panel.

EDIT: I just read on Drupal Planet that there is a module that lets you easily embed a Webform in a block: clicky . With this module, you "can just stick them anywhere".

If you want to design your own form, here are some resources for a beginner:
Forms API Quickstart Guide
Ten Example Forms

And yes, you just create the .info file, and a .module file with a function for the form definition (this is where Form Panel is helpful) and a few necessary helper functions (to validate the form data, or to define what happens when the form is submitted, etc.).

I do not think that Conditional Fields will work with this module, as it seems (from a quick read of it's docs) that it is only used for CCK, which is a module that allows you to create custom content types but not forms.

HTH

beckyjohnson’s picture

So if I wanted to use this module, or try to use it to adapt a content type form....that wouldn't be a good idea or a wrong usage of this module?

Becky

gribnif’s picture

You could do it within a hook_form_alter. Here's an example taken from some code of mine. For the content type "my_content_type", it modifies the fields contained in the group called "group_week_day", putting them into a 3-column table.

function my_module_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if ($form_id == 'my_content_type_node_form') {
      $form['group_week_day']['#theme'] = 'form_panel_table';
      $form['group_week_day']['field_wd_start']['#weight'] = 2001;
      $form['group_week_day']['field_wd_end']['#weight'] = 2002;
      $form['group_week_day']['field_wd_increment']['#weight'] = 2003;
    }
  }
}
beckyjohnson’s picture

Awesome. I think I'm getting this! Can I choose to only format a part of my content type of do i have to do to the whole form?

Thanks!
Becky

gribnif’s picture

The example I gave only does a portion of the form. Basically, in order to get the correct theme, the fields you want to put into a table have to be in a sub-array, which is why I chose to group them in CCK.

You could also create a sub-array on-the-fly and move items from the top level of the $form tree into it, but that's a little more work.

beckyjohnson’s picture

OK I made a .info file and a .module file and put this code in my .module file as a test. this is just one group of fields...and actually it's not all the fields in the group, but I wanted to see what the form was looking like so far. I am not sure what I did wrong. Maybe I should have printed every field out? I don't know, but when I enabled the module and looked at my form, nothing had changed.....

<?php
function ps_form_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if ($form_id == 'certified-product-database_node_form') {
      $form['group_crn']['#theme'] = 'form_panel_table';
      $form['group_crn']['field_crn_active']['#weight'] = 2001;
      $form['group_crn']['field_mfg_name']['#weight'] = 3001;
      $form['group_crn']['field_firmware_id_url']['#weight'] = 4001;
      $form['group_crn']['field_ddf_and_url']['#weight'] = 5001;
      $form['group_crn']['field_release']['#weight'] = 6001;
      $form['group_crn']['field_arq_pkg1']['#weight'] = 7001;
      $form['group_crn']['field_bphy_pkgq']['#weight'] = 7002;
      $form['group_crn']['field_bmac_pkg1']['#weight'] = 7003;
      $form['group_crn']['field_bwa_pkg1']['#weight'] = 8001;
      $form['group_crn']['field_bwa_pkg2']['#weight'] = 8002;
      $form['group_crn']['field_clipc_pkg1']['#weight'] = 8003;
      
       print drupal_render($form);                    
    }
  }
}
?>

So....is my code wrong? I basically used the format you used on this thread as a model...

Becky

gribnif’s picture

A white screen is usually caused by a call to a missing function. In this case, the reason might be that the form_panel module isn't enabled. Make sure that it is. If you still see the problem, you'll have to look in your web server's error log for clues.

Also, you don't need to print anything or call drupal_render() in this case. That shouldn't cause the white screen, though.

beckyjohnson’s picture

I fixed the white screen problem. I had an errant <?php in there. ugh. So, now the error is fixed and my custom module and form panel is enabled but nothing on the form changed.

Becky

Mike_Waters’s picture

That's pretty slick, bypassing the forms api by hooking node_create for a custom content type...
Is this a general practice, or just something you hacked together?

Mike_Waters’s picture

Make sure you clear the cache after making theme changes.

Is your form now being rendered as a table, or is it still divs? If it is still divs, then you should make sure your hook_form_alter is working.
You might have the form_id wrong, so put a print_r() on the first line of your hook_form_alter implementation:

function yourmodule_form_alter(&$form, $form_state, $form_id) {
    print_r("Rendering form:" . $form_id);
    ...

You should see the form_id for each form being rendered on a page.

gribnif’s picture

@beckyjohnson: Actually, contrary to what MIke says, when you're dealing with hooks, you don't have to clear the cache; the change should take effect immediately. I do agree with Mike's suggestion to insert a print_r to make sure your code is being called.

@Mike_Waters: Well, the term "hack" is pretty subjective :-). IMHO, this is exactly the sort of thing that the hook is intended to permit: changing the appearance of a form. Technically, this isn't bypassing Forms API but, rather, working with it to alter the form elements before it renders them.

beckyjohnson’s picture

Ok! I did as you both suggested and I got this result:

Rendering form:certified_product_database_node_formRendering form:search_theme_form.

In my custom module I have this set up as the form id : certified-product-database_node_form.

I was wondering, since I am really only trying to put one of my field groups into a table format, do i need to use a specific form ID for that subset?

Becky

beckyjohnson’s picture

OK. So, I'm still hammering away at this.

This is my code, so far

<?php
function productshowcase_modify_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if ($form_id == 'cert_prod_db_node_form') {
      $form['group_crn'] ['wrapper'] =array(
      	'#theme' => 'form_panel_table');
      $form['group_crn']['field_crn_active']['#weight'] = 2001;
      $form['group_crn']['field_mfg_name']['#weight'] = 3001;
      $form['group_crn']['field_firmware_id_url']['#weight'] = 4001;
      $form['group_crn']['field_ddf_and_url']['#weight'] = 5001;
      $form['group_crn']['field_release']['#weight'] = 6001;
      $form['group_crn']['field_arq_pkg1']['#weight'] = 7001;
      $form['group_crn']['field_bphy_pkgq']['#weight'] = 7002;
      $form['group_crn']['field_bmac_pkg1']['#weight'] = 7003;
      $form['group_crn']['field_bwa_pkg1']['#weight'] = 8001;
      $form['group_crn']['field_bwa_pkg2']['#weight'] = 8002;
      $form['group_crn']['field_clipc_pkg1']['#weight'] = 8003;
                  
    }
  }
}
?>

I tried to add this in

 $form['group_crn'] ['wrapper'] =array(
      	'#theme' => 'form_panel_table');

because I was reading on another post (http://drupal.org/node/455272) that you had to do some trickery to get a field set to modify, which is what I'm trying to do. So I'm trying to emulate that but not with success.
On the post I saw, there is a wrapper around the field set. Is the code adding that "wrapper" class in or is that wrapper pre-existing. I can't find a wrapper in my field set that wraps around the whole thing. There is a wrapper of some kind around each individual field but not the whole thing....
Any more ideas about what I'm doing wrong? I think I'm really close...

Becky