Why does the '#weight' property sometimes not have any effect in Drupal forms?

Wanted to insert a <div> I could use in JS. This didn't work for me:

  $form['you_as_reviewer']['ui_container'] = array(
    '#type' => 'markup',
    '#value' => '<div id="le_reviewer_tags_ui"/>',
    '#weight' => 5,
  );

Weight was ignored.

This worked:

  $form['you_as_reviewer']['ui_container'] = array(
    '#type' => 'markup',
    '#prefix' => '<div>',
    '#value' => '<div id="le_reviewer_tags_ui"/>',
    '#suffix' => '</div>',
    '#weight' => 5,
  );

Added prefix and suffix.


Sometimes (or always, when weighting CCK elements) the line that works in your hook_form_alter or $form['#after_build'] callback is this one:

$form['#content_extra_fields']['taxonomy']['weight'] = 5;

This sounds pretty strange because the manipulation of the form elements' #weight parameter always works reliably for me as advertised. One thing to note, though, is that the weights only affect the order relative to the elements siblings, so if the element you want to move around is on a level below that of the other elements, you'd have to change the weight of the parent element that is on the same level as the ones you want to move against.

To clarify, if you have a hierarchy like so,

$element['foo'];
$element['bar'];
$element['bar']['baz']

you can not move 'baz' relative to 'foo' by setting the weight of 'baz'. You'd have to either set the weight on 'bar' (moving it also), or pull out 'baz' and bring it to the same level as 'foo'.

Another possible reason could be CCK: If you have CCK installed, it allows you to set the order of its own as well as other fields under admin/content/node-type/<yourNodeType>/fields. It changes the order by registering the pre-render callback content_alter_extra_weights(), so this would run after your changes in hook_form_alter.


Edit: Update to answer the question update

The markup field type has a special behavior when used inside fieldsets, which is hinted on in the forms api documentation:

Note: if you use markup, if your content is not wrapped in tags (generally <p> or <div>), your content will fall outside of collapsed fieldsets.

It looks like if it does not only fall outside of collapsed fieldsets, but also refuses to respect the weight in those cases. Wrapping the content of the markup field in <p> tags makes it respect the weight on my machine:

$form['taxonomy']['instructions'] = array(
  '#value' => "<p>These are the instructions</p>",
  '#weight' => -1,
);

Tags:

Forms

Drupal