Why Label widget chose to use <div> instead of <label>?

310 views
Skip to first unread message

Open eSignForms

unread,
Dec 2, 2009, 10:45:43 PM12/2/09
to Google Web Toolkit
Does anybody know the history as to why GWT's Label widget uses a
<div> instead of a <label> tag?

The label tag allows the label to be tied to another element, such as
the input tag, for accessibility, yet that seems lost with the Label
widget.

Seems like Label was a misnomer and should have been called Text to
parallel HTML.

As for myself, I essentially copied the GWT Label widget source to
make my own Label that creates a <label> instead. It's below if
anybody cares. I removed all of the deprecated stuff from GWT Label
since it's a new class. And I don't set the default style to be gwt-
Label since that would surely match more than expected and use esf-
Label just for keeping it in sync. And because it's a label tag, the
label can also be HTML or Text.

package com.esignforms.open.gwt.client.widget;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasAllMouseHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWordWrap;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
* A widget that creates a &lt;label&gt; tag. This code was based on
the Google com.google.gwt.user.client.ui.Label widget that
* creates a DIV/SPAN, with all of the deprecated code removed.
*/
public class Label
extends Widget
implements HasHorizontalAlignment, HasText, HasWordWrap,
HasDirection, HasClickHandlers, HasAllMouseHandlers
{

/**
* Creates a Label widget that wraps an existing &lt;div&gt; or
&lt;span&gt;
* element.
*
* This element must already be attached to the document. If the
element is
* removed from the document, you must call
* {@link RootPanel#detachNow(Widget)}.
*
* @param element the element to be wrapped
*/
public static Label wrap(Element element)
{
// Assert that the element is attached.
assert Document.get().getBody().isOrHasChild(element);

Label label = new Label(element);

// Mark it attached and remember it for cleanup.
label.onAttach();
RootPanel.detachOnWindowClose(label);

return label;
}

private HorizontalAlignmentConstant horzAlign;

/**
* Creates an empty label.
*/
public Label() {
setElement(Document.get().createLabelElement());
setStyleName("esf-Label");
}

/**
* Creates a label with the specified text.
*
* @param text the new label's text
*/
public Label(String text) {
this();
setText(text);
}

/**
* Creates a label with the specified text.
*
* @param text the new label's text
* @param wordWrap <code>false</code> to disable word wrapping
*/
public Label(String text, boolean wordWrap) {
this(text);
setWordWrap(wordWrap);
}

/**
* This constructor may be used by subclasses to explicitly use an
existing
* element. This element must be a &lt;label&gt; element.
*
* @param element the element to be used
*/
protected Label(Element element) {
setElement(element);
assert element.getTagName().equalsIgnoreCase("label");
}

public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}

public HandlerRegistration addMouseDownHandler(MouseDownHandler
handler) {
return addDomHandler(handler, MouseDownEvent.getType());
}

public HandlerRegistration addMouseMoveHandler(MouseMoveHandler
handler) {
return addDomHandler(handler, MouseMoveEvent.getType());
}

public HandlerRegistration addMouseOutHandler(MouseOutHandler
handler) {
return addDomHandler(handler, MouseOutEvent.getType());
}

public HandlerRegistration addMouseOverHandler(MouseOverHandler
handler) {
return addDomHandler(handler, MouseOverEvent.getType());
}

public HandlerRegistration addMouseUpHandler(MouseUpHandler handler)
{
return addDomHandler(handler, MouseUpEvent.getType());
}

public HandlerRegistration addMouseWheelHandler(MouseWheelHandler
handler) {
return addDomHandler(handler, MouseWheelEvent.getType());
}

public Direction getDirection() {
return BidiUtils.getDirectionOnElement(getElement());
}

public HorizontalAlignmentConstant getHorizontalAlignment() {
return horzAlign;
}

public String getText() {
return getElement().getInnerText();
}

/**
* Returns the HTML if it is set to HTML.
* @return the getInnerHTML of the element.
*/
public String getHTML()
{
return getElement().getInnerHTML();
}

public boolean getWordWrap() {
return !getElement().getStyle().getProperty("whiteSpace").equals
("nowrap");
}

