Vaadin TextField's value not available in shortcut listener - vaadin

I want to read a Vaadin Flow TextField's value when the user presses the Enter key. I can add a ShortcutListener to listen for the keypress, but the value of the TextField is null in the listener even though the TextField is not empty:
TextField textField = new TextField();
Shortcuts.addShortcutListener(UI.getCurrent(), () -> {
String text = texttextField.getValue();
// text doesn't contain the latest text
}, Key.ENTER);
Why is this happening and how can I read the value that the user has entered when the keypress listener is triggered?

The behavior boils down to browser events. While the user may have entered some text into the input element, the value of the TextField is not updated to the server until there's a ValueChange event - even the vaadin-text-field element in the browser doesn't "know" of the text (the value property has not been updated) when the enter keypress event occurs. By default, the value of the text field is only updated when the input loses focus. You can work around the issue by explicitly toggling a blur of the TextField:
// member field in class
boolean shortcutFired = false;
// ...
Shortcuts.addShortcutListener(UI.getCurrent(), () -> {
textField.blur();
shortcutFired = true;
}, Key.ENTER);
and listening to the value change event instead of the shortcut listener:
textField.addValueChangeListener(e -> {
if( shortcutFired ) {
String value = e.getValue();
// do something with the value
shortcutFired = false;
}
}
This approach doesn't work too well if you need to keep track of multiple fields; in that case, you might want to make the TextFields update their values to the server more eagerly by setting their ValueChangeMode to ValueChangeMode.EAGER. The downside of this approach is that it increases the amount of traffic between the browser and the network, as every keypress will trigger a server request.

Related

TextField onValueChange is Called When Focused

Using TextField in Compose, I found that looks like a bug.
When I change the textfield value , focus out and in again,
onValuseChange method is called even there is no change.
this is not What I want, So I write some defending code for this comparing prev value.
But I want to know another nice solution.
here is my code.
onValueChange = { _inputText ->
if(_inputText.text != countState.value){
}
},

Customize SmartGwt ListGrid dynamically for passwords

I have a com.smartgwt.client.widgets.grid.ListGrid for my configurations screen.
I have 3 ListGridFields name, value, isHidden.
I want to use PasswordItem if isHidden is true, and TextItem if isidden is false.
How can I customize the grid?
I tried with setEditorCustomizer, but it only works when I am editing a cell. In view mode I am able to see the text.
I don't think there's a way to do what you want (show the PasswordItem editor when visualizing the ListGrid's fields). As you already found out, setEditorCustomizer works only when in editing mode.
But you can mask the field values. Here is how to do it:
// very important for not having to set all fields all over again
// when the target field is customized
listGrid.setUseAllDataSourceFields(true);
// customize the isHidden field to make it respond to changes and
// hide/show the password field accordingly
ListGridField isHidden = new ListGridField("isHiddenFieldName");
isHidden.addChangedHandler(new ChangedHandler() {
#Override
public void onChanged(ChangedEvent event) {
// the name of this field has to match the name of the field you
// want to hide (as defined in your data source descriptor,
// ListGridField definition, etc).
ListGridField passwordField = new ListGridField("passwordFieldName");
if ((Boolean) event.getValue() == true) {
passwordField.setCellFormatter(new CellFormatter() {
#Override
public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
return ((String) value).replaceAll(".", "*");
}
});
}
// you need to re-add here the isHidden field for the ChangeHandler to
// be present when recreating the ListGrid
listGrid.setFields(isHidden, passwordField);
listGrid.markForRedraw();
}
});
// add the customized field to the listGrid, so that we can have the
// desired ChangeHandler for the isHidden field
listGrid.setFields(isHidden);
Bear in mind that if you hide the value (or use a PassowrdItem), an 'expert' user could see the value, simply because the server is sending the value to the client.
If you actually have a security constraint, you may use DataSourceField.viewRequires, which accepts velocity expressions.

Value of textfield before "Editing Changed" event is fired

I want to know if there is a way to know the value of textfield before the value is changed to the new value.
For example:
If the text field had a value "a" and the user entered "b", so the editing changed event is fired. When I try to fetch the value of the text field in the debugger it will display "ab". Is there a way that I can get "a" before "b" was written?
Here is a piece of code where I am trying to fetch the value:
#IBAction func commentEditingChanged(sender: AnyObject) {
if(!((sender as? UITextField)!.text!.isEmpty)){
counter++
}
else
{
counter--
}
}
In this case I want to know if the text was empty before the user entered text because I don't want the counter increments every time the user enters a character. I want to increment once the user entered any text.
And please don't propose to use delegate function textField:shouldChangeCharactersInRange:replacementString because my question is about this IBAction method.
If there is no way to do that using this IBAction Method, is there is any other IBAction method that can achieve what i want?

How to hide spinner on the basis of text entered in edittext box?

M sorry for wrong English. I want to hide the spinner on the basis of text entered in the edit Text box and not on some click event. This means spinner hiding condition should be checked on the basis of Edit Text value.
Any kind of help will be appreciated.
I have Used TextWatcher class to have a check on the text that is being entered in the edittext. And then have used the method to check ds
private void checkFieldsForEmptyValues()
{
Spinner =(Spinner)findViewById(R.id.site_spinner1);
String s1 = edit1.getText().toString();
String s2 = edit2.getText().toString();
if(s1.equals("admin") && s2.equals("admin"))
{
spinner.setEnabled(false);
}
}

Vaadin addStyleName problem

I created a TextField with TextChangeListener. When user types in certain values (in this case 'admin') then addStyleName is invoked on that field and font color becomes red. But afterwards, the value is blank and each entered character is being cleared.
Here is the code of the application. Why after adding new style to TextField its value changes?
public class VaadintestApplication extends Application {
#Override
public void init() {
Window mainWindow = new Window("Vaadintest Application");
setTheme("test");
TextField textField = new TextField("username");
textField.setEnabled(true);
textField.setTextChangeEventMode(TextChangeEventMode.EAGER);
textField.addListener(new TextChangeListener() {
public void textChange(TextChangeEvent event) {
if ("admin".equals(event.getText())) {
((TextField) event.getComponent()).addStyleName("text-error");
} else {
((TextField) event.getComponent()).removeStyleName("text-error");
}
}
});
mainWindow.addComponent(textField);
setMainWindow(mainWindow);
}
}
I would guess that the following happens:
The style name change triggers a repaint on the server, causing the TextField component to be serialized again to the client
The client receives the serialization (the whole bloody thing, not just the changed parts, because that's how things work with Vaadin), and hence it changes the contents of the textfield, while ignoring any changes that are pending from the text change listener
Solutions:
Update the value of the TextField at the same time you add/remove the style name: ((TextField) event.getComponent()).setValue(event.getText())
Create a custom client side widget which extends VTextField and add the functionality there

Resources