button beside textfield

Hi Jouni Koivuviita,

Hi I’m a beginner with Vaadin and I’m trying to use this component:

I want to keep the Button beside the TextField can u give me an example.

Hi,

Which component are you referring to? It is not clear. However, the simplest answer is “Use A Horizontal Layout”. Layouts are explained in
Chapter 6
of the
Book Of Vaadin
.

One of the best things about Vaadin is it’s documentation : I strongly recommend that you read “The Book”.

Anyway, here’s a working example of a button-beside-a-textbox.

Cheers,

Charles.

public class HorizontalLayoutExampleApp extends Application {
  @Override
  public void init() {
    final TextField textField = new TextField();
    textField.setImmediate(true);
    Button button = new Button("Go", new Button.ClickListener() {
      @Override
      public void buttonClick(Button.ClickEvent event) {
        event.getButton().getWindow().showNotification("Value:" + textField.getValue());
      }
    });

    HorizontalLayout layout = new HorizontalLayout();
    layout.addComponent(textField);
    layout.addComponent(button);
    layout.setSpacing(true);

    Window w = new Window();
    w.addComponent(layout);
    setMainWindow(w);
  }
}

I’m afraid I don’t understand your question. What icon?

Please, explain clearly what you want to happen, and what is happening : show a code snippet, and/or a screenshot.

We can’t help you if we don’t understand what your problem is, and I can think of very few problems that can be explained in a single sentence :slight_smile:

Cheers,

Charles.

Hi,

I have a text field (ID) where a user can enter an Integer (ID). I want a button right of the field, clicking on which the ID should be auto generated, instead of the user entering the ID.

I want this textfield+button to be treated as a single component. I am using this field inside a form layout.

Should I create a custom component?

Or should I extend a Textfield with a button functionality? Like this component here ResetButtonForTextField (https://vaadin.com/directory#!addon/resetbuttonfortextfield) . The author explains the process of extention in this blog https://vaadin.com/blog/-/blogs/extending-components-in-vaadin-7

Firstly, is there an existing add-on/vaadin component that I can use, so as to not reinvent the wheel

Secondly, if it comes to extending the Textfield, in the example of ResetButtonForTextField, the reset button appears when user enters some text. However in my case I need a permanent button. My application is completely Server side, would I need to write client side code incase I nedeed to add a permanent button to the text field?

Please provide some pointers/examples to follow, if an existing reusable component does not exist.

Thanks for your help.

Chahat

Hi Chahat,

in case you are using Vaadin 7.3+ you can style a CssLayout to look like a component group. For example combining a TextField with a Button.

TextFieldWithButton.class

[code]
public class TextFieldWithButton extends CssLayout {

private final TextField textField;
private final Button button;

public TextFieldWithButton(String caption, Resource icon, ClickListener listener) {
    setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
    setCaption(caption);

    textField = new TextField();
    textField.setWidth(100, Unit.PERCENTAGE);

    button = new Button(icon);
    button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
    button.addClickListener(listener);

    addComponents(textField, button);
}

public TextField getTextField() {
    return textField;
}

public Button getButton() {
    return button;
}

}
[/code]How to use:

TextFieldWithButton fieldWithButton = new TextFieldWithButton("FieldWithButton", FontAwesome.USER,
                onClick -> Notification.show("Hello World!"));

Result:



I hope this suites your use case.

best regards

Johannes

Dear JohannesL,

Thanks for your reply. The composition of components did cross my mind. I wasnt sure though if the bean binding/validation etc would still work out of the box like it works with a normal text field. or I will have to hand craft the composition.

Please let me know.

thanks for the help.

thanks
Chahat

Dear JohannesL,

I did the composition of textfield+button like you suggessted. I put it in a Horizontal layout instead os CssLayout.

The dataproperty bound to this field is a required field. When I setRequired on the text field, the required indicator is not at the place where it is supposed to be. Please see the attachment

Any suggestions please?

thanks
Chahat
28230.png

Hi,

the JavaDoc of CustomField<?> suggests, that it should be what you are looking for.


"A Field whose UI content can be constructed by the user, enabling the creation of e.g. form fields by composing Vaadin components. Customization of both the visual presentation and the logic of the field is possible. […]
"

In case you want a reusable component you could expose all method you want to be able to modify.

e.g.
ButtonField:

[code]
public class ButtonField extends CustomField {

private final TextField textField = new TextField();
private final Button button = new Button();

@Override
protected Component initContent() {
    CssLayout layout = new CssLayout();
    layout.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);

    textField.setWidth(100, Unit.PERCENTAGE);
    textField.setImmediate(true);
    textField.addTextChangeListener(onTextChange -> this.setValue(textField.getValue()));

    button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);

    layout.addComponents(textField, button);
    return layout;
}

