Add id to field with ui:field declaration - gwt

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?

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());

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>

b:id="test" works for all gwtbootstrap3 widgets.

Related

How to locale angular element using by.model in protractor

I have this text box element.
<input type="text" name="textbox" class="box-input ng-pristine ng-scope md-input ng-empty ng-valid ng-valid-required ng-touched" ng-required="field.required" ng-model="$ctrl.model[field.nameField.uuid]" ng-disabled="::field.readOnly" id="input_15" aria-invalid="false" style="">
In protractor how should I use it to locate the element? I am not quite sure how to use ng-model="$ctrl.model[field.nameField.uuid]"
If you are using angular 2 or above by model might not work for you, see here.
You could still use the model attribute to identify your element through css like so
$('[ng-model="$ctrl.model[field.nameField.uuid]"]')
or
element(by.css('[ng-model="$ctrl.model[field.nameField.uuid]"]'))
try like this
let input = element(by.model('$ctrl.model[field.nameField.uuid]'));
I suggest to use unique ID if its possible, or some unique class styles leading to single element.

How to append a link to gwtbootstrap 3 InputField

I want to do this in html:
<div class="input-group" id="name">
<input type="text" class="form-control" name="name" placeholder="Name">
<span class="input-group-addon">None</span>
</div>
I try this in GWT Bootstrap:
<b:InputGroup>
<b:TextBox b:id="name" placeholder="Name"/>
<b:InputGroupAddon>
<b:Anchor ui:field="noName" text="None"/>
</b:InputGroupAddon>
</b:InputGroup>
But thus I get the error:
Illegal child <b:Anchor text='Name' ui:field='noName'> in a text-only context. Perhaps you are trying to use unescaped HTML where text is required, as in a HasText widget?: <b:InputGroupAddon> (:56)
Why? b:Anchor implements HasText interface.
My aim is to add a link on which, when a user clicks input will fill value NONE
The HasText bit is about InputGroupAddon, not Anchor. "Text-only context" (implied by implementing HasText) means you can only put, well, text into that widget. Either through the text property (<b:InputGroupAddon text='Name' />) or inside the tags (<b:InputGroupAddon>Name</b:InputGroupAddon>) - those declarations are equivalent. You can't put unescaped HTML or widgets in such a context.
For your use case, I'd recommend using buttons (as the Bootstrap docs suggest):
<b:InputGroup>
<b:TextBox b:id="name" placeholder="Name" />
<b:InputGroupButton>
<b:Button ui:field="noName" text="None" />
</b:InputGroupButton>
</b:InputGroup>
See the demo to see it in action. You can easily style it to your needs (maybe no text and just an icon = "ERASER").

Generate <input type="search" /> using Play! framework

I'm using the Play Framework. I want to use the HTML5 input type 'search'. So, I want to output:
<input type="search" />
I've tried:
#inputText(field = myForm("myField"), 'type -> "search")
but it still kept the type="input"
the method inputText represents an HTML input text (see the source code here).
You have to define your own template to define the input of type search. Take a look at the Play documentation.
#helper.input(myForm("myField")) { (id, name, value, args) =>
<input type="search" name="#name" id="#id" #toHtmlArgs(args)>
}
Most probably your search field will not use many typical things from common form element (like constraints or error messages) so you can just use plain HTML to insert it, and add field's value in the proper attribute (if required at all):
<input type="search" name="myField" value="#myForm("myField").value" />
If it's just a search form (with this only field) you even don't need to wrap it with the Form class
(of course Nico's suggest is advisable in more sophisticated scenarios)
Some helpers you're looking for are avalaible in a play 2 module. The html5 input helpers are not in the core part of the framework because play authors want to keep it light.
Here is the module page on github : https://github.com/loicdescotte/Play2-HTML5Tags

Play 2.0 Nested forms: generate <input id="email"> instead of <input id="user_email">

Posted this to Play user group; I account for the sole view, so hoping to get a view, or perhaps even an answer ;-)
Nested forms are great, but there's one glitch that adds boilerplate to either javascript or scala templates.
For example, given:
#inputText(field = _form("user.email"),
'_label-> "Email Address*",
'class-> "required email",
'placeholder-> "jdoe#gmail.com"
)
the generated input field is something like:
<input id="user_email" name="user.email" ...>
Now, when you want to validate the email address client-side you then have to reference DOM id: $('#user_email')
Where $('#email') would be more natural.
I know I can set the id attrib manually in the template but would prefer to, by default, have the nested name (user in this case) stripped out from the id attrib.
Looking in github views helper directory, I am not finding where I can get access to the generated id (i.e. which file I need to overload and how).
Anyone know how to pull this off and/or have a better approach?
Here is where the field's ID is auto-generated:
https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/data/Form.scala#L274
There's not really any way you can override that behaviour, but you could write your own #inputText helper that strips the "user_" part from the ID when generating the HTML.
Basically copy-paste the default helper and replace
<input type="text" id="#id" ...
with your own code, e.g.
<input type="text" id="#processFieldId(id)" ...
or (untested!):
<input type="text" id="#(id.split('_').last)" ...
Then just import your custom helper in your template, and use it just like you would use #inputText.

How to dynamically populate a choices widget in symfony?

Suppose there is an image_url column in database.
I want the user to choose from several recommended images,which is something like this:
<input type="radio" value="domain.com/path_to_img1" name="image_url" />
<img src="domain.com/path_to_img1" />
<input type="radio" value="domain.com/path_to_img2" name="image_url" />
<img src="domain.com/path_to_img2" />
Where the image urls are generated on the fly.
How to do this in a symfony flavor by sfForm?
I tried this:
$form->widgetSchema['key'] = new sfWidgetFormSelect(...)
But get a fatal error:
Cannot access protected property
But what's the exact way to do this?
Well, standart approach is to write a widget.
In your concrete case it seems you actually want to perform a choice, right? So you have to implement another sfWidgetFormChoice renderer. To do that, inherit sfWidgetFormSelectRadio (let's call them sfWidgetFormSelectRadioImage) to learn them to render labels as <img> tags. Then ask sfWidgetFormChoice explicitly to render itself with sfWidgetFormSelectRadioImage class, and that should be all.
In your form configuration insert the following:
$this->widgetSchema['choices'] = new sfWidgetFormChoice (array('choices' => $custom_values_array));