Community Documentation

Theming CCK input form for CCK2 & CCK3

Last updated December 30, 2011. Created by drupal-id.com on October 11, 2009.
Log in to edit this page.

This tutorial will show you how to customize a CCK2 & CCK3 Form such as rename CCK button, hide a CCK field, remove CCK field, hide field-set, disable CCK field, etc. You can also design you own form layout. Change CCK form title.

This is a real customize CCK form that I deliver to one of my client (thanks to PT MHS that allow me to post their Consignment-Note form):

To theming CCK Input you just need:

  1. Edit template.php
  2. Create node-content_type-edit.tpl.php
  3. Clear Cache Data before view your result: Administer-Site Building-Performance: Clear Cache Data

EXAMPLE

Suppose your content-type is: "account_registration" and you theme is "bluemarine"

  1. Edit template.php (or create a new one), add this code:
    <?php

    function bluemarine_theme($existing, $type, $theme, $path) {
      return array(
       
    'account_registration_node_form' => array(
           
    'arguments' => array('form' => NULL),
           
    'template' => 'node-account_registration-edit'
       
    )
      );
    }

    ?>

  2. Create node-account_registration-edit.tpl.php

    //To REMOVE Title field
    <?php unset($form['title']); ?>

    <fieldset class=" collapsible">
        <legend>Company Data</legend>
        <?php
         
    //NOTE: if you don't have Field Group then simply type:
          // print drupal_render($form['field_accreg_company_name']['0']['value']);
         
    print drupal_render($form['group_company']['field_company']['0']['value']);
          print
    drupal_render($form['group_company']['field_street']['0']['value']);
       
    ?>

    </fieldset>  
    <?php
     
    print drupal_render($form);

     
    //Enable below to show all Array Variables of Form

      //print '<pre>';
      //print_r($form);
      //print '</pre>';
    ?>

HOW TO ...........

  1. RENDER ONLY 1 FIELD
    <?php print drupal_render($form['group_company']['field_street']['0']['value']); ?>

  2. RENDER A GROUP OF FIELDS
    You don't need to render fields in group one by one, just enter this code to render all fields in a group:
    <?php print drupal_render($form['group_company']); ?>

  3. RENDER A SELECT LIST
    Almost same like render a TEXTFIELD, but avoid ['0']['value'] at the end
    <?php print drupal_render($form['group_company']['field_region']); ?>

  4. RENDER A FILEFIELD
    Contributed by HEY_GERMANO
    <?php print drupal_render($form['field_video_file']); ?>

  5. REMOVE AN INPUT FIELD
    You may want to remove an input field, this example will remove TITLE-FIELD of a form:
    <?php unset($form['title']); ?>

  6. HIDE AN INPUT FIELD (HIDE vs REMOVE!)
    You may still want to enable an input form but need to prevent it:
    <?php $form['title']['#access'] = FALSE; ?>

  7. HIDE A TITLE/LABEL OF FIELD
    Some tutorials say:
    <?php unset($form['field_test']['#title']); ?>

    Above code only remove '#title' from array elements, but not remove the title/label.

    To hide title/label from a field:

    <?php unset($form['field_test']['value']['#title']); ?>

  8. SHOW ALL VARIABLES OF FORM
    You may want to know what variables available for you:
    <?php print_r($form); ?>

    or for better look (but very long output):

    <?php
     
    print "<pre>";
     
    print_r($form);
      print
    "</pre>";
    ?>

  9. REORDER
    Use ['#weight'] to reorder
    $form['buttons']['#weight'] = -50; // buttons at the top

  10. PRINT BUTTONS
    <?php print drupal_render($form['buttons']); ?>

  11. RENAMING BUTTON
    What is "Submit"? You may need to write it as "Save now!", don't you?
    $form['buttons']['submit']['#value'] = 'Save to Database';

  12. HIDE BUTTON
    $form['buttons']['submit']['#access']= FALSE; //Hide Submit
    $form['buttons']['preview']['#access']= FALSE; //Hide Preview

  13. HIDE GROUP FIELD-SET
    $form['group_general']['#access'] = FALSE;

  14. DISABLE INPUT FIELD
    $form['field_your_field_name']['#attributes']['disabled'] ='disabled';

    Unfortunately, above code doesn't work for DISABLE INPUT FIELD! But here are the solutions: http://drupal.org/node/357328 and http://drupal.org/node/300705

  15. CHANGE FORM TITLE
    When you add a new CCK form, you will see "Create page". How to change it to "Make a new data"? Use this code:
    drupal_set_title('Make a new data');

  16. THEMING DRUPAL DEFAULT REGISTRATION, USER & PASSWORD FORMS
    function bluemarine_theme($existing, $type, $theme, $path) {
      return array(
        'user_register'    => array('arguments' => array('form' => NULL), 'template' => 'user-register-edit'),
        'user_login'       => array('arguments' => array('form' => NULL), 'template' => 'user-login-edit'),
        'user_pass'        => array('arguments' => array('form' => NULL), 'template' => 'user-pass-edit'),
      );
    }

