5

I'm still learning Drupal, and I was trying to use hook_form_alter() to resize a text field added from a module. My problem is that I don't think I'm indentifying the element correctly.

Here's the element code:

<input type="text" class="form-text form-autocomplete" value="" size="60" id="edit-2" name="2" maxlength="128" autocomplete="OFF">

Here's my module code:

/**
 * Implements hook_form_alter().
 */
if ($form_id == 'edit-2') {
  $form['text'] = array(
    '#type' => 'text',             
    '#size' => 25,
  );
}

I'm not sure what to do; any suggestions would be helpful.

Thanks!

9

The HTML id has nothing to do with $form_id.

$form_id is the name of the whole form. In most cases, it is the name of the function that generates the form unless hook_forms() is used.

Instead of checking the $form_id with an if condition, it is often easier to implement the more specific hook_form_FORM_ID_alter() hook. So if the form_id is BLA, you can directly create a function yourmodule_form_BLA_alter(&$form, &$form_state)and don't need to mess with $form_id at all.

There are exception when this doesn't work or isn't practically, but it most cases, it is recommended to use that hook (It's a performance improvement too, because your function will just be called for that specific form and not every single form in Drupal).

If you are not sure what $form_id is, implement hook_form_alter() and put a drupal_set_message($form_id) in there. That should then print all form ids of the page you are on, allowing you to easily pick the one you want to change.

About the name of the form element, you can't guess that from the HTML in most cases, because unless #tree is set to TRUE, the names are flattened, so it might be $form['some_fieldset']['example'] in the $form structure and just name="example" in HTML.

So, to find the element you want to change, there are two ways.

a) Look at the source code of the function that defines the form structure.

b) Use dpm($form) (requires devel.module).

I prefer the second method, and this is usually the second step after figuring out the $form_id, if I don't know exactly what I want to do. dpm() prints complex array/object structures in a very nice and browseable way. That is actually something you should get used to all the time when you work with Drupal. Don't just guess things. You're going to be wrong pretty often. Instead, if there are any variables that you want to use but don't know the exact structure of them, add a dpm($var), load the page/trigger the action and then you can exactly see what you are working with.

Edit:

The last problem is that right now, your code does completely replace that form element. Instead, you only want to override the #size property, like this:

$form['finder_form'][2]['#size'] = 25;
|improve this answer|||||
  • Thank you so much Berdir. I can't thank you enough. I pretty much had to google everything you said but it gave me the tools to get close to solving the problem. I'm not there yet though. I got to the part where I get an array from dpm($form) but I'm not sure to actually identify what is the element itself that I modifying. Its basically a text search box, but I can't seem to find any names that resemble it at all. Any tips of narrowing down what I want to modify? – Lostsoul Jun 22 '11 at 2:39
  • In my function I tried to add something like this: $form['2'] = array( '#type' => 'textfield', '#size' => 25, ); } but its actually not modifying the existing search bar, but adding a second one, which makes me think I am not identifying the element correctly. – Lostsoul Jun 22 '11 at 2:44
  • I saw in the dpm command, there was an element named 2(under the finder_form element which I think is the one I need). under "2", there was a bunch of options that looked like they were correct for the element I am trying to modify, but no luck. – Lostsoul Jun 22 '11 at 2:45
  • I managed to figure it out. 2 was the correct element but it was under another element, so I added: $form['finder_form']['2'] = array( '#type' => 'textfield', '#size' => 25, ); } and it worked. Right now I'm using an actual value for size, is there a way to make it relative so if a person has a larger/smaller screen it always looks good? – Lostsoul Jun 22 '11 at 3:13
  • sorry, last question..alot of my fucntionality is gone(it was an autocomplete search field)...does this mean I have to add all the elements I want back into my module above? or is there a way for it to only modify what I tell it to change? – Lostsoul Jun 22 '11 at 3:15
3

The problem is that you are looking at the HTML produced by Drupal, to decide which is the identifier of the form field that you want to modify.

  • hook_form_alter(), hook_form_FORM_ID_alter(), and hook_form_BASE_FORM_ID_alter() (introduced in Drupal 7) don't directly alter the HTML output produced from Drupal; they alter an array containing the values described in Form API Quickstart Guide, Form API Reference (for Drupal 7, there are Form generation and Form API Reference).
  • The form you are trying to alter could contain a form field that is contained in another form field; this normally happens with form fields that are part of a field set. The structure of the form array used by the form API is difficult to interpret basing on the HTML output.

What you would need to do is to

  • find out the module that creates the form field you are trying to alter
  • find out the form building function that generates the form containing that form field
  • read the array containing the description of the form field you need to alter

Once you have done it, you can create the implementation of the hook that will allow you to alter that form field.

If the form builder function is, for example, path_admin_form() and your module is mymodule.module, then you can implement mymodule_form_path_admin_form(&$form, &$form_state).

|improve this answer|||||
1

First you want to look for the form in HTML of the loaded page.

<form class="node-form node-article-form" enctype="multipart/form-data" action="/cruzr/node/226/edit?destination=admin/workbench" method="post" id="article-node-form" accept-charset="UTF-8"><div><div class="form-item form-type-textfield form-item-title">

</form>

Here the ID is 'article-node-form'.

Then you want to use the HOOK_form_FORM_ID_alter() callback function.

|improve this answer|||||
0

1 For a quick answer I'd use the html. The form tag tells you

<form action="/yhivebook/class/917/1503856800?XDEBUG_SESSION_START=10676" method="post" id="yhivebook-booking-form"

2 In hook_form_alter the 3rd parameter is the form_id

function views_megarow_form_alter(&$form, &$form_state, $form_id) {

3 Any function with $form_state has it in

$form_state['build_info']['form_id']

Point your debugger there.

For example, submitting the form with the form id will work.

drupal_form_submit($form_state['build_info']['form_id'], $form_state);
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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