Grid rows: how to add grid rows ?

In Vaadin Grid while doing multiselection, there was this example where users can easily delete selected rows. However, my needs are that – can you also add items instead.

// Allow deleting the selected items
Button delSelected = new Button("Delete Selected", e ->
{ 
	// Delete all selected data items
	for (Object itemId: selection.getSelectedRows())
		grid.getContainerDataSource().removeItem(itemId);
	// Otherwise out of sync with container
	grid.getSelectionModel().reset();
	// Disable after deleting
	e.getButton().setEnabled(false); 
});
delSelected.setEnabled(grid.getSelectedRows().size() > 0);

Something like this would be great:
grid.getContainerDataSource().addItem(itemId);

Hi, I’m not sure what you mean. Do you mean how to easily duplicate selected rows as new rows to Grid or something else?

Okay, how do you “easily duplicate selected rows as new rows to Grid or something else”

Can anyone give some code example to do such thing in Vaadin Grid?

Although I am looking into how to dynamically add new rows in Vaadin Grid with BeanItemContainer, but without any success yet.

So if the BeanItemContainer is your datasource for Grid and you call container.addBean(bean) nothing happens?

Thanks for your response.

I am trying something like this:
(but does not seem to work)

[code]
add.addClickListener(new Button.ClickListener() {

        /**
         */
         
        private static final long serialVersionUID = 1L;

        @Override
        public void buttonClick(ClickEvent event) {
                for (Object itemId: selection.getSelectedRows()) {
              
                    //  grid00.getContainerDataSource().addItem(itemId);
                    final BeanItemContainer<NotesPojo> beans =
                            new BeanItemContainer<NotesPojo>(NotesPojo.class);
                  
                    beans.addBean((NotesPojo) itemId);
                }
            
        }
    }); 

[/code]I am trying to add a button that will add a row in the BeanItemContainer but nothing seem to work yet.

grid00.getContainerDataSource().addItem(itemId); Should work if the grid00 doesn’t already contain the id - the bean in case of BeanItemContainer.

Thanks for the response.
How can you add row without selection?

Of course, doing like what you said will copy the elements rows from the grid
but can we add row by just by clicking of the button?

I hope this helps.

package com.example.addingitemstogrid;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
@Theme("valo")
public class AddingitemstogridUI extends UI {
    private static final int POJO_AMOUNT = 30;
    private Button addNew;
    private Button addSelected;
    private ListSelect select;
    private Grid grid;
    
    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = AddingitemstogridUI.class)
    public static class Servlet extends VaadinServlet {
    }

    @Override
    protected void init(VaadinRequest request) {
        
        BeanItemContainer<MyPojo> selectContainer = new BeanItemContainer<>(MyPojo.class);
        BeanItemContainer<MyPojo> gridContainer = new BeanItemContainer<>(MyPojo.class);

        select = new ListSelect();
        select.setItemCaptionPropertyId("name");
        select.setMultiSelect(true);
        select.setContainerDataSource(selectContainer);
        select.addValueChangeListener(this::onListSelectValueChanged);
        selectContainer.addAll(getRandomPojos(POJO_AMOUNT));
        
        grid = new Grid();
        grid.setContainerDataSource(gridContainer);
        grid.getContainerDataSource().addItem(new MyPojo("Hello", 13));
        
        VerticalLayout buttons = new VerticalLayout();
        addNew = new Button("Add New", this::onAddNew);
        addNew.setWidth("100%");
        addSelected = new Button("Add Selected", this::onAddSelected);
        addSelected.setWidth("100%");
        addSelected.setVisible(false);
        buttons.addComponents(addSelected, addNew);
        buttons.setWidth("130px");
        buttons.setSpacing(true);
        
        HorizontalLayout content = new HorizontalLayout();
        
        setContent(content);
        content.addComponents(select, buttons, grid);
        content.setExpandRatio(grid, 1.0f);
        content.setSpacing(true);
        content.setMargin(true);
    }
    
    private void onAddNew(Button.ClickEvent event) {
        grid.getContainerDataSource().addItem(new MyPojo("Douglas Adams", 42));
    }
    
    private void onAddSelected(Button.ClickEvent event) {
        if (select.getValue() instanceof Collection) {
            for (Object itemId : ((Collection<?>) select.getValue())) {
                // In BeanItemContainer the item id is actually the bean. 
                // The item is BeanItem and we don't want that.
                // You could clone your bean here if you need another reference
                grid.getContainerDataSource().addItem(itemId);
            }
        }
    }
    
    private void onListSelectValueChanged(Property.ValueChangeEvent event) {
        if (((Collection<?>) event.getProperty().getValue()).isEmpty()) {
            addNew.setVisible(true);
            addSelected.setVisible(false);
        } else {
            addNew.setVisible(false);
            addSelected.setVisible(true);
        }
    }
    
    private static List<MyPojo> getRandomPojos(int amount) {
        Random rand = new Random(1001L);
        String names = { "John", "Johannes", "Jonathan", "Jonas", "Joan", "Jill" };
        int ages = { 21, 28, 32, 64, 35, 46 };
        
        List<MyPojo> result = new ArrayList<>();
        for (int i = 0; i < amount; i++) {
            result.add(new MyPojo(names[rand.nextInt(names.length)]
, ages[rand.nextInt(ages.length)]
));
        }
        
        return result;
    }
    
    public static class MyPojo {
        private String name;
        private int age;
        
        public MyPojo() {
            
        }
        
        public MyPojo(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }

}

EDIT 21.3.2016: fixed button visibility bugs

Thanks for the solution.

To delete, I added this method in your solution. It works nicely now.

  private void onDelete(Button.ClickEvent event) {
        MultiSelectionModel selection = (MultiSelectionModel) grid.getSelectionModel();
        for (Object itemId: selection.getSelectedRows()) {
            grid.getContainerDataSource().removeItem(itemId);
        }
        grid.getSelectionModel().reset();

    }