SEPARATE FORM LABEL AND INPUT

Usually in custom form you want to make an input form in a table format, mean you need to separate the FORM LABEL and FORM INPUT, look at this sample:

<table>
<tr><td>
  Label is: <?php print $form['field_sample1']['#title']; ?>
</td></tr>

<tr><td>
  <?php unset($form['field_sample1']['0']['value']['#title']); ?>
  <?php print drupal_render($form['field_sample1']['0']['value']); ?>
</td></tr>
</table>

Author: www.drupal-id.com

AttachmentSize
cck_form_sample.jpg112.38 KB
cck_separate_label.jpg17.91 KB

Comments

Adding multiple content edit pages

This helped me tremendously. To most people I'm sure this was obvious, but it took me a bit. If you have multiple content type edit pages you want to theme, here's the template.php code

<?php
function YOURTHEME_theme($existing, $type, $theme, $path) {

return array(
   
'type1_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-type1-edit'
   
),
   
'type2_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-type2-edit'
   
),
   
'type3_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-type3-edit'
   
)
  );
 
?>

It was the commas after each array that held me up. Hope this helps someone else.

Not able to redirect

Thanks for this information. I have been able to resolve all my requirements save one - redirecting to another page. Here's my code (in node-content_type-edit.tpl.php):

<?php
$form
['buttons']['submit']['#value'] = 'Done';
$form['buttons']['preview']['#access']= FALSE;
$form['#redirect'] = '/node/add/attendance';
print
drupal_render($form);
?>

While the first 2 lines do take effect, the redirection does not get done. What I am trying to do is - after one node is added, allow user to go to adding next node. Currently it shows me a confirmation that node is created and goes to the created node page.

Please help!

Thanks.

SB

Function drupal_goto()

You can use drupal_goto(), e.g.: drupal_goto("node/add/attendance", NULL, NULL, 301); put this code in nodeapi hook (http://api.drupal.org/api/function/hook_nodeapi/6).

Conditional text fields are not working.

Hello. Thanks for this HowTo. I have found it very useful.
I ran into one small problem, and I was wondering if anyone else has had this problem or if there is a solution to it. After using these instructions to theme my form i noticed that some of my conditional fields were not working. I have a couple nested fieldsets that contain radio buttons, an on/off check box, and a text field. The check box controls the radio buttons. A radio button then controls the text field. For some reason, the text field always appears on the form and acts as if it is not a conditional field. However, the radio buttons function as expected. I have also tested this form using the check box as the controller of the text field, but it still ALWAYS appears on the form. I have also tested this by having all of the controlling and controlled fields in the same fieldset.

Any help is greatly appreciated.

Thanks,
MT

I changed the rendering of my text field from...

<?php
print drupal_render($form['field_bpo']['0']['value']);
?>

to...

<?php
print drupal_render($form['field_bpo']);
?>

and it now works fine.

Fields not appearing

solved

No preprocess required?

Is no preprocess required? Or is that a nice-to-have/do?

500 - Internal Server Error

I keep getting an '500 - Internal Server Error' whenever I add the code into my template.php file. My code is below. Can anyone see what is wrong?

<?php
function check_in_theme($existing, $type, $theme, $path) {
  return array(
   
'check_in_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-check_in-edit'
   
)
  );
}
?>

Name of the theme

Is your theme named check_in?

Thanks for the writeup, very helpful

I have another question though.
Do I need to create seperate theme files for add and edit (and add more arrays in the template.php function)? I.E. node-nodename-edit.tpl.php and node-nodename-add.tpl.php or are they essentially the same page?

Just create an "edit form"

Just create an "edit form" for both "add" and "edit" task. You only need 1 tpl.php file.

Great write up, but have follow up

I have been bashing my head around this for a bit now and haven't been able to figure it out (plus it would make a good addition to this post!).
I can't display multiple inputs on the same line i.e. city: ________ state: ___ zip:_____
Tried:
div style="display: inline;margin-left:0;padding-left:0;" fieldset
[code]

<?php

        $form
['title']['#size'] = 20;
       
$form['field_datasource_organization'][0]['value']['#size'] = 20;
       
$form['body_field']['format']['#access'] = false;
       
$form['body_field']['teaser_include']['#access'] = false;
        print
