How to dynamically calculate value of a column in edit mode in Vaadin 8 grid component - vaadin

I have a table in my UI which is a grid component. The value of one of the columns is calculated based on other column input values. So for example there are columns A,B, and C and value of column C = A + B. What I want to achieve is when user edits a row, before clicking the save button it would be able to see the calculated value in edit mode.
Is there a possibility to do that without Javascript or if not, how can I run a javascript snippet on onBlur event of the editable columns (A and B).
The calculated column is not editable by user.
This is a non functional code snippet that shows more or less what is the basis of my code.
Grid<Numbers> grid = new Grid<>(Numbers.class, false);
Editor<Numbers> editor = grid.getEditor();
Grid.Column<Numbers> aColumn = grid
.addColumn(Numbers::getA).setHeader("A")
.setWidth("120px").setFlexGrow(0);
Grid.Column<Numbers> bColumn = grid.addColumn(Numbers::getB)
.setHeader("B").setWidth("120px").setFlexGrow(0);
Grid.Column<Numbers> cColumn = grid.addColumn(Numbers::getC)
.setHeader("C");
Grid.Column<Numbers> editColumn = grid.addComponentColumn(numbers -> {
Button editButton = new Button("Edit");
editButton.addClickListener(e -> {
if (editor.isOpen())
editor.cancel();
grid.getEditor().editItem(numbers);
});
return editButton;
}).setWidth("150px").setFlexGrow(0);
Binder<Numbers> binder = new Binder<>(Numbers.class);
editor.setBinder(binder);
editor.setBuffered(true);
TextField aField = new TextField();
aField.setWidthFull();
binder.forField(aField)
.bind(Numbers::getA, Numbers::setA);
aColumn.setEditorComponent(aField);
TextField bField = new TextField();
bField.setWidthFull();
binder.forField(bField)
.bind(Numbers::getB, Numbers::setB);
bColumn.setEditorComponent(bField);
TextField cField = new TextField();
cField.setWidthFull();
binder.forField(cField)
.bind(Numbers::getC, Numbers::setC);
cColumn.setEditable(false);
Button saveButton = new Button("Save", e -> editor.save());
Button cancelButton = new Button(VaadinIcon.CLOSE.create(),
e -> editor.cancel());
cancelButton.addThemeVariants(ButtonVariant.LUMO_ICON,
ButtonVariant.LUMO_ERROR);
HorizontalLayout actions = new HorizontalLayout(saveButton,
cancelButton);
actions.setPadding(false);
editColumn.setEditorComponent(actions);
I tried adding this to some events:
Page.getCurrent().getJavaScript().execute("alert('the calculated value')");
The problem is the elements that are created by grid component have no id, so accessing them directly is not an option. Traversing dom is not really feasible too.

Related

Grid Row Freezing

Is there a way to freeze the top-most row in a Vaadin Grid so that it can always be viewed, no matter how much the user scrolls vertically? I was looking at https://vaadin.com/docs/latest/components/grid/#column-freezing, but I'm not sure if this would help for rows.
Based on idea given in the commments, here is a proof of concept code that demonstrate how to do it Vaadin Grid.
Grid<String> grid = new Grid<>();
grid.setHeight("250px");
grid.setWidth("250px");
GridListDataView<String> dataView = grid.setItems("Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten");
Column<String> col = grid.addColumn(value -> value.toString()).setHeader("A number");
HeaderRow row = grid.appendHeaderRow();
Div div = new Div();
div.setText(dataView.getItem(0).toString());
div.getElement().getStyle().set("text-align", "left");
div.getElement().getStyle().set("width", "100%");
row.getCell(col).setComponent(div);
grid.addSelectionListener(event -> {
event.getFirstSelectedItem().ifPresent(item -> {
div.setText(item.toString());
});
});

add label to check box item in smart gwt

