Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

button beside textfield

R Madhu Sudhan
10 years ago Apr 02, 2012 9:37am
Charles Anthony
10 years ago Apr 02, 2012 10:21am
Charles Anthony
10 years ago Apr 03, 2012 6:28am

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 :)

Cheers,

Charles.

chahat bhatia
5 years ago Sep 22, 2016 1:27pm
Johannes Laidler
5 years ago Sep 22, 2016 2:03pm

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:

I hope this suites your use case.

best regards

Johannes

chahat bhatia
5 years ago Sep 22, 2016 6:03pm
chahat bhatia
5 years ago Sep 23, 2016 9:30am
Johannes Laidler
5 years ago Sep 23, 2016 9:45am

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:

public class ButtonField extends CustomField<String> {

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

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

public class IDField extends CustomField<String> {

    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";
    }
}
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.

chahat bhatia
5 years ago Jan 03, 2017 2:27pm
John K
3 years ago Oct 25, 2018 11:03am
Tatu Lund
3 years ago Oct 25, 2018 11:17am
John K
3 years ago Oct 25, 2018 12:16pm

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);
    }
	   
}
Last updated on Oct, 25th 2018