public void setDirection(Direction direction) {
BidiUtils.setDirectionOnElement(getElement(), direction);
}

public void setHorizontalAlignment(HorizontalAlignmentConstant
align) {
horzAlign = align;
getElement().getStyle().setProperty("textAlign",
align.getTextAlignString());
}

public void setText(String text) {
getElement().setInnerText(text);
}

/**
* Sets the label value to be the specified HTML.
* @param html the HTML value of the label.
*/
public void setHTML(String html)
{
getElement().setInnerHTML(html);
}

public void setWordWrap(boolean wrap) {
getElement().getStyle().setProperty("whiteSpace",
wrap ? "normal" : "nowrap");
}
}

Yozons Support on Gmail

unread,
Dec 2, 2009, 10:56:55 PM12/2/09
to Google Web Toolkit
I forgot the methods for setting the "for" attribute id!  I used the setHtmlFor() method name to match the dom LabelElement class (my own pref would have been setFor(id)).

  /**
   * Sets the attribute "for" on the label tag to be the specified id.
   * @param id the String id to use.
   */
  public void setHtmlFor( String id )
  {
      ((LabelElement)getElement().cast()).setHtmlFor(id);     
  }
 
  /**
   * Sets the attribute "for" on the label tag to be the id of the specified widget.
   * @param forWidget the Widget that should have an id.  Note that if forWidget does not have
   * an id, both it and the label "for" will be set to a unique id.
   */
  public void setHtmlFor( Widget forWidget )
  {
      assert forWidget != null;
      String wid = forWidget.getElement().getId();
      if ( wid == null || "".equals(wid) )
      {
          wid = DOM.createUniqueId();
          forWidget.getElement().setId(wid);
      }
      setHtmlFor(wid);
  }

philippe

unread,
Dec 3, 2009, 3:37:11 AM12/3/09
to Google Web Toolkit
Maybe Label widget generate div to a better compatibility with ie6 ??
Maybe..

Thomas Broyer

unread,
Dec 3, 2009, 5:04:32 AM12/3/09
to Google Web Toolkit

On Dec 3, 4:45 am, Open eSignForms <yoz...@gmail.com> wrote:
> Does anybody know the history as to why GWT's Label widget uses a
> <div> instead of a <label> tag?

Probably because the Label widget is only for showing some text, not
necessarily label an input widget (such as a TextBox).
I also think GWT has not a really good history regarding accessibility
(feel free to disagree with me)

> The label tag allows the label to be tied to another element, such as
> the input tag, for accessibility, yet that seems lost with the Label
> widget.

GWT is hiding HTML, the DOM, etc. from developers (when using widgets'
"high level" APIs), so that developers don't depend on widgets
internals. For instance, there's no method for setting a widget's
"ID", you have to getElement().setId("myId"); but there's a method for
setting IDs for debugging purposes (ensureDebugId).