I need to add a label to my checkbox in smart GWT. For example, I have three fruits: apple, mango and banana. How can I add the label Fruits as heading. I am also unable to use CheckboxGroup.
CheckBox check1 = new CheckBox();
check1.setBoxLabel("Classical");
CheckBox check2 = new CheckBox();
check2.setBoxLabel("Rock");
check2.setValue(true);
CheckBox check3 = new CheckBox();
check3.setBoxLabel("Blue");
CheckBoxGroup checkGroup = new CheckBoxGroup();
checkGroup.setFieldLabel("Music");
checkGroup.add(check1);
checkGroup.add(check2);
checkGroup.add(check3);
Hy Abhaya, first of all i don't know what version of smart GWT you use but i can see that this is not smart GWT, its more like gwt component and that CheckBoxGroup is some awt component.
If You want to use smart GWT check box component then use CheckboxItem widget, if its item that means you need to use dynamic form.
So lets say:
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.DynamicForm;
CheckBoxItem item1 = new CheckBoxItem();
item1.setTitle("Classical");
CheckBoxItem item2 = new CheckBoxItem();
item1.setTitle("Rock");
So now we have 2 check box items, wee need to put them in dynamic form like this (I set border so u can see what happens):
DynamicForm box = new DynamicForm();
box.setBorder("1pt solid red")
box.setFields(item1,item2);
Lets draw that:
box.draw();
This is output:
drawn dynamic form
Ok now we need title, best way is to add lable before dynamic form. Now dynamic form is root element, lets put it in some layout (new package), layout will be vertical so for every new member it will be one beneath other:
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.Label;
Label title = new Label();
title.setContents("Music");
title.setHeight(20);
VLayout lay = new VLayout();
lay.setBorder("1pt solid black");
lay.addMember(title);
lay.addMember(box);
So wee added title in layout then dynamic form named "box", now u don't need to draw() box, only layout because that layout consists of label and box that will be automatically drawn:
lay.draw();
And output is this:
drawn vertical layout
Here is the little bit styled look:
Styled look
Entire code:
CheckboxItem item1 = new CheckboxItem();
item1.setTitle("Classical");
CheckboxItem item2 = new CheckboxItem();
item2.setTitle("Rock");
CheckboxItem item3 = new CheckboxItem();
item3.setTitle("Metal");
CheckboxItem item4 = new CheckboxItem();
item4.setTitle("House");
DynamicForm box = new DynamicForm();
box.setFields(item1,item2, item3, item4);
box.setWidth100();
box.setHeight100();
box.draw();
Label title = new Label();
title.setContents("<h3>Music:</h3>");
title.setHeight(20);
VLayout lay = new VLayout();
lay.setMargin(20);
lay.setBorder("1pt solid black");
lay.setPadding(10);
lay.setBackgroundColor("#e6e6e6");
lay.addMember(title);
lay.addMember(box);
lay.draw();
In property setContents() u can use HTML tags and CSS
I hope it helps.
Regards, Jakov A.

Setting the height of a devexpress mvc Gridview combo box

I am using a DEvExpress mvc grid with a few combo boxes and I was wondering how I can set the maximum/minimum height (in a number of rows) of the drop down section.
For example can I set the rows visible before you have to scroll or even if there is only one row of data for the drop down height to be set to a certain number of rows.
The current code for the combo I have now is
#Html.DevExpress().ComboBox(edtSettings =>
{
edtSettings.ControlStyle.CssClass = "employeeDetailsGridEditField";
edtSettings.Name = "DepartmentID";
edtSettings.Width = 350;
//edtSettings.Height = 200;
//THIS sets the height of the initial control not the drop down part
edtSettings.Properties.TextField = "DepartmentName";
edtSettings.Properties.ValueField = "DepartmentID";
edtSettings.Properties.ValueType = typeof(int);
edtSettings.Properties.DropDownStyle = DropDownStyle.DropDown;
edtSettings.ShowModelErrors = true;
}).BindList(Model.DepartmentList).Bind(Model.EmployeeSingle.DefaultDepartmentID).GetHtml()
Is there a property for the drop down section height?
Use the ComboBoxProperties.DropDownRows property to get or set the number of list items displayed within the editor's scrollable dropdown window simultaneously:
#Html.DevExpress().ComboBox(edtSettings =>
{
//...
edtSettings.Properties.DropDownRows = 5; // default is 7
//...
}).BindList(Model.DepartmentList).Bind(Model.EmployeeSingle.DefaultDepartmentID).GetHtml()