drupal_render($form['title']);
        print
drupal_render($form['field_datasource_organization']);

        print
drupal_render($form['body_field']);

        print
drupal_render($form['field_contact_name']);
        print
drupal_render($form['field_contact_title']);
        print
drupal_render($form['field_contact_address1']);
        print
drupal_render($form['field_contact_address2']);
        print
drupal_render($form['field_contact_city']);
        print
drupal_render($form['field_contact_state']);
        print
drupal_render($form['field_contact_zip']);
       
//print drupal_render($form);
   
?>
[/code]
/fieldset /div
Note that all of that is wrapped in a div with display: inline; style applied. Anyone have any suggestions on how to correct this or achieve the effect? (Note: Couldn't figure out how to display html with out it being taken out, hence the broken html tags, I think it gets the point across though)

style not applied to fields

@richard,

Did you ever solve this problem? It looks to me like the style elements are applied to the div, not the individual fields. Think of the div as a black box. What's inside it doesn't matter in this case. The style elements (display, margin, and padding) are going to be applied to the box, not the contents. You won't get the individual components of the contents falling inline, each with the given margin and padding.

To style the contents of that div, assign style elements to the fields via a separate style sheet instead. Something like
div.contact-info div.field {margin: 0px;}
which says, "give any div with a class=field that falls within a div with an assigned class name=contact-info a margin of zero px."

You do want that extra div around the fields that you want to fall inline so that you can isolate them from other fields that shouldn't be inline

Good luck!

Separate Form Label and Input

I have added a new sub-title "SEPARATE FORM LABEL AND INPUT" including a sample image. Of course, according to mastoll comment above, you still need combination of tpl.php and CSS.

File Field Uploader breaks

Thank you for the helpful instructions. I used the RENDER A GROUP OF FIELDS option in a template override. This implementation worked correctly for all the fields - except the File Field. Here the interface Uploader fails during the upload process. It appears to make it halfway through the progress bar and fails with the message "An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (XX MB) that this server supports" The file size is very small and cannot be the cause of this problem. Also testing without the override demonstrated proper functionality. I have no error entry on the server logs during the failed upload. Is there an issue with improper paths when trying to write the file to the directory because the override XXX.tpl.php is not stored in the top level themes directory. I am using a template stored in the "sites/all/themes/template-name" not in directory "themes/template-name". I have tried moving the template to the top theme directory "themes/template-name and still receive the same error. Has anyone else seen this issue?

Thank you in advance

Drupal 6.19
Dev environment
Devel = off

Joel Mellon
eCreative Innovations in Web and Print Media
ECI Resources Corp
http://eciresources.com

Solution for you if you've not yet found it

At the end of your .tpl file, you need to add a the line:
print drupal_render($form);
If you've already printed all of the fields you are interested in seeing, and set #access to FALSE for everything else, then visually, this will have no effect - functionally however it has an impact.
I found this answer here, though it doesn't exactly shed much more light on the topic - http://drupal.org/node/647868#comment-2332596

hth,
D.

No Error messages displayed

If there are required fields which are not filled in by the user, the error messages and the red borders of those fields are not displayed.

Is it possible to change that?

More detail please ...

I'm not fully understand your question. If u mean How to set a field as "required" field for condition A but "not required" for condition B then you must remove "Required" option in this content-type. Then ... using nodeapi hook (http://api.drupal.org/api/function/hook_nodeapi/6) with $op='validate' to validated "required" field based on your custom conditions.

It won't publish/submit , it refreshes . [URGENT]

I have followed all steps but for some reasons my form just refreshes instead of submiting and redirecting to created node. Please help here is the code

<?php
//added lines in the template.php
function magazeen_theme($existing, $type, $theme, $path) {
  return array(
   
'sweepstake_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-sweepstake-edit'
   
)
  );
}
?>

the form

<?php
    $form
['buttons']['submit']['#value'] = 'Submit Sweepstake';
    
$form['buttons']['preview']['#access']= FALSE;
    
    
//print drupal_render($form);
   
   
print drupal_render($form['buttons']);
?>

?>

there are other input forms textfields,select lists and cck_other_select/cck_other_textfield

PLEASE HELP!!

Ending with drupal_render($form)

Ending with drupal_render($form) as shown below:

<?php
  $form
['buttons']['submit']['#value'] = 'Submit Sweepstake';
 
$form['buttons']['preview']['#access']= FALSE;

  print
drupal_render($form['buttons']);
  print
drupal_render($form);
?>

What a great tutorial, thanks

