How to add a button to Vaadin Table Item

Hi,

I am displaying the data in one column & multiple rows using Vaadin Table.
I want to add one button in each row just below the data.

I have given some syntax below

private void getTaskDetails(IndexedContainer container) {
container.addContainerProperty(TASK_NAME, String.class, null);
private void getTaskDetails(IndexedContainer container) {
container.addContainerProperty(TASK_NAME, String.class, null);
/container.addContainerProperty(TASK_ADDRESS, String.class, null);
container.addContainerProperty(TASK_HKTUNNUS, String.class, null);
/

    List listt = mobileApplicationService.getTaskDetailsForUser("abcd");

    String taskDesc = null;
    
    for(int i=0; i<listt.size(); i++){
        taskDesc = (String)listt.get(i);
        Item item = container.addItem(taskDesc);


        Button btn = new Button(CAPTION);
        btn.setEnabled(true);
        btn.setImmediate(true);
        btn.setVisible(true);
        item.getItemProperty(TASK_NAME).setValue(taskDesc+"\r\n"+btn);
    }

Here I am getting the output “false” inplace of button.



How to add the button at the required place and if I click on button how to get the corresponding row data.

Thanks & Regards,
Sanjay

What you’re effectively doing is creating a string in place of the button with the concatenation operator ‘+’ (item.getItemProperty(TASK_NAME).setValue(
taskDesc+“\r\n”+btn
):wink:

And you can’t use newline characters to format layout, it only works for pure text content, not for other components/widgets.

And since your column property type is set to String (container.addContainerProperty(TASK_NAME,
String.class
, null);), it’s content will always be presented as a string, no other content is possible.

What you need to do is set the column property type to some layout, preferrably CssLayout (fastest), and then insert instances of that layout into the cell. Then the layout should contain your actual information, in this case ‘taskDesc’ and ‘btn’.

Here’s some code, not tested, but I hope you get the picture:

container.addContainerProperty(TASK_NAME, [b]
CssLayout.class
[/b], null);

List listt = mobileApplicationService.getTaskDetailsForUser("abcd");

String taskDesc = null;

for(int i=0; i<listt.size(); i++){
    taskDesc = (String)listt.get(i);
    Item item = container.addItem(taskDesc);

    Button btn = new Button(CAPTION);
    btn.setEnabled(true);
    btn.setImmediate(true);
    btn.setVisible(true);

    [b]
CssLayout layout = new CssLayout();
[/b]
   [b]
 layout.addComponent(new Label(taskDesc));
    layout.addComponent(btn);
[/b]

    item.getItemProperty(TASK_NAME).[b]
setValue(layout)
[/b];
}

Hi Jouni,

Thanks for the quick response.
Your code is working successfully and I am able to get the button in each row.

Here I have one query like “how to get the corresponding row data after clicking on the Button?”

Regards,
Sanjay

When creating your button, set the item data into the button’s data filed via button.setData. Then, in a click listener, use getData to fetch your associated data

Thanks a lot.
It worked successfully.

This is how I did it


	private void init () {

		IndexedContainer indexedContainer = new IndexedContainer();
		indexedContainer.addContainerProperty(DETAIL, Button.class, null);

		Item newRow = this.addItem("first");

		Button detailButton = new Button();
		detailButton.setIcon(icon);
		detailButton.setData("my data");
		newRow.getItemProperty(DETAIL).setValue(detailButton);

		detailButton.addListener(new DetailInfoListener());
	}

	private class DetailInfoListener implements Button.ClickListener {
		@Override
		public void buttonClick(ClickEvent event) {
			String data = (String) event.getButton().getData();
			System.out.println("BUTTON CLICKED : " +  data);
			
		}		
	}

There is a cleaner way to do this


	private void init () {

		IndexedContainer indexedContainer = new IndexedContainer();
		indexedContainer.addContainerProperty(DETAIL, Button.class, null);

		Item newRow = this.addItem("first");

		Button detailButton = new Button();
		detailButton.setIcon(icon);
		// detailButton.setData("my data");
		newRow.getItemProperty(DETAIL).setValue(detailButton);

		[b]
detailButton.addListener(new DetailInfoListener("my data"));
[/b]
	}

	private class DetailInfoListener implements Button.ClickListener {
                [b]
private final String myData;
                public DetailInfoListener(String myData){
                     this.myData = myData;
                }
[/b]

		@Override
		public void buttonClick(ClickEvent event) {
			// String data = (String) event.getButton().getData();
			System.out.println("BUTTON CLICKED : " +  myData);
			
		}		
	}

I don’t think it’s a cleaner way. Correct me if I am wrong, but:
Original implementation allows for 1 static instance of DetailInfoListener
Which saves a TON of ram (over all the buttons created in each row * for each of the users on the server).

I would expect the memory overhead of the second solution (compared to one static listener) to be around 30 bytes per listener or possibly even less (assuming it doesn’t use a new copy of “my data”). Probably quite small compared to all the other overhead you have for the data on each row. If you are keeping in memory so many rows that this is a problem, you should consider using lazy loading instead.

In Vaadin 7 calling on BeanItemContainer, to be precise container.addContainerProperty throws
“Use addNestedContainerProperty(String) to add container properties”

but nested property is not what I want, I need to add button into tepi Filtered table which opens dialog when pressed. I used generated column before, but it’s not suported by Filtered table

I got somewhere with GeneratedPropertyContainer which adds desired column with CssLayout and buton into FilterTable, works fine except the table doesn’t sort, nor it does filter - throws exception instead

Hi,

I am displaying the data in 3 columns & multiple rows using Vaadin Table.
I want to add the delete button in each row just next to the score.

I have given the code for my buttons and grid below.
Attachment has the current layout of the table.

private Button addNew = new MButton(VaadinIcons.PLUS, this::add);
private Button edit = new MButton(VaadinIcons.PENCIL, this::edit);
private Button delete = new ConfirmButton(VaadinIcons.TRASH,
“Are you sure you want to delete this entry?”, this::remove);

private MGrid list = new MGrid<>(User.class) .withProperties(“id”, “name”, “score”) .withColumnHeaders(“User id”, “User Name”,“Score”) .withFullWidth();
33119.png