How to append a link to gwtbootstrap 3 InputField - gwt

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").

Related

is there a way to bind html file with my GWT widgets

I have this HTML file for a simple Login page
<g:HTMLPanel>
<div class="login">
<div class="heading">
<h2>Sign in</h2>
<form action="#">
<g:Label ui:field="lblError" styleName="errorFields"></g:Label>
<div class="input-group input-group-lg">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input type="text" class="form-control" placeholder="Username or email" ui:field="txtUserName"/>
</div>
<div class="input-group input-group-lg">
<span class="input-group-addon"><i class="fa fa-lock"></i></span>
<input type="password" class="form-control" placeholder="Password" ui:field="txtPassword"/>
</div>
<button type="submit" class="float" ui:field="btnSubmit">Login</button>
</form>
</div>
</div>
Now is there a way I can bind this in my GWT .
I put this Html in my uibinder.xml file...
But then it says
Type mismatch: cannot convert from InputElement to TextBox
But if i change the input to GWT textbox , whole styling disturbs.
I want to have the exact same styling/effects of this html file in my GWT.
Please advice.
First of all the error you receive just means that in your java file (for this uiBinder) you've mapped txtUserName wrong;
yours is like:
#UiField
TextBox txtUserName;
Change it to
#UiField
InputElement txtUserName
But be aware - InputElement will have really small amount of functions to work with. You can "convert" this line
<input type="text" class="form-control" ui:field="txtUserName"/>
to
<g:TextBox setStyleName="form-control" ui:field="txtUserName">
You can then set the placeholder in your java file (in the constructor after the uiBinder call):
txtUserName.setAttribute("placeholder", "Username or email");
And to be sure your style is not overriden by GWT default theme - please check your ...gwt.xml file does not contain not commented lines like:
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
First of all: yes it is possible to bind to existing input elements. I used it myself for creating a login form, which should be able to allow autofill of username/password. (As far as I remember that was only possible in some browsers if the input elements were already existing during page load contained in HTML not added by GWT).
You can create a textbox that binds to the existing input element using TextBox.wrap(element) and PasswordTextBox.wrap(element) like that:
Element elemUsername = DOM.getElementById("login_username");
Element elemPassword = DOM.getElementById("login_password");
txtUserName = TextBox.wrap(elemUsername);
txtPassword = PasswordTextBox.wrap(elemPassword);
As a consequence, you would have to remove the ui:field tags in your HTML file.
And either you change the the #UiField annotation to #UiField(provided = true) for these textboxes in your java file and wrap the elements in the constructor of the form - or you have to remove this annotation completely and bind events manually (by code) if you need them.

Can my aria-describedby be placed before the input element?

I have a form with aria-describedby attributes on the input alements, followed by a span tag with a description/example of the desired input. It also has class to only display for screenreaders (sighted people can make use of the placeholder information instead).
The issue here is that, according to Fangs at least, the screenreader reads the label, then prompts for input, then reads the aria-describedby text.
Can I move the text above the input in the code, e.g.
<label for="givenName">Given name</label>
<span id="givenNameHelp" class="help-block sr-only">e.g. Liam</span>
<input class="form-control" type="text" id="givenName" placeholder="Liam" aria-describedby="givenNameHelp">
if you are already adding an HTML label to the input, you don't need to use ARIA attributes at all. You can safely remove the aria-describedby, and nest the span content. Example:
<label for="givenName">Given name
<span id="givenNameHelp" class="help-block sr-only">e.g. Liam</span>
</label>
<input class="form-control" type="text" id="givenName" placeholder="Liam">
Hope it helps!
As a general rule..First try to make accessible content with standard HTML. Then, use ARIA to describe website sections, widgets and interactive behavior (like menues, tabs, pop ups, messages, dropdowns, calendars, etc), and also to describe what you could not do with HTML.

TYPO3 merge list and edit

I've got a TYPO3 backend module which lists a lot of elements. Now, I want to include in my list the edit form, but that doesn't work well at the moment.
Rendering is good, but if I send the form, I get the error:
Required argument "note" is not set.
My code looks like this:
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<textarea class="form-control gettooltip" rows="1" placeholder="Kommentar" title="Kommentar zur Note">{note.kommentar}</textarea>
</f:form>
</f:for>
How can I merge these two views correctly?
Your code cannot work because your textarea doesn't have a property (or you don't use the <f:form.textarea ViewHelper).
If you property map $note in your controller, the property must be passed to Fluid with the prefixed extension name and plugin name. This is done automatically when using the "property" argument of the textarea ViewHelper. The name attribute will then be:
<textarea name="tx_myext_myplugin[note]"...
Thîs will map to $note in the controller.
So if you don't use the ViewHelper, you need to manually prefix the name attribute to create an output like printed just above.
If you're planning to update multiple objects of the of the same kind in one request, this won't because because there is an Extbase limitation.
You could do the following:
Use a submit button for each note and save/reload the changes through AJAX.
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" property="kommentar">{note.kommentar}</f:form.textarea>
<f:form.submit value="Update" />
</f:form>
</f:for>
Then you intercept the submit click, submit the form through AJAX and set the new content to the textarea.
If you want to have one form for all objects, you will need to prefix the fields
<f:form action="update" name="note">
<f:for each="{notes}" as="note">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" name="note[note{note.uid}][kommentar]">{note.kommentar}</f:form.textarea>
</f:for>
<f:form.submit value="Update" />
</f:form>
You will then have an array of values and need to iterate in your controller and manually persist the changes.
For your problem - as #lorenz answered you need to use viewhelpers for rendering fields OR at least use valid name attributes for your fields...
Anyway, I'm wondering why do you want to reinvent the wheel - especially while creating BE modules, the fastest, easiest and most elegant way is... using TYPO3 forms. They handle many things, relations, localization, validation, RTE etc, etc. What's more you can also add own type of field to TCA and process with your own PHP and JS - very rare situation, but may be used i.e. for adding GoogleMap field,
#see: user type in TCA
Finally all you need to open the record from your BE module is creating proper link - which can be easily copied from List module (right click on the yellow pencil next to your record and copy the code), sample:
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][1234]=edit'; return false;" title="Edit user">
<span title="" class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-open"> </span>
</a>
Where fe_users is table name and 1234 is record uid.
alt_doc.php?returnUrl='+T3_THIS_LOCATION part handles returning to the place from which edit was started, so it will be your module again including all GET params selected by admin before editing.
For creating new user
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>
In this case 6789 is a PID (uid of the page where the user should be created...
You can even set some default values when creating records from your own module using params in your new link:
&defVals[table_name][field_name]=value
sample
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new&defVals[fe_users][tx_extbase_type]=Tx_MyExt_People&defVals[fe_users][usergroup]=1'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>

Add id to field with ui:field declaration

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.

jQueryUI datepicker issue in append method

okay so i have this page im making, the navigation panel is simple, when i click a link according the the link name it appends the html into the content area, here is the append script for this section
So my goal is where the input box is the ID datepicker im trying to use the jQueryUI datepicker function from jQuery, i tested a regular input box in the actual BODY and not through the append method and it works fine, my issue is im guessing the single vs the double qoutation marks, the ' vs "
how can i solve this issue?
else if (this.id == "tour"){
$("#content").empty();
$("#content").append("<p>\
<h2> Add Tour Dates </h2>\
<form action='tourdates.php' method='post'>\
<input type='text' name='title' placeholder='Title' id='title'>\
<input type='text' name='venueName' placeholder='Vanue Name' id='venueName'>\
<input type='text' name='venueStreetAdress' placeholder='Location Street Adress' id='venueStreetAdress'>\
<input type='text' name='venueCity' placeholder='City' id='venueCity'>\
<input type='text' name='venueState' placeholder='State' id='venueState'>\
<input type='text' name='venueZip' placeholder='Postal Code' id='venueZip'>\
<input type='text' name='datepicker' id='datepicker'>\
<input type='text' name='time' placeholder='Time' id='time'> </p>\
");
If you have a strong feeling that there's something to do with your quotation mark, try to narrow down the problem: Have you tried to put this in a separated variable and make the reference there?
var htmlStuff = "<p>\
<h2> Add Tour Dates </h2>\...";
$("#content").append(htmlStuff);
But I don't think your problem is related to double/single quotes, but with the asynchronous operation of setting up a link to append HTML and try to assign an UI widget before the components exist in the DOM.
Although I find this very bad for code readability, one option would be to append another call to a function that defines the DatePicker (like a "callBack") right after your append. It should work, e.g.:
$('something').append(" <html stuff> ").defineDatePicker();
function defineDatePicker(){
$('one of the elements within that html stuff').datepicker();
}