What a great tutorial, thanks a lot of writing it so well and making so easy to follow. I did run into a problem though, which doesn't seem to make sense when you look at the comments.
When I create a new node with this content type, it uses the template file.
When I edit an existing node of the same content type, it reverts to the origonal template file and doesn't use the override.
Can anyone think of a reason for this? And how to fix it.

EDIT: ok, i'm an idiot, it does work, I just was looking in the wrong place...well sort of. What a great article.

CCK computed fields

Was wondering if there was anyone out there that had an example of displaying a CCK computed field on the edit form? I don't need to edit it - just display the result.

CCK Computed Field

Try this:

<?php
print drupal_render($form['field_yourcomputedname']['0']['value']);
?>

Above code not yet tested, if it doesn't work you can try to see what is the right variable ... see "SHOW ALL VARIABLES OF FORM"

How would I move a form-item using CSS?

This really helped me out so far, but I had a question that I hope one can answer.

I'm building a content type where I'm using a mix of php and css to get the theme I want. What I'm trying to achieve is using css to move an entire field (the label, and options...)
The div class for the entire field is called 'form-item'. here is a snippet of the html generated.

<div class="form-item">
<label>Type of administration: </label>
<div class="form-checkboxes"><div id="edit-field-sh-ac-typeadministrati-value-1-wrapper" class="form-item">
<label for="edit-field-sh-ac-typeadministrati-value-1" class="option"><input type="checkbox" class="form-checkbox" value="1" id="edit-field-sh-ac-typeadministrati-value-1" name="field_sh_ac_typeadministrati[value][1]"> High-level</label>
</div>

I've looked at dsm($form) but nothing to change the output of the div id.
Doing some code searching, I did find
  $output = '<div class="form-item"';
  if (!empty($element['#id'])) {
    $output .= ' id="'. $element['#id'] .'-wrapper"';
  }

at file includes/form.inc; Line 2208.

So any ideas on how I can add something to that 'form-item'?

Thanks in advance

MVC

Drupal is MVC (Model View Controller) thus you just need create a node-content_type-edit.tpl.php and you can add your own class or div. Look at this sample (modifying from this tutorial section) :

<div id="this-is-your-own-id"> 
  <fieldset class="collapsible this-is-my-class">
    <legend>Company Data</legend>
    <?php
     
print drupal_render($form['group_company']['field_company']['0']['value']);
   
?>

  </fieldset> 
</div>

So, you don't need to touch includes/form.inc

I do have a

I do have a node-content_type-edit.tpl.php and using drupal_render. I don't change any core files. 'form-item' is created by core, and wanted to know if there was a way to change it
If I write my own divs with php, then I'm looking at 50 hours or so, if I use php and CSS, then about 10 hours if I can get that 'form-item' to change.
Oh well, thanks for the help, I'll start doing some php :D

You right, Drupal also only

You right, Drupal also only provide <form id="node-form"> instead <form id="node-form-story"> for 'story' content-type. Fortunately, for every form-item(s) Drupal has give specific ID. According to your example:

<div id="edit-field-sh-ac-typeadministrati-value-1-wrapper" class="form-item">

We can use the ID of "edit-field-sh-ac-typeadministrati-value-1-wrapper" rather than class of "form-item" fo specific task. IMHO, this is the safest way, because when you alter "form-item" then others element will changing especially form-item in Views module (in Views admin area).

Drupal 7?

Will this still work in Drupal 7?

I follow the tutorial

I follow the tutorial precisely and...nothing happens. My content type is cal_event and theme is mytheme:

I add this to template.php in my theme:

<?php function mytheme_theme($existing, $type, $theme, $path) {
  return array(
   
'cal_event_node_form' => array(
       
'arguments' => array('form' => NULL),
       
'template' => 'node-cal_event-edit'
   
)
  );
}
?>

I add this to node-cal_event-edit.tpl.php, to check if it works:

<?php unset($form['title']);

print
drupal_render($form);
?>

I clear cached data. Nothing happens.

Nothing happens.

What stupid mistake am I making?

Try visit Administer-Site Building-Themes then just click "Save configuration".

Please publish some CSS

The form in the "Consignment Note" above looks nice; is there a chance you can publish some CSS here just to get an idea? Additionally, Do you have any recommendations whether the CSS should hard-coded in the node-xxxxxx-edit.tpl.php or added to the main CSS of the theme.

Thanks

Main CSS. Never hardcode css

Main CSS. Never hardcode css into a template

CSS into certain template file

@youssefr and @willhowlett:
I didn't put the CSS into Drupal main css (style.css), instead I starting the node-content_type-edit.tpl.php with css definition, why? Because I have > 20 forms which will make the style.css become very complex css. But this may make some duplicate css as @willhowlett concern.