This means that if GWT had such a widget, it'd probably have a
setLabeledControl(...) method (to have a friendly API); which means
that:
- the NewLabel widget would have to create the ID of the labeled
control, which means it'd break as soon as ensureDebugId is called on
the labeled control
- the "link" between NewLabel and its labeled control would break as
soon as the labeled control's ID is changed, which breaks the
assumption that the "link" is between the widgets (you passed a Widget
to setLabeledControl, not an ID)
- because per the HTML spec [1,2], the for="" attribute references a
"control" [3,4], setLabeledControl would have to check the widget
argument for being "labelable". It'd better be done at compile time
than runtime, which would mean constraining the use of NewLabel to
labeling known widgets: TextBox (PasswordTextBox extends TextBox),
ListBox, TextArea, Button, FileUpload, SimpleCheckBox
(SimpleRadioButton extends SimpleCheckBox); which rules out user-
defined widgets, even if they use a "labelable" DOM element (well,
eventually, there could be a Labelable interface, but implementing it
wouldn't be enough for the NewLabel to "work")

[1] http://www.w3.org/TR/html4/interact/forms.html#adef-for
[2] http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#attr-label-for
[3] http://www.w3.org/TR/html4/interact/forms.html#h-17.2
[4] http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-label

If you were to have a setLabeledControlID(String) instead of
setLabeledControl(Widget), it'd mean you expect people to use the
lower-level getElement().setId(...) method of the labeled widget,
which also means they are aware that it can play quite badly with
ensureDebugId. Providing a high-level API (NewLabel widget and its
setLabeledControlID method) that requires users to use low-level APIs
in other widgets in order to use it, looks weird.

I think GWT doesn't include such a widget for all these reasons. If
you want such a widget, you have to know the implications, i.e. know
GWT's internals, which means you are capable of writing the widget
yourself.
If GWT provided such a widget, expect a high number of bug reports,
just because people do not understand the implications, which means
incidentally much (too much) time spent on "fixing" the widget to make
it reliably work in almost all situations.

> Seems like Label was a misnomer and should have been called Text to
> parallel HTML.

Many widgets in other toolkits are called "label" without the
associated meaning of being associated with a control; for instance
java.awt.Label: http://java.sun.com/javase/6/docs/api/java/awt/Label.html

> As for myself, I essentially copied the GWT Label widget source to
> make my own Label that creates a <label> instead.

As for myself, I'm now using UiBinder, so the <label> is in the
*.ui.xml and if the labeled control has to be a widget, then in my
Java code I assign the labeled widget's ID and the label for="" to the
same createUniqueID() value.
You can search the GWT-C archives for a proposal to better handle this
in UiBinder; I also have a proposal (as a private Wave), but I'm
waiting for 2.0 to be released to make it public and actually discuss
it.

philippe

unread,
Dec 3, 2009, 6:13:42 AM12/3/09
to Google Web Toolkit

philippe

unread,
Dec 12, 2009, 11:49:44 AM12/12/09
to Google Web Toolkit
Label tag must be used with input ID. With GWT we can't put an ID on
input tag so the label tag can't be used.

I think that ID aren't authorized for avoid the double ID in the DOM
and bugs.

HTML 4.01 or XHTML 1.1 are older. I hope that futur HTML version will
provide better management of dynamic pages.


On 3 déc, 12:13, philippe <vonck...@yahoo.fr> wrote:
> I also think GWT has not a really good history regarding
> accessibility.
>
> http://code.google.com/intl/fr-FR/webtoolkit/doc/1.6/DevGuideI18nAndA...

philippe

unread,
Dec 12, 2009, 2:35:15 PM12/12/09
to Google Web Toolkit
I've a solution to use a label with an input.

Is to use Html GWT widget to create this:
&lt;label&gt;
Description
&lt;input type="text" name="description" /&gt;
&lt;/label&gt;

philippe

unread,
Dec 12, 2009, 3:37:05 PM12/12/09
to Google Web Toolkit
Ok it's the last :)

I've a solution to use a label with an input.

Is to use Html GWT widget to create this:
<label>
Description
<input type="text" name="description" />
</label>

mP

unread,
Dec 12, 2009, 4:58:09 PM12/12/09
to Google Web Toolkit
Who really cares if GWT uses DIV instead of Label. In the end many
elementsare interchangable, with the main difference being they
initially come with some predefined styles, and the element name makes
it easier to build a selector in css without assigning a class. After
styling said element it can be made to look like a completely
different element. Naturally this is not true of elements that
represent actual ui controls like SELECT - but even that can be
emulated if one really wants too.

Yozons Support on Gmail

unread,
Dec 12, 2009, 7:22:11 PM12/12/09
to google-we...@googlegroups.com
The use of LABEL tags is useful for accessibility.  Just like TH is useful for tables, though a TD will suffice, this is less the case when attempting to be accessible.

philippe

unread,
Dec 13, 2009, 4:06:47 AM12/13/09
to Google Web Toolkit
It is very important to improve accessibility. Everybody benefits from
this because at the same time improves the overall ergonomics.

See : http://www.seoconsultants.com/html/forms/labels/

Jan Ehrhardt

unread,
Dec 13, 2009, 6:01:20 AM12/13/09
to google-we...@googlegroups.com
A HTML Label tag is used as a label for an input. A GWT Label widget is just a text containing area somewhere in your UI. I think a Div tag is the natural choice for a Widget like Label.

Regards
Jan Ehrhardt


--

You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.



philippe

unread,
Dec 13, 2009, 1:48:07 PM12/13/09
to Google Web Toolkit
@Jan: no, html label tag isn't just a text. For Visually impaired
people, Readers for Visually impaired interpreter tag "Label" as the
text input fields. If you click on the text label tag, the input is
automatically selected. The input tag can't be automatically selected
with a text Div tag.

A good structure of your DOM is benefit for all agents.
> > google-web-tool...@googlegroups.com<google-web-toolkit%2Bunsubs cr...@googlegroups.com>
> > .

Yozons Support on Gmail

unread,
Dec 13, 2009, 2:04:56 PM12/13/09
to google-we...@googlegroups.com
I agree, and it would have been better name Text or TEXT to match the setText() methods and to go in parallel with the HTML widget. But bad choice of names is impossible to fix once they are done, and anybody who's ever written an API knows that we all get them wrong from time to time.

There's no issue with divs or how the Label widget works, just that the when writing widgets for HTML-based solutions, Label would have mapped nicer to <label>, and a Text widget would have mapped to an HTML-escaped widget that just contains text (and not markup).  That's just my 2 cents. 

I built my own simple widgets using GWT, so it's not like it can't be done, just that it's not out of the box.  No problem at all really, just part of the learning curve.

But I do love GWT, and once the holidays are over, I'll investigate SmartGWT further to determine if its widgets are nicer to work with for building business apps.  Then the real question is do I deal with proprietary SmartGWT PRO/EE or just stick with the LGPL version and GWT-RPC to plug into their DataSource scheme.  It's just not clear to me yet whether SmartClient folks are really committed to GWT since much of their toolset is still JS-based (like ExtJS).  But that's another topic entirely <smile>


Jan Ehrhardt

unread,
Dec 13, 2009, 4:36:10 PM12/13/09
to google-we...@googlegroups.com
Well, GWT supports WAI-ARIA. I don't know what GWT does in the case of a Label to support it, but you can create a custom class, that extends Label and gives it the exact WAI-ARIA behavior you want.

Regards
Jan Ehrhardt

To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.

philippe

unread,
Dec 14, 2009, 5:55:55 AM12/14/09
to Google Web Toolkit
WAI-ARIA doesn't forget the HTML structure. The two are complementary.


On 13 déc, 22:36, Jan Ehrhardt <jan.ehrha...@googlemail.com> wrote:
> Well, GWT supports WAI-ARIA. I don't know what GWT does in the case of a
> Label to support it, but you can create a custom class, that extends Label
> and gives it the exact WAI-ARIA behavior you want.
>
> Regards
> Jan Ehrhardt
>
> > > > google-web-tool...@googlegroups.com<google-web-toolkit%2Bunsu...@googlegroups.com><google-web-toolkit%2Bunsubs
> > cr...@googlegroups.com>
> > > > .
> > > > For more options, visit this group at
> > > >http://groups.google.com/group/google-web-toolkit?hl=en.
>
> > --
>
> > You received this message because you are subscribed to the Google Groups
> > "Google Web Toolkit" group.
> > To post to this group, send email to google-we...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > google-web-tool...@googlegroups.com<google-web-toolkit%2Bunsu...@googlegroups.com>

Jan Ehrhardt

unread,
Dec 14, 2009, 8:30:06 AM12/14/09
to google-we...@googlegroups.com
WAI-ARIA allows you to declare a DIV tag as an 'aria-label', so you can decide, if a GWT label should be an 'aria-label' or not.

GWT widgets are more like Swing or SWT widgets than plain HTML tags. This might be one reason for naming a simple text containing widget 'label'. The name clash between GWT label and HTML label isn't fine, but if you know, that they're not the same, it's not a real problem anymore.

By default there is no widget in GWT, that does exactly, what a HTML label does, but if you need one, you can easily create your own.

Regards
Jan Ehrhardt


To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages