views:

70

answers:

1

Hello all,

I don't have experience in php. I've followed a few tutorials to modify my Drupal forms using the theme method in template.php.

For some reason the [#weight] property for a field does not adhere to its values. I'd like to move the Category field [cid] above Subject field [subject]. These are the lines of code I used:

$form['cid']['#weight'] = 0.003;
$form['subject']['#weight'] = 0.004;

When I print my array to view I see the values have changed, but when I render the form no changes are made. I have already cleared performance cache after every modification.

If you're interested here is a snippet of my printed array:

[subject] => Array
        (
            [#type] => textfield
            [#title] => Subject
            [#maxlength] => 255
            [#required] => 1
            [#post] => Array
                (
                )

            [#programmed] => 
            [#tree] => 
            [#parents] => Array
                (
                    [0] => subject
                )

            [#array_parents] => Array
                (
                    [0] => subject
                )

            [#weight] => 0.004
            [#processed] => 1
            [#description] => 
            [#attributes] => Array
                (
                )

            [#input] => 1
            [#size] => 60
            [#autocomplete_path] => 
            [#process] => Array
                (
                    [0] => form_expand_ahah
                )

            [#name] => subject
            [#id] => edit-subject
            [#value] => 
            [#defaults_loaded] => 1
            [#sorted] => 1
        )

    [cid] => Array
        (
            [#type] => select
            [#title] => Category
            [#default_value] => 1
            [#options] => Array
                (
                    [1] => General Enquiries
                    [2] => Support
                )

            [#required] => 1
            [#post] => Array
                (
                )

            [#programmed] => 
            [#tree] => 
            [#parents] => Array
                (
                    [0] => cid
                )

            [#array_parents] => Array
                (
                    [0] => cid
                )

            [#weight] => 0.003
            [#processed] => 1
            [#description] => 
            [#attributes] => Array
                (
                )

            [#input] => 1
            [#size] => 0
            [#multiple] => 
            [#process] => Array
                (
                    [0] => form_expand_ahah
                )

            [#name] => cid
            [#id] => edit-cid
            [#value] => 1
            [#defaults_loaded] => 1
            [#sorted] => 1
        )

Much appreciated,

Chris

+3  A: 

You generally see that behavior on node forms when CCK is enabled. This is because CCK overrides weight for the default and CCK fields with its own ordering system configurable by going to Content management -> Content types -> [Content Type] -> Manage fields.

Of course, if you disable CCK (probably not an option), your #weight values will be respected.

One thing to note is that while Forms API allows decimals for #weight, it's good practice to use integers.


Edit

If you want to work within the constraints CCK presents, in a custom module you'll need to implement a #pre_render handler that will alter the weights of the form elements after CCK alters them:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['#pre_render'][] = 'mymodule_form_alter_weight';
}

function mymodule_form_alter_weight($elements) {
  $elements['cid']['#weight'] = 0.003;
  $elements['subject']['#weight'] = 0.004;

  return $elements;
}

The problem is, you will have no idea what weight values CCK has used for other form elements, so while you'll have ordered cid before subject, both fields might show up in the middle of all the other fields on the page and not in their original position.

CCK forces you into a corner when it comes to weight. The correct, Drupal/CCK way to handle form ordering is to respect the choices made by an administrator on Content management -> Content types -> [Content type] -> Manage fields.

If you have a custom form element, you can tell CCK about it so it shows up in Manage fields by implementing hook_content_extra_fields(). Continuing with the code above:

function mymodule_content_extra_fields() {
  $extras['mymodule'] = array( // Name of field
    'label' => t('Mymodule'),
    'description' => t('Mymodule field'),
    'weight' => 10, // The default weight, can be overriden on Manage Fields
  );

  return $extras;
}
Mark Trapp
That makes sense. So is there a way around this? I need an exception just for the contact form. I know I could probably theme it, but is there a coding fix?
Chris
@Chris, yes and no. I've updated my answer with more information and some possible solutions.
Mark Trapp
@MarkThanks for the solution. I understand how CCK handles form fields now. I guess if I had a custom form then I would go this route, but since I just need to rearrange one [cid] field in the site-wide contact form I will just go with theming CSS. I will take note of your solution for future reference. Many thanks!
Chris