Another solution is to create a new CSS file if you like.

What I have done to keep the

What I have done to keep the CSS tidy is in the edit.tpl.php file, in the <head> of the HTML, include the CSS file. The draw back is, Drupal won't handle the CSS as is cache, gzip compression... But it will only be called on that form which saves resources.

Or add a line to mytheme.info for your CSS.

Hi By any chance, is there

Hi

By any chance, is there anyone who can post some sample or similar code?

Thanks.

Node Form Template module

...may be of use to some people: http://drupal.org/project/node_form_template

Hi, Is this for the editing /

Hi,

Is this for the editing / adding a new node page?

Thanks.

Yes it is

Yes it is

theme function for Zen sub-theme

Use something like this:

function generic_theme(&$existing, $type, $theme, $path) {

  $hooks = zen_theme($existing, $type, $theme, $path);

  $hooks['question_node_form'] = array(
      'arguments' => array('form' => NULL),
      'template' => 'templates/node-account_question-edit'
  );

  return $hooks;
}

Nicolas
-------------------------
http://nic.ipwa.net

gmap?

function garland_theme($existing, $type, $theme, $path) {
return array(
'form_node_form' => array(
'arguments' => array('form' => NULL),
'template' => 'node-form-edit'
)
);
}

<?php
<fieldset class="location collapsible ">
<
legend>location</legend>
    <?
php print drupal_render($form['locations']['0']['street']);
?>

<?php
print drupal_render($form['locations']['0']['additional']);
?>

<?php
print drupal_render($form['locations']['0']['country']);
?>

<?php
print drupal_render($form['gmap']['auto1map']['gmap0']);
?>

<?php
print drupal_render($form['gmap']['auto1map']['locpick_latitude0']);
?>

<?php
print drupal_render($form['gmap']['auto1map']['locpick_longitude0']);
?>

?>
It can not print .....
id=gmap-auto1map-gmap0
id=gmap-auto1map-locpick_latitude0-wrapper
id=gmap-auto1map-locpick_longitude0-wrapper
why???

remove body label.

I try to remove the body label,

<?php
unset ($form['body_field']['#title']);
?>
won't work.

I guess I am missing something:).

Thanks for your help!

CSS

@xenta have you tried editing this in the CSS? Isolate the tag for that field and set the div ID to display: none;

Not sure the "right" way to remove this coding-wise but that's the quick and dirty method I've used.

Only able to remove body label on certain inputs

First of all thanks a ton for this write up!
I am having one issue and I would rather solve it in my template file rather than using css to hide the labels.
I use

<?php
unset ($form['body_field']['#title']);
?>

to hide the labels in my template file. It works for select list input types but not for text fields or text areas.
Does anyone have any solutions to this problem?

7. HIDE A TITLE/LABEL OF FIELD

This already mention in this tutorial, read this section may help:

7. HIDE A TITLE/LABEL OF FIELD
Some tutorials say:

<?php
unset($form['field_test']['#title']);
?>

Above code only remove '#title' from array elements, but not remove the title/label.

To hide title/label from a field:

<?php
unset($form['field_test']['value']['#title']);
?>

Sorry for my typo

Thanks for the response.

I mistyped my original post. I had actually tried all of these:

<?php
unset($form['field_test']['value']['#title']);
?>

<?php
unset($form['field_test']['#title']);
?>

<?php
unset($form['field_test']['0']['#title']);
?>

All of the code pieces resulted in the same problem. Label/title is not removed for text area or text field inputs.

Please read again this tutorial, especially on the last paragraph, you need ['0'] before ['value'].

<table>
<tr><td>
  Label is: <?php print $form['field_sample1']['#title']; ?>
</td></tr>

<tr><td>
  <?php unset($form['field_sample1']['0']['value']['#title']); ?>
  <?php print drupal_render($form['field_sample1']['0']['value']); ?>
</td></tr>
</table>

Thanks for your help

I appreciate your help. Sorry to have missed that in my reading of the tutorial. Following the instructions worked like a charm...imagine that.

Hello All, Can someone please

Hello All,
Can someone please guide me how to set width/size of a select list. I have 8 select lists in a CCK content type. All 8 select list are different size in width. I want to set their size to for example 60.

Thanks

CSS?

CSS?

Render taxonomy form

<?php print drupal_render($form['taxonomy']); ?>

Any idea how to render

Any idea how to render taxonomy per vocabulary ? I would like to render several vocabularies using hierarchical select

Page status

No known problems

Log in to edit this page

About this page

Drupal version
Drupal 6.x
Audience
Themers

Theming Guide

Drupal’s online documentation is © 2000-2012 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.