Want to get Lullabot article, videocast, and podcast announcements delivered right to your in-box?
Let us know your email address (we won't share it) and we'll let you know when anything exciting happens.
Modifying Forms in Drupal 5 and 6
Drupal has a lot of forms to fill out and not all of them may be just the way you want or need them to be. Modifying forms is a topic that is often met with groans but once you understand the two methods to accomplish the task and the basic, underlying concepts, it really isn't that hard to do at all. You'll be a form-modifying, input-customizing wiz in no time. This article will briefly discuss what's going on and then mainly focus on showing working examples for both methods in Drupal 5 and 6. You should be comfortable creating a new function, looking at arrays and a having at least a passing understanding of the Forms API is real handy. Also note that in the examples below I have them wrapped in php tags but you should not include those if you copy/paste. That is just so it looks nice and clear for the article.
Deciding to make the change in the theme or a module
So there are two methods for altering form output in Drupal, one at the theme layer and the other through a custom module. Changes to the HTML can be accomplished with either method so most people will use the method they are more comfortable with already; themers use the theme and developers use a module. There are two situations however where you will want to use a module rather than a theme:
- Changing functionality of a form (e.g. adding new validation rules or submission actions) can only happen in a module.
- Form elements can be completely removed from the HTML in the theme layer but from an access point of view, someone could still theoretically make use of the field in the form's $_POST because the field is not removed from the form process, only the HTML output is removed. Removing an element in a module can completely remove access to it in any way. This is not often a real problem so removing elements in the theme layer is still acceptable but you should be aware of the distinction.
An example form: User edit
We will not be looking at functional changes here so I'm going to take an example that works well in either method and you can choose the one you prefer. The code is actually quite similar and both rely on two important things: 1) the form's ID and 2) some knowledge of Drupal's Form API.
Our example is altering the form as seen at My Account > Edit in a very simple way to change the name of the Username field from "Username" to say "Login ID" instead.
Find the form ID
All forms in Drupal have a unique ID. You can easily find the form ID in the HTML source code. On your site view the source of the page (Firebug is very handy for this) and look for some hidden fields near the top of the form. One has token stuff in it and another will have the name="form_id". You want to use the value of that form_id input field. In this example it looks something like this (in D5):
<input id="edit-user-edit" type="hidden" value="user_edit" name="form_id"/>The value for our form ID in this case is "user_edit". In Drupal 6 the form ID is "user_profile_form".
[Note that if you find the form element, e.g. <form id="user-edit" enctype=...) at the top of the form, you will see that is has a very similar id property (in this case "user-edit"). The thing to be aware of is that the form id property uses a hyphen (-) and the form_id that you need for your work has to use an underscore (_).]
Creating your override functions
Now let's start creating the function we will need to hook into the form. Of course, naming and placing the function is slightly different for themes and modules. In all of these examples replace themename and modulename as appropriate. Here is the starting code:
Option 1: Override the theme function
In the theme layer place your function in your theme's template.php file. You will create a new function for each form you wish to modify.
D5 theme override
<?php
/**
* Theme override for user edit form.
*
* The function is named themename_formid.
*/
function themename_user_edit($form) {
// Our kickin' mods go here.
}
?>D6 theme override
In D6 theming this gets interesting. Many forms in D6 now have template files or "registered" functions. For those you can simply edit the .tpl file or override the function as in D5, respectively. For forms that do not have templates or registered functions though, we need to not only create the override function but we also need to register it with the theme system so it knows about it. For more information on this see the handbook page about using the theme registry for special cases. Our user edit form is one such beast. Once you add the following functions to your template.php, reset the the theme registry by clearing cached data on the Administer > Performance page.
Here is the theme registry function we need:
<?php
/**
* Implementation of hook_theme.
*
* Register custom theme functions.
*/
function themename_theme() {
return array(
// The form ID.
'user_profile_form' => array(
// Forms always take the form argument.
'arguments' => array('form' => NULL),
),
);
}
?>And here is the override function; very much like the D5 version except the form ID.
<?php
/**
* Theme override for user edit form.
*
* The function is named themename_formid.
*/
function themename_user_profile_form($form) {
// Our kickin' mods go here.
}
?>Option 2: Use hook_form_alter() in a module
D5 hook_form_alter()
If using a module, place the hook_form_alter function (D5 and D6) in your .module file. You will use this one function to change as many forms as you want, using the form ID in a switch statement for each one.
<?php
/**
* Implementation of hook_form_alter().
*
* The function is named modulename_form_alter.
*/
function modulename_form_alter($form_id, &$form) {
// Normally a switch is used because you may want to alter more than
// one form and it is easy to add a new case for each form.
switch ($form_id) {
// This is our form ID.
case 'user_edit':
// Our kickin' mods go here.
break;
}
?>D6 hook_form_alter()
<?php
/**
* Implementation of hook_form_alter().
*
* The function is named modulename_form_alter.
*/
function modulename_form_alter(&$form, $form_state, $form_id) {
// Normally a switch is used because you may want to alter more than
// one form and it is easy to add a new case for each form.
switch ($form_id) {
// This is our form ID.
case 'user_profile_form':
// Our kickin' mods go here.
break;
}
?>Viewing the $form array
Once you have gotten the form ID and created the function you will need to see the existing form elements you have to work with. If you have Devel module enabled, you can use the shorthand dsm() function to pretty print the $form array. Otherwise a regular PHP print_r() or var_dump() will work fine. Whichever function you use to see the array, place it in your function where the code above says "// Our kickin' mods go here." For example:
<?php
function themename_user_edit($form) {
return print_r($form);
}
?>When you reload the page with the form on it now you should see a whole bunch of yummy array output. If not, make sure you got the form_id correct and that you have named your function properly.
Find the form element and property
There is quite a bit of documentation on FAPI and I'm not going to dive very deeply here. Here are the quickstart guides for D5 and D6. You may also want to have a handy bookmark to the form property reference, D5 and D6.
Basically we are going to look at the $form array, find what we want to change and translate that into FAPI for our function. Let's look at a section of the $form array that I am seeing on my site:
Array
(
[account] => Array
(
[#type] => fieldset
[#title] => Account information
[name] => Array
(
[#type] => textfield
[#title] => Username
[#weight] => 0
[#maxlength] => 60
[#description] => Your preferred username; punctuation is not allowed except for periods, hyphens, and underscores.
)
)
[pass] => Array
(
[#type] => password_confirm
// snip...
)
// snip...
[comment_settings] => Array
(
[#type] => fieldset
[#title] => Comment settings
[#collapsible] => 1
[#collapsed] =>
// snip...
)
)So basically we need to walk down the array to find the part we want to change. I want to change the title of the Username field. Looking at my array that means I want to target [account][name][#title]. Once I find that, I can just put that in my function and tell Drupal what I want to do with it. If you aren't sure what you can do to a given property, looking at the reference chart linked to above will help out.
$form['account']['name']['#title'] = t('Login ID');I can do this with any of the FAPI properties. For example I can set the default value of a fieldset to collapsed:
$form['comment_settings']['#collapsed'] = TRUE;Or I can even remove an element entirely using the unset function. This would remove the Signature text area from the form:
unset($form['comment_settings']);So, go have fun and get those rascally forms just the way you want them!
Full example functions
Here are the complete, commented example functions.
Theme override: D5
<?php
/**
* Theme override for user edit form.
*
* The function is named themename_formid.
*/
function themename_user_edit($form) {
$output = '';
// Print out the $form array to see all the elements we are working with.
//$output .= dsm($form);
// Once I know which part of the array I'm after we can change it.
// You can use the normal Form API structure to change things, like so:
// Change the Username field title to Login ID.
$form['account']['name']['#title'] = t('Login ID');
// Make sure you call a drupal_render() on the entire $form to make sure you
// still output all of the elements (particularly hidden ones needed
// for the form to function properly.)
$output .= drupal_render($form);
return $output;
}
?>Theme override: D6
Theme registry function:
<?php
/**
* Implementation of hook_theme.
*
* Register custom theme functions.
*/
function themename_theme() {
return array(
// The form ID.
'user_profile_form' => array(
// Forms always take the form argument.
'arguments' => array('form' => NULL),
),
);
}
?>Form override function:
<?php
/**
* Theme override for user edit form.
*
* The function is named themename_formid.
*/
function themename_user_profile_form($form) {
$output = '';
// Print out the $form array to see all the elements we are working with.
//$output .= dsm($form);
// Once I know which part of the array I'm after we can change it.
// You can use the normal Form API structure to change things, like so:
// Change the Username field title to Login ID.
$form['account']['name']['#title'] = t('Login ID');
// Make sure you call a drupal_render() on the entire $form to make sure you
// still output all of the elements (particularly hidden ones needed
// for the form to function properly.)
$output .= drupal_render($form);
return $output;
}
?>Module hook_form_alter(): D5
<?php
/**
* Implementation of hook_form_alter().
*
* This lets you make changes to any form in the site. You can alter, remove
* or add form elements. You can also alter the validation and submission
* behavior. The name will always be modulename_form_alter.
*/
function modulename_form_alter($form_id, &$form) {
// Normally a switch is used because you may want to alter more than
// one form and it is easy to add a new case for each form.
switch ($form_id) {
// This is our form ID.
case 'user_edit':
// Print out the $form array to see all the elements we are working with.
//$output .= dsm($form);
// Once I know which part of the array I'm after we can change it.
// Change the Username field title to Login ID.
$form['account']['name']['#title'] = t('Login ID');
break;
}
}
?>Module hook_form_alter(): D6
<?php
/**
* Implementation of hook_form_alter().
*
* This lets you make changes to any form in the site. You can alter, remove
* or add form elements. You can also alter the validation and submission
* behavior. The name will always be modulename_form_alter.
*/
function modulename_form_alter(&$form, $form_state, $form_id) {
// Normally a switch is used because you may want to alter more than
// one form and it is easy to add a new case for each form.
switch ($form_id) {
// This is our form ID.
case 'user_profile_form':
// Print out the $form array to see all the elements we are working with.
//$output .= dsm($form);
// Once I know which part of the array I'm after we can change it.
// Change the Username field title to Login ID.
$form['account']['name']['#title'] = t('Login ID');
break;
}
}
?>







Comments
Forms always confuse me.
I'll have to go over this line by line to understand it. Particularly the code section where they have such a strange way of representing forms.
Just the thing I was looking for!
I love it when an article falls out of the sky with perfect timing... thanks Addi!
Very valuable
Excellent post that helps us understand overriding forms and create custom forms.
Nice trick (or better to
Nice trick (or better to say: approach), thanks for sharing.
The missing piece to the puzzle!
Terrific! You're saving a lot of people agony, time and angst. Thanks for clarifying a woefully underdocumented yet crucial part of how Drupal works.
Awesome!
Great article! Couldn't have come at a better time too.
I needed to figure out how to substitute user profile fields in a user reference field rather than usernames (since I use LDAP for authentication), and this is a much simpler solution than I was considering.
Here's what I came up with:
<?phpfunction themename_node_form($form) {
$output = '';
foreach ($form['field_instructor_pref_first']['uids']['#options'] as $uid => $username) {
$form['field_instructor_pref_first']['uids']['#options'][$uid] = t('!first !last', array(
'!first' => user_load(array('uid' => $uid, 'status' => 1))->profile_firstname,
'!last' => user_load(array('uid' => $uid, 'status' => 1))->profile_lastname)
);
}
$output .= drupal_render($form);
return $output;
?>
Thanks again!
got a question.
this is a great tutorial. I want to customize my forum comment reply form.
<div class="box">
<h2 class="title">Reply</h2>
<div class="content">
<form action="/mom/comment/reply/5" method="post" id="comment-form">
I want to remove
Reply
, but this is not in the array. is there a way to remove it?
comment.tpl.php
That is coming from your comment.tpl.php file. So you can edit it there directly.
you cannot change it in
you cannot change it in comment.tpl.php file.
<div class="content"><?php print $content ?>
</div>
$content contains that code.
Urgh, sorry - box.tpl.php
Comments are printed inside boxes so you need to use box.tpl.php. Sorry about the misdirection there.
If your theme does not already have a box.tpl.php file you can override the default one by creating one for your theme, using the default one as a template. The default tpl (for D5) can be found at themes/engines/phptemplate/box.tpl.php. In D6 it is located at modules/system/box.tpl.php.
thank you addi
thank you so much. cannot believe I didnt figure out i should change box.tpl.php file.
Themer
I would like to point out to users that the 'themer' module provides body classes by role, path, locale, etc.
This is useful in the case of forms because if you need to hide the input format field for users of a certain role you can achieve this with this simple selector:
body.role-manager fieldset.input-format {
display: none;
}
etc, which is useful for un-cluttering portions of forms very quickly. Keep in mind that if you do not wish them to have access to these fields at all then this is not the way to go.
custom validation for user form
I'm trying to require a checkbox be checked on the user registration form in D6. In D5, I would have done something like:
<?phpfunction myModule_form_alter($form_id, &$form) {
if ($form_id == 'user_register' || $form_id == 'user_edit') {
$form['FormSection']['profile_myCheckbox']['#validate'] =
array('myModule_myCheckbox_validate' =>
array($form_id, $form));
}
}
?>
(sorry about the awkward wrappng.)
I can't seem to figure out the equivalent in D6....
#validate changed in D6
In D5 #validate could be used for both elements and the form itself. This was changed in D6 so that validating an element is now #element_validate and #validate is only used for the form-level validation. So you need to use #element_validate in your example for D6.
another newbie question, how to restyle forms?
I try to restyle comment reply form.
here's part of the code:
<div class="form-item">
<label>your name: </label>
<a href="/mom/user/1" title="View user profile.">feelexit</a>
</div>
right now, "your name" is one line, name input box is on another line, I want to make them one line. what I did right now is to put styles in style.css, make label display inline.
I want to know, if theres a way to change code to
<div class="form-item">
<span style="font-weight:normal;">your name: </span>
<a href="/mom/user/1" title="View user profile." style="text-decoration:underline;">feelexit</a>
</div>
I have the same question on
I have the same question on theming forms so that elements don't wrap lines but stay on the same line. Any suggestions?
render form in D5 with tiny etc
Hi All,
i am trying to render a from in Drupal 5 with all its attributes. My problem is i can render the form like drupal_render($form['group_index']['field_awards'][0]['value'] but this dosn´t give me the tinyMCE wtih the form if i try do go like drupal_render($form['group_index']['field_awards'][0]['value']['#process']['tiny_etcect'] nothing will happen.
Does anyboddy has an suggestion for me?
Dirk
Adding new fields and validating them
Thanks for the article!
How about adding new fields and validating them? Any instructions or articles on that?
Maybe a part 2
Sounds like that would be a good follow up article. I'll see what I can do.
I second that I idea
I'd do a tutorial how to add additional fields to forms, validate them and add save them to the db.
profile form field hidden on edit page
First, thank for the great writeup!
I would like to create a textfield in which I can assign (type) different titles to users. That field should be hidden from users when they click 'edit' on their profile (but I, or the user admin, can still see and edit it there) and visible to everyone on the user profile view page.
I was thinking of finding the form field name within the form with the user-edit id and setting that field to hidden (except for the admins). Can I do that in the form attributes?
If not, what would you suggest?
Thanks!
Yes
You can set any FormAPI property. So you can put an if statement around the change in your modification function and set the element's '#type' => 'hidden'.
So, in user-edit (within a
So, in user-edit (within a custom module) I just put:
$form['Personal Information']['profile_year']['#type']='hidden';and it works, i.e. the year is displayed only on the profile view page and not on the profile edit page.
A quick question: When would I use '=>'and when '=' when assigning form properties?
Could you direct me to a link where I could read more about this?
Thanks and thanks for the great article!
=> is for use inside an array
so if you were setting an element with an array you use =>.
<?php
$form['foo'] = array(
'#type' => 'hidden',
'#title' => t('My foo thing'),
);
?>
The = is for straight assignment of a single property in the array.
<?php$form['foo']['#type'] = 'hidden';
?>
Hide the password fields for LDAP-auth sites
This is an excellent article. I've been having fun tweaking a module to edit for fields. Here's the best application of this technique I've found so far:
We authenticate users by LDAP (w/ LDAP Integration module). So I don't want users going to their user//edit form, filling out a password field, and then calling the helpdesk when they can't log in with their "changed" password. Solution:
function ulaw_utils_form_alter($form_id, &$form) {switch ($form_id) {
case 'user_edit':
// hide the password thingy, we're using LDAP! (except for admin)
if ($GLOBALS['user']->uid != 1) {
$form['account']['pass'] = array(
'#title' => 'Password',
'#type' => 'item',
'#description' => t('To change your password for this site, you must '.
l('change your LDAP password.', 'https://ldap/password/form/url'),
);
}
break;
}
}
This will save us a lot of user education. (for various reasons, I can't use the password-changing feature of LDAP integration, which would be the simpler solution!)
Posting form modification from 'View' page via Ajax?
First tnx, for great explanation.
Ok then. I've got a form on a user profile page (I made a new content type with nodeprofile module and added CCk field) 'View' tab witch I want to modify with custom ajax defined in node-myContentType.tpl.php page witch I've overriden.
Now the problem is that not only I need to modify data, I also had to read new data from response. Any suggestion? Or should I make custom queries from $node object info.? So my problem is, what fns or. query to call? Collecting data and sending them via ajax isn't problem here.
IDEA(in steps):
1.(client)send modifiedValue- (server?)oldData + modifiedValue = Sum (write that to database)
- (server?)echo Sum
2.(client)Update current Sum field
client --> current page (e.g. JavaScript in it)
server --> page I'm sending request to.This is problematic.I don't know where?
Oh.I need custom JS because I'll refresh few other parts on this page based on response value.
Any hint would be grea, tnx.
p.s.I'm only month with Drupal, so bear with me plz ;)
Ok, I'll do a module ;)
You said in beggining that one can only modify data in module. I think it's getting clearer to me. I'll make a kind of helper module for this. It should work I think.
I'm watching http://drupaldojo.com/node/73 lesson now on using jQuery and I'll work something out with that. ;)
Again, tnx for great article.
Always provide the right
Always provide the right answers!
Love the lullabot! :)
Thanks for a great article
This was excactly what i needed, very easy to follow
More on the theme override approach (with template file)
How to theme a Drupal 5 form with a template file goes over a rather robust approach we used at Agaric. For instance, it works for the combined user registration form generated by the Bio module.
Does this hold true for comment forms?
Hi,
Great tutorial. However, is this for non-comment forms? I can't seem to use the above tutorials to customise my comment form.
I've tried using hook_comment in my module file but if I put:
<?phpreturn print_r($form);
?>
after
<?phpcase 'form':
?>
part it seems to gibber... any ideas?
Wrong code
You aren't following this tutorial - hook_comment is an entirely different thing that what this tutorial is covering.
bit harsh?
I was following the tutorial actually. I've tried using hook_form_alter to change the comment form, and I got the same result.
There is no 'name' like the other forms for the comment form.
If comment forms can't be modified using this tutorial it might help to make that clear because I couldn't find that information anywhere.
Sorry if this isn't all immediately obvious, but I'm still learning here - that's why I'm using tutorials!
I didn't intend to be harsh
I didn't intend to be harsh at all, but just wanted to point out that hook_comment is a totally different thing that what this tutorial covered so I wasn't sure how that applied to this. When I look at the comment form HTML I can see the ID is comment_form. Remember that you are looking for the "value" of the input that is named "form_id", not the "name." The following code gives me the form array for the comment form in D5:
<?phpfunction modulename_form_alter($form_id, $form) {
switch ($form_id) {
case 'comment_form':
print_r($form);
break;
}
}
?>
Thanks
Cheers for that, great help.
I'm trying to use this
I'm trying to use this approach to modify the admin settings form for the Nice Menus module to allow an arbitrary number of menus instead of the 10 that are hardcoded into the module. I'm using hook_form_alter to modify the nice_menus_admin_settings form. The problem I'm having is that I'm unable to modify the form for some reason. I know I've identified the form properly because if I do a print_r($form), the form array is printed out.
Here's what I have:
/**
* Implementation of hook_form_alter()
*
* Modify the admin settings for nice_menus module to allow
* an arbitrary number of menu blocks
*/
function cwl_form_alter($form_id, &$form) {
switch ($form_id) {
case 'nice_menus_admin_settings':
$form['nice_menus_number']['#type'] = 'textfield';
break;
}
}
?>
So what I'm trying to do is change the select list to a text field. However, this has no effect. I've also tried just replacing the whole array for this field:
/**
* Implementation of hook_form_alter()
*
* Modify the admin settings for nice_menus module to allow
* an arbitrary number of menu blocks
*/
function cwl_form_alter($form_id, &$form) {
switch ($form_id) {
case 'nice_menus_admin_settings':
$form['nice_menus_number'] = array(
'#type' => 'textfield',
'#title' => t('Number of Nice Menus'),
'#description' => t('The total number of independent nice menus (blocks) you want.'),
'#default_value' => variable_get('nice_menus_number', '2'),
);
}
}
?>
Is that doable? Is there something obvious I'm missing?
Thanks.
Module weight
This is one of those weird gotchas. Your module is running before Nice Menus because by default they run in alphabetical order. You can change the weight of your module to 1 to make it run after NM and then it should fire correctly. This is in the system table, weight column.
Also, this feature is actually part of the D6 version of Nice menus and could easily be backported to Drupal 5. If you make a patch, I'd be willing to commit it. ;-)
Modifying Drupal Search
I am on the low edge of the curve with hooks and modifying Drupal with functions, and your explanation demystifies a lot. Thanks...
I am modifying a form which is already registered (in Drupal 6), the Theme Search Form (just trying to alter/remove the label), so it works a little differently. Following your instructions, it ends up printing the form twice, the original version and the modified one. Then when I create a search-theme-form.tpl, I seem to fall short on the correct syntax to use there.
This is the array in the core search module that I am trying to modify:
$form[$form_id] = array(
'#title' => t(''),
'#type' => 'textfield',
'#size' => 15,
'#default_value' => '',
'#attributes' => array('title' => t('Enter the terms you wish to search for.')),
);
This should be really simple but for some reason I keep falling short. Can anyone point me to the best way to do this, ... or any way. ;) thanks
module do nothing..
hi all..
i have some working personal module, but the "e_reg_form_alter" doo nothing..
i try this:
<?phpfunction eaposztrof_signup_form_alter($form_id, $form) {
switch ($form_id) {
case 'user-register':
print_r($form);
break;
}
}
?>
the module name and filenames is "e_reg" too.. and the drupal is the newest 6.2..
any ideea?
sorry..
the correct code from the enabled module is:
<?phpfunction e_reg_form_alter($form_id, $form) {
switch ($form_id) {
case 'user-register':
print_r($form);
break;
}
}
?>
why not working?
Different parameters
Hey there,
The parameters changed in D6 so make sure you are using the right version of the code. What you have there is for D5. The parameters in D6 are
&$form, $form_state, $form_id.This is very helpful, just one question
I agree, this is an extremely helpful tutorial, thank you for writing it. I'm wondering if there's a way in D6 to do the override, but keep the .tpl.php file in the loop. Like the tutorial, if I want to change a form field's label, I know I can do :
function phptemplate_search_block_form($form) {$output = '';
$form['search_block_form']['#title'] = t('Some new title');
$form['submit']['#value'] = t('Some new button value');
$output .= drupal_render($form);
return $output;
}
But any other markup in the .tpl.php file is ignored. So, am I understanding this right that if you do the override function in a theme's template, you effectively take the .tpl.php file completely out of the loop? I was hoping I could just modify the values somewhere in the stack, but keep .tpl.php for rendering. Maybe a preprocess function or something?
This is appreciated - thanks
Forum topics don't really need teaser's on my site. This article was really helpful in removing the Teaser field when submitting new topics. Thanks.
Upon checking the box profile field becomes uneditable
First, thanks for the great writeup!
I used your code to do the following: Using profile module I created a 'verified user' (profile_verify) checkbox field which is visible only to admins/themes. I want that, upon checking the box (by admin), the email field becomes uneditable.
I got it to work, and all is fine but I just want to be sure that what I did is valid and makes sense (in terms of code)
<?phpfunction formxyz_form_alter($form_id, &$form) {
global $user;
switch ($form_id) {
case 'user_edit':
if ($form['_account']['#value']->profile_verify=='1') {
$form['account']['mail']['#attributes']=array('readonly' => 'readonly');
}
break;
}
}
?>
again, it works fine, but is that the way to go?
thanks!
#access
I'm curious why you'd use unset to remove an element rather than set #access to FALSE (http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...).
Wow, thanks so much for this
Wow, thanks so much for this article! I learnt a lot today.
Here's what I needed to do:
On our site, both anonymous and registered users are allowed to create nodes. We allow them to provide multiple authors for content, so that if a report was made by several people, they can all get proper credit for it.
Anonymous users can fill in their name in a CCK text field; registered users fill in a nodereference field. Both of these fields are required. Hiding one or the other field from one or the other user role is done with cck_field_permissions.
The problem: when admins (who have access to the text field as well as the nodereference field) want to edit a node, they got a validation error, because both fields are required, and one of them is often empty.
Solution: a module that un-requires both fields for admin roles.
<?phpfunction modulename_form_alter($form_id, &$form) {
switch ($form_id) {
case 'article_node_form':
global $user;
$allowed = array('admin','edito');
foreach($user->roles as $role) {
if (in_array($role, $allowed)) {
$form['field_author_reg']['0']['user_name']['#required'] = 0;
$form['field_author_anon']['0']['value']['#required'] = 0;
}
}
break;
}
}
?>
field title change not reflected in preview and view of form
Hi,
I am trying to over-ride the comments form for our drupal 5.8 site. I need to change "Subject" to "Re". I can do this using hook_form_alter:
function hook_form_alter($form_id, &$form) {
switch ($form_id) {
case 'comment_form' :
$node = node_load($form['nid']['#value']);
$subject = $node->title;
$form['subject']['#title'] = "Re";
$form['#submit']['external_page_comment_form_submit'] = array($subject);
$form['#submit'] = array_reverse($form['#submit']);
return $form;
}
}
The problem is that the change doesn't seem to carry over to previewing or posting the comment. The subject label reverts back to "Subject".
I think that I also have to change the subject label in hook_comment but I am not sure how to do this. Can I use the same form api syntax as in hook_form_alter?
Here is what I have in my hook_comment:
function hook_comment(&$comment, $op) {
switch ($op) {
case 'view':
if (variable_get('vote_up_down_widget_comment', 1)) {
//print_r($comment);
$comment->comment = $comment->comment ."". theme("external_page_points_alt", $comment->cid, 'comment') ."";
$comment->comment = $comment->comment . theme("external_page_widget_alt", $comment->cid, 'comment');
}
break;
}
}
I am using vote-up-down and have been able to insert the point info at the bottom of comments, before the comment $links.
I can't seem to figure out how to get at the stuff at the beginning of comments, it's all lumped in $comment->comment.
Thanks for this article and thanks to anyone who can point me to more examples of bending comment forms to my will :-)
Excellent!
Thank's a lot for this tutorial! It's just excellent - and unique!
Do you know if there is a chance to access $node contents within a theme function (option 1)?
What I'm trying to do is to modify the form which is used to add a comment. If I am in a special forum, I want to have a special layout of this form.
So I am overriding the comment reply form (comment_form) which works fine. I just have to check if the user is adding a comment to a topic in that specific forum. Just: how to find out about this? The easiest way is to check the taxonomy term of the parent article. And therefore, access to $node would be nice :-)
Thanks, Gerald
Fantastic!
After sifting through so much confusing Drupal documentation, this article is a real breath of fresh air. Thank you for your thoroughness!
Get the right ID!
Hello.
This is an awesome tutorial - thanks.
Just to clarify something which fooled me for a while. You appear to suggest that using the id attribute from a tag like
<form action="/node/61/edit" accept-charset="UTF-8" method="post" id="node-form" enctype="multipart/form-data">is possible, as long as one turns the '-' into a '_'. This is not true (and may not be what you meant to imply). The correct id we require is found in a tag like
<input type="hidden" name="form_id" id="edit-modulename-node-form" value="modulename_node_form" />(in this case, the id is modulename_node_form).
If I spent half an hour trying to work my mistake out, I am sure others will appreciate this being cleared up too.
Apart from that, thanks again for this fantastic tutorial.
Trouble with weight
I don't know if I'm doing something wrong, or if I need to submit a bug report on this one. Figured I'd start here since this is where I got the info...
function fblike_theme() {return array(
'node_form' => array(
'arguments' => array('form' => NULL),
),
);
}
function fblike_node_form($form) {
if (arg(2) == 'profile') {
$form['field_first_name']['0']['value']['#size'] = 25;
$form['title']['#size'] = 25;
$form['field_age']['value']['#description'] = 'testf';
$output .= drupal_render($form); }else{
$output .= drupal_render($form);
}
return $output;
}
So that's just some test to see how everything was working, and it worked fine. However, the weight (now operated by the jquery drag and drop) gets all messed up. The form submit, preview, and menu options appear at the top of the node regardless of changes to the "manage fields" and clearing all cache.
Is this incompatible? Suppose to happen? Do I need to define the weight? Anyone having the same problem?
Thanks! - besides this error, the tutorial helped a ton.
More Info
So, if I define the weight it works fine. Who knows that the problem is, but defining the weight will work fine for me. I'm still sure there must be a way to retain the weight as defined in the manage fields tab.
How to find a particular form..
Actually I want to modify "Body" field Blog edit form. I want to try out Google API to translate the content of blog written in English to Chinese on this page.
I took it's source and found
So as per the your article, my form will be "blog_node_form". I tried to find it, but didn't get any where in Drupal package.
I am new (just 2 days on Drupal) to Drupal. May I know how I can find this form and modify it?
Thanks in advance,
Post new comment