Add id to field with ui:field declaration

11,860

Solution 1

UiBinder uses the ID to implement its ui:field magic, so no you can't set it from the XML.

The way to do it is to have a Java constant with the ID and use it from both sides:

@UiField(provided = true)
final String lastNameId = Document.get().createUniqueId();

@UiField InputElement lastNameField;

…

lastNameField.setId(LAST_NAME_ID);

and in the XML:

<ui:with field="lastNameId" type="java.lang.String"/>

…

<label for="{lastNameId}">Last Name:</label>
<input ui:field="lastNameField" maxlength="150"/>

Note that I haven't tested the above code with type="java.lang.String", I've always used a class containing various identifiers instead (or rather, an interface with a generator)

Alternatives are:

  • if you can, use the alternate syntax for <label>:

    <label>Last Name: <input ui:field="lastNameField" maxlength="150"/></label>
    
  • read the for="" value from Java to use it in setId(), that way at least you remove duplication, but you'll still have the issue that your IDs possibly won't be unique (as soon as you use your UiBinder-widget more than once)

    <label ui:field="lastNameLabel" for="lastName">Last Name:</label>
    <input ui:field="lastNameField" maxlength="150" />
    
    @UiField LabelElement lastNameLabel;
    @UiField InputElement lastNameField;
    
    …
    
    lastNameField.setIf(lastNameLabel.getHtmlFor());
    

Solution 2

You may simplify Thomas' answer (a bit) by accessing the id in uibinder like this:

<b:ControlLabel for="{testTextBox.getId}">TextBox</b:ControlLabel>
<b:TextBox ui:field="testTextBox"></b:TextBox>

// In code behind:
@UiField(provided = true)
TextBox testTextBox = new TextBox();
...
testTextBox.setId("test");
this.initWidget(uiBinder.createAndBindUi(this));

If you use GWT Bootstrap there is a handy feature that let's you wire up everything in xml only:

<b:ControlLabel for="{testTextBox.getId}">TextBox</b:ControlLabel>
<b:TextBox ui:field="testTextBox" b:id="test"></b:TextBox>
Share:
11,860
Roddy of the Frozen Peas
Author by

Roddy of the Frozen Peas

Software engineer and mountain climber from the Rocky Mountains. I primarily contribute on StackOverflow but I'm inherently curious about most things and will sometimes show up on other StackExchange sites as well. I blog (poorly) about technology related things here: https://dev.to/roddy

Updated on June 04, 2022

Comments

  • Roddy of the Frozen Peas
    Roddy of the Frozen Peas almost 2 years

    I'm trying to declare these elements in my UiBinder XML:

    <label for="lastName">Last Name:</label>
    <input type="text" id="lastName" ui:field="lastNameField" maxlength="150" />
    

    Simply put, a label that is associated with a text input.

    When I try to compile, however, I get this error:

    [ERROR] Cannot declare id="lastName" and ui:field="lastNameField" on the same element Element (:23)

    This seems like an idiotic restriction, especially since ui:field doesn't generate an ID. The only solution I've found so far is to assign the ID in the Java code itself like this:

    @UiElement InputElement lastNameField;
    ...
    lastNameField.setId("lastName");
    

    This adds needless clutter to my Java. It also adds the complication that if this ID gets updated somewhere down the line, the <label> declaration in the XML will also need to be updated (and there's no @UiElement for the label, so it's pretty much completely invisible from the Java side.)

    Is there a way to add an ID to an element with a ui:field declaration from within the UiBinder XML itself?

  • Jonathan
    Jonathan about 11 years
  • Thomas Broyer
    Thomas Broyer about 11 years
    Debug-IDs are there for… debugging. Abusing tools rarely does good in the long-term.
  • annouk
    annouk over 10 years
    Thanks a lot for the section about gwt-bootstrap, it was extremely useful to me!
  • Roddy of the Frozen Peas
    Roddy of the Frozen Peas about 9 years
    Unfortunately the question is about vanilla GWT, not some bootstrap variant.
  • Greg Sheremeta
    Greg Sheremeta about 9 years
    It's useful information. Bootstrap is very popular.
  • Greg Sheremeta
    Greg Sheremeta about 9 years
    gwtbootstrap and gwtbootstrap3 are two different libraries. They share the same functionality in this case, but that's not always the case. My post is about gwtbootstrap3, while he mentioned gwtbootstrap.