How to add a click Listener to a table's cell in vaadin?

I created a multiselectable table in vaadin, but I can't select only a cell in this table when I click it selects all row.
Is there any way of selecting only a cell of a row ?
The title of the question doesn't reflect the actual question inside
Is there any way of selecting only a cell of a row ?
No. The whole point of a Vaadin table is to reflect rows of data in a tabular form. Setting a table to selectable keeps track of the itemIds of the selected rows with the table
You might be able to simulate selecting cells by using a ColumnGenerator in the table, and adding a listener to the generated component. Removing the listener may be tricky, however.
Alternatively, you may wish to simply generate components in a GridLayout and keep track of the selected cells yourself.
Ultimately, the approach here really depends upon exacly what you are trying to achieve.
It depends on what you're trying to accomplish. (Your question title and your question details are addressing two different questions.) If you're wondering whether or not you can target a specific cell and add a click listener to it, then yes, of course you can:
//initial layout setup
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
//Create a table and add a style to allow setting the row height in theme.
final Table table = new Table();
table.addStyleName("components-inside");
//Define the names and data types of columns.
//The "default value" parameter is meaningless here.
table.addContainerProperty("Sum", Label.class, null);
table.addContainerProperty("Is Transferred", CheckBox.class, null);
table.addContainerProperty("Comments", TextField.class, null);
table.addContainerProperty("Details", Button.class, null);
//Add a few items in the table.
for (int i=0; i<100; i++) {
// Create the fields for the current table row
Label sumField = new Label(String.format(
"Sum is <b>$%04.2f</b><br/><i>(VAT incl.)</i>",
new Object[] {new Double(Math.random()*1000)}),
Label.CONTENT_XHTML);
CheckBox transferredField = new CheckBox("is transferred");
//Multiline text field. This required modifying the
//height of the table row.
TextField commentsField = new TextField();
//commentsField.setRows(3);
//The Table item identifier for the row.
Integer itemId = new Integer(i);
//Create a button and handle its click. A Button does not
//know the item it is contained in, so we have to store the
//item ID as user-defined data.
Button detailsField = new Button("show details");
detailsField.setData(itemId);
detailsField.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
// Get the item identifier from the user-defined data.
Integer iid = (Integer)event.getButton().getData();
Notification.show("Link " +
iid.intValue() + " clicked.");
}
});
detailsField.addStyleName("link");
//Create the table row.
table.addItem(new Object[] {sumField, transferredField,
commentsField, detailsField},
itemId);
}
//Show just three rows because they are so high.
table.setPageLength(3);
layout.addComponent(table);
It might be beneficial to examine the documentation.

Is the layout for a vertical panel with components correct?

How to insert a vertical panel in the form for laying out the components in a vertical layout fashion.
For example as
Component 1
Component 2
Component 3.
Please give me an example code.
I want to fit it in the following fashion!
Display of the panels
HorizontalPanel mainPanel = new HorizontalPanel();
VerticalPanel leftSidePanel = new VerticalPanel();
TextBox textBox1 = new TextBox();
TextBox textBox2 = new TextBox();
leftSidePanel.addMember(textBox1);
leftSidePanel.addMember(textBox2);
VerticalPanel rightSidePanel = new VerticalPanel();
ListBox listBox = new ListBox();
listBox.addItem("value1","value1");
listBox.addItem("value2","value2");
rigthSidePanel.addMember(listBox);
mainPanel.addMember(leftSidePanel);
mainPanel.addMember(rightSidePanel);

Resources