Creating textfields dynamically

Hi,

I need to create a layout which contains between 2 and 20 textfields and a Validate button;
these textfields are created dynamically, so i guess they have the same reference (tx1 here).
When the user click on the Validate button, how to gather the values of all the textfields ?

TextField tx1 = new TextField("");
TextField tx1 = new TextField("");
TextField tx1 = new TextField("");
...
Button validate = new Button("Validate");
validate.addListener(new Button.ClickListener() {
				public void buttonClick(ClickEvent event) {

                 String str1 = tx1.getValue();
                 ... ? ...
});

Hi,

First of all,

TextField tx1 = new TextField("");
TextField tx1 = new TextField("");
TextField tx1 = new TextField("");

would give a compile error. I assume you meant

TextField tx1 = new TextField("");
tx1 = new TextField("");
tx1 = new TextField("");

So, your problem is that when you click a validation button, you want to process all these TextFields?
If you add them all to the same layout, you could just iterate through that layout’s components and cast the components to TextFields where appropriate. However, then every TextField in that Layout would be processed. Why not just add the references of the TextFields (or the Properties of the TextFields) to some external Collection? This depends much on the use case.

BR,
Johan

Thank you Johan, i think the following code should work :

TextField[ ]
 tabTextFields = new TextField[ ]
;

for(int i=0; i<5;i==){
      tabTextFields[ i ]
 = new TextField("");
      tabTextFields[ i ]
.setValue(i);
}

then
for(int i=0; i<5;i==){
      System.out.println( tabTextFields[ i ]
.getValue()) ;
}

Eric

Hi

As long as you know that you are not going to remove any of the TextFields in action, using arrays will work.

As I earlier pointed out, you could also use the componentIterator of your layout, then you do not need to have double book keeping of your components. Here is an example:

First, add your components to some layout:


        myLayout.addComponent(new TextField() {{ setValue("1"); }});
        myLayout.addComponent(new TextField() {{ setValue("2"); }});
        myLayout.addComponent(new TextField() {{ setValue("3"); }});
        myLayout.addComponent(new CheckBox("checkbox", true));

then, when you want to process the values of your components, you could create a method like


    public void myProcessingMethod(ComponentContainer layout) {
        Iterator<Component> componentIterator = layout.getComponentIterator();
        while (componentIterator.hasNext()) {
            Component component = componentIterator.next();

            // This would be specifically only for TextFields
            if (component instanceof TextField) {
                System.out.println("Alt 1: TextField String value: "
                        + (String) ((TextField) component).getValue());
            } else if (component instanceof CheckBox) {
                System.out.println("Alt 1: Checkbox boolean value: "
                        + ((CheckBox) component).booleanValue());
            }

            // Alternatively, you could check any component that implements the
            // Property interface
            if (component instanceof Property) {
                System.out.println("Alt 2: Property object value: "
                        + ((Property) component).getValue());
            }

            // If you are nesting your layouts, you could check them recursively like this
            if (component instanceof ComponentContainer) {
                myProcessingMethod((ComponentContainer) component);
            }
        }
    }

then just call your method somewhere and process any layout


myProcessingMethod(someLayout);

The result for this would be


Alt 1: TextField String value: 1
Alt 2: Property object value: 1
Alt 1: TextField String value: 2
Alt 2: Property object value: 2
Alt 1: TextField String value: 3
Alt 2: Property object value: 3
Alt 1: CheckBox boolean value: true
Alt 2: Property object value: true

Thanks Johan,
I used tables for my work and it works fine.
I will use the ComponentIterator the next time !
:smiley:

This is working fine.But to create any component dynamically and add it to a layout,
myLayout.addComponent(new TextField(“TextField”)); ← Is this the only way

I have to set input prompt for dynamically created textFields.how can i do it.

Hey vineel,
maybe the FieldGroup coming with the FieldFactory is going to solve your issue. With FieldFactory you can create dynamically fields while having full control. Another benefit is that you have beans bound.

https://vaadin.com/book/-/page/datamodel.itembinding.html