drupal

Drupal Form API 'value' element

It’s common to use hidden value in a form to specify certain variable that was meant to logic which would handle the form processing rather than the user facing the form, hence the name ‘hidden’. Drupal Form API provide special element ‘value’ that can be used for the same task except that the value would not be sent together with the form. Let say you need to main a refference to customer_id when user entering their order in order form, the typical way is to used hidden element like this:-

$form['customer_id'] = array('#type' => 'hidden', '#value' => $customer_id);

This would put the value as a hidden form element and sent along other form value when user submit the form. The alternative is to use the ‘value’ element:-

$form['customer_id'] = array('#type' => 'value', '#value' => $customer_id);

No value would be sent to the browser but it’s still available to the form submit handler just like any other element. Neat idea, I think.

Drupal Form API Gotcha

Doing an upgrade of my app from Drupal 4.7.x to Drupal 5.x. The big difference in Form API in Drupal 5.x vs 4.7.x is on how drupal_get_form (the way form is build) work. In 4.7.x, drupal_get_form work through a push model where we supply the array of form definition to the function call:-

function customer_edit($customer) {
  $form = array();
  $form['customer_name'] = array(
    '#type' => 'textfield',
    '#title' => 'Name',
    '#default_value' => $customer->name
  );
  return drupal_get_form($form, 'customer_edit');
}

The second argument is the form_id. In 5.x however, this has changed to pull model where the form definition need to be build in a dedicated builder function.

function customer_build_form() {
  $form = array();
  $form['customer_name'] = array(
    '#type' => 'textfield',
    '#title' => 'Name',
    '#default_value' => $customer->name
  );
  return $form;
}

function customer_edit($customer) {
  return drupal_get_form('customer_build_form');
}

Now the first argument to drupal_get_form function call is the name of the form builder function. Another way is to implement the new hook introduced hook_forms to do some complex mapping of form_id to builder function.

function customer_forms() {
  $forms = array();
  $forms['customer_edit'] = array(
    'callback' => 'customer_build_form'
  );
  $forms['customer_add'] = array(
    'callback' => 'customer_build_form'
  );
}

function customer_edit($customer) {
  return drupal_get_form('customer_edit');
}

I got some problems when using the hook_forms approach. No errors from PHP process and Nginx just gave an ‘500 server error’. Further checking revealed that the problem was with the form_id which is similar to already defined function name. My guess was some recursive calling occured when drupal_get_form first try to call a function named customer_edit as being used in the form_id. Unfortunately, the calling function was also a customer_edit. So the fix is, never used form_id that is similar to already defined function since drupal_get_form will first look for it instead of relying on the hook_forms if it is implemented.

new layout

Finally, got my own layout instead of the stock drupal’s template. Not my own actually. The layout was taken from andreas03 template at openwebdesign.org website. FYI, openwebdesign.org is a fork from oswd.org project following recent issues with the oswd maintainer which lead to the oswd being temporarily offline. Both sites are now back to operational but look’s like more will move to the new openwebdesign.org website. Andreas is one of my favourites designer there. All his templates feature a clean XHTML markup and easy to extend. I got some problem with IE, mostly with the overflow: auto attribute which IE failed to render properly. A little hack seems to fix the problem:-

pre {
  overflow: scroll;
  border: 1px solid #ddd;
  margin-left: 20px;
  padding: 3px;
  font-size: 1.1em;
  width: 97%;
}

/* IE Fixes */
html body pre {
  overflow: auto;
  border: 1px solid #ddd;
  margin-left: 20px;
  padding: 3px;
  font-size: 1.1em;
}

it based on this forum post. Thanks to Andreas anyway for such a nice template. If not because of this post, this layout is valid XHTML 1.1.

Update:

Play a little bit with inline list style for the topic block.

no foreign key in drupal's schema

While playing with Drupal, I got some problem with the forum. The listing show’s that there’s one topic in the category but when I clicked it, the topic is not exist. I thought it was permission problem but after playing with the permission settings, it’s still the same. Then I decide to look directly into the database. With some sql command, I quickly found that the topic is really not exist in the node table but it still referenced from the forum table (which implement many-to-many relationship with the node table). This thing should not happened if foreign key constraint were implemented but a quick look on all the tables show’s that Drupal do not use any foreign key constraint in their schema. I can’t see the argument why they don’t leverage such a good feature provided by PostgreSQL. Anyway, I’m going to patch the schema to add foreign key constraint so that I’ll not wasting my time debugging why certain record is still referenced by some tables even though they were not exists anymore.

Syndicate content