The XHTML label is highly flexible, with the
theoretical ability to appear anywhere within the same form as its associated form control:

<form action="example" method="get">
	<fieldset>
		<input type="text" name="somewhereelse" id="somewhereelse" 
			size="26" value="My label is somewhere else &#8230;" />
		<br />
		<label for="before">It can be <strong>before</strong> the control.</label>
		<input type="text" name="before" id="before" />
		<br />
		<input type="checkbox" name="after" id="after" />
		<label for="after">It can be <strong>after</strong> the control.</label>
		<br />
		<label for="somewhereelse">It can be <strong>somewhere else</strong>
			in the form.</label>
		<br />
		<label>It can be <em>even</em> be &#8230;
			<input type="text" name="around" id="around" />
		&#8230; wrapped <strong>around</strong> the control!</label>
	</fieldset>
</form>

Of course, theory tends to break down in practice. Screenreaders generally require the label to either enclose or be adjacent to the control, rather than wandering off on its own. In theory, wrapping a label round the control should implicitly associate the label with the control (as in the example code above). But, in practice, many user agents screenreaders still require the for attribute to recognise the association.

Still, some web designers have found wrapping controls in their label elements the best starting point for styling a form. Unfortunately, Wicket's SimpleFormComponentLabel cannot cope with that situation, since it replaces its entire body (including the control itself) with the label text defined in its model.

The solution is to use FormComponentLabel for adding the correct id to the label's for attribute, but add the actual text of the label in with other components – typically a Label bound to a span. For example, in the form in ExamplePage.html:

<label for="something" wicket:id="somethingLabel">
      <span wicket:id="somethingLabelSpan">[Label text]</span>
      <input type="text" name="something" id="something" wicket:id="something" />
</label>

And in ExampleForm.java:

/* Bind a TextField to the input element: */
TextField somethingField = new TextField("something");
somethingField.setOutputMarkupId(true);
/* This could equally pull a label out of a resource. */
somethingField.setLabel(new Model("Something or other: "));

/* Bind a FormComponentLabel component to the label element: 
 * This will automatically update the "for" attribute to match the id of somethingField
 */
FormComponentLabel somethingLabel = new FormComponentLabel("somethingLabel",somethingField);

/* Add the field to the containing label.*/
somethingLabel.add(somethingField);
Label somethingLabelSpan = new Label("somethingLabelSpan",somethingField.getLabel());

/* Get rid of the span tag, leaving the label only: */
somethingLabelSpan.setRenderBodyOnly(true);

/* Add the label span to the containing label: */
somethingLabel.add(somethingLabelSpan);

/* Finally, add the containing label to the form: */
this.add(somethingLabel);
  • No labels