@Override
public Class<? extends String> getType() {
    return String.class;
}

@Override
public void setValue(String newFieldValue)
        throws com.vaadin.data.Property.ReadOnlyException, ConversionException {
    textField.setValue(newFieldValue);
    super.setValue(newFieldValue);
}


//Create setters for everything you need?
public void setButtonIcon(Resource icon) {
    button.setIcon(icon);
}

public void addClickListener(ClickListener listener) {
    button.addClickListener(listener);
}

public void removeClickListener(ClickListener listener) {
    button.removeClickListener(listener);
}

}
[/code]How to use:

ButtonField field = new ButtonField(); field.setButtonIcon(FontAwesome.KEY); field.addClickListener(onClick -> field.setValue("12345678")); field.addValidator( new StringLengthValidator("The name must be 1-10 letters (input: {0})", 1, 10, true)); You could also create a Field specific to your case.

e.g.
IDField

[code]
public class IDField extends CustomField {

private final TextField textField = new TextField();
private final Button button = new Button();

@Override
protected Component initContent() {
    CssLayout layout = new CssLayout();
    layout.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);

    textField.setWidth(100, Unit.PERCENTAGE);
    textField.setImmediate(true);
    textField.addTextChangeListener(onTextChange -> this.setValue(textField.getValue()));
    textField.addValidator(
            new StringLengthValidator("The name must be 1-10 letters (input: {0})", 1, 10, true));

    button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
    button.setIcon(FontAwesome.KEY);
    button.addClickListener(event -> textField.setValue(generateID()));

    layout.addComponents(textField, button);
    return layout;
}

@Override
public Class<? extends String> getType() {
    return String.class;
}

@Override
public void setValue(String newFieldValue)
        throws com.vaadin.data.Property.ReadOnlyException, ConversionException {
    textField.setValue(newFieldValue);
    super.setValue(newFieldValue);
}

private String generateID() {
    return "12345";
}

}
[/code] IDField field = new IDField(); Required and validate behavor should be like a normal TextField.



regards

Johannes

PS: I can see that your using Reindeer. You don’t need to use the CssLayout and its aditional styles if you are not using Vaadins Valo Theme.

Thanks JohannesL

Johannes Laidler:
Hi Chahat,

in case you are using Vaadin 7.3+ you can style a CssLayout to look like a component group. For example combining a TextField with a Button.

TextFieldWithButton.class

public class TextFieldWithButton extends CssLayout {

    private final TextField textField;
    private final Button button;

    public TextFieldWithButton(String caption, Resource icon, ClickListener listener) {
        setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        setCaption(caption);

        textField = new TextField();
        textField.setWidth(100, Unit.PERCENTAGE);

        button = new Button(icon);
        button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
        button.addClickListener(listener);

        addComponents(textField, button);
    }

    public TextField getTextField() {
        return textField;
    }

    public Button getButton() {
        return button;
    }
}

How to use:

TextFieldWithButton fieldWithButton = new TextFieldWithButton("FieldWithButton", FontAwesome.USER,
                onClick -> Notification.show("Hello World!"));

Result:

![]
(http://fs5.directupload.net/images/160922/38zy7uam.png)

I hope this suites your use case.

best regards

Johannes

This looks great, however, is it possible to bind this to a field in fieldgroup? Currently, i use:-

fieldGroup.buildAndBind(“CHAIRED BY”, “chairedByName”, TextField.class);

John.

This looks great, however, is it possible to bind this to a field in fieldgroup?

The above code example does not work with field group directly, since it is not a field. So you need to wrap it inside CustomField.

Tatu Lund:

This looks great, however, is it possible to bind this to a field in fieldgroup?

The above code example does not work with field group directly, since it is not a field. So you need to wrap it inside CustomField.

Thanks, is there a simple way to achieve this? I looked at CustomField but only see an example using a Boolean…

I did the following:-

public class TextButtonField extends CustomField<String> {
	private TextField textField = new TextField();
	
    @Override
    protected Component initContent() {
    	
        textField.setWidth(100, Unit.PERCENTAGE);
        textField.setStyleName(ValoTheme.TEXTFIELD_SMALL);
        textField.setStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
        textField.setReadOnly(true);

        Button button = new Button();
        button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
        button.setIcon(FontAwesome.USER);
        //button.addClickListener(listener);

        CssLayout myLayout = new CssLayout();
        myLayout.addComponents(textField, button);
        myLayout.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        return myLayout;
    }

    @Override
    public String getValue() {
        return textField.getValue();
    }

    @Override
	public void setValue(String value) {
        this.textField.setValue(value);
    }

	@Override
	public Class<? extends String> getType() {
		// TODO Auto-generated method stub
		return String.class;
	}
	
	
	@Override
    protected void setInternalValue(String v) {
        textField.setValue(v);
    }
	   
}