* Fix displaying checkboxes within Grid editor row. - Checkbox margins should match regular row content margins. - Multiselect checkbox label should only be visible for assistive devices.tags/8.13.0.alpha1
// editor overlay since the original one is hidden by | // editor overlay since the original one is hidden by | ||||
// the overlay | // the overlay | ||||
final CheckBox checkBox = GWT.create(CheckBox.class); | final CheckBox checkBox = GWT.create(CheckBox.class); | ||||
checkBox.setStylePrimaryName(grid.getStylePrimaryName() | |||||
+ "-selection-checkbox"); | |||||
// label of checkbox should only be visible for | |||||
// assistive devices | |||||
checkBox.addStyleName("v-assistive-device-only-label"); | |||||
checkBox.setValue( | checkBox.setValue( | ||||
grid.isSelected(pinnedRowHandle.getRow())); | grid.isSelected(pinnedRowHandle.getRow())); | ||||
checkBox.sinkEvents(Event.ONCLICK); | checkBox.sinkEvents(Event.ONCLICK); |
padding-right: $v-grid-cell-padding-horizontal / 2; | padding-right: $v-grid-cell-padding-horizontal / 2; | ||||
} | } | ||||
input[type="checkbox"] { | |||||
:not(.v-assistive-device-only-label).v-widget > input[type="checkbox"] { | |||||
margin-left: $v-grid-cell-padding-horizontal; | margin-left: $v-grid-cell-padding-horizontal; | ||||
} | } | ||||
padding-right: round($v-grid-cell-padding-horizontal / 2); | padding-right: round($v-grid-cell-padding-horizontal / 2); | ||||
} | } | ||||
.v-checkbox { | |||||
.v-checkbox.v-widget { | |||||
margin: 0 round($v-grid-cell-padding-horizontal / 2) 0 $v-grid-cell-padding-horizontal; | margin: 0 round($v-grid-cell-padding-horizontal / 2) 0 $v-grid-cell-padding-horizontal; | ||||
> input[type="checkbox"] { | > input[type="checkbox"] { |
package com.vaadin.tests.components.grid; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.tests.components.AbstractTestUI; | |||||
import com.vaadin.ui.CheckBox; | |||||
import com.vaadin.ui.Grid; | |||||
import com.vaadin.ui.renderers.HtmlRenderer; | |||||
public class GridEditorCheckBox extends AbstractTestUI { | |||||
@Override | |||||
protected String getTestDescription() { | |||||
return "Editor content alignments should match regular row content " | |||||
+ "alignments.<br>(Double-click a row to open the editor.)"; | |||||
} | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
List<Person> items = new ArrayList<>(); | |||||
items.add(new Person(true, false, false)); | |||||
items.add(new Person(false, true, true)); | |||||
CheckBox adminEditor = new CheckBox(); | |||||
CheckBox staffEditor = new CheckBox(); | |||||
staffEditor.setPrimaryStyleName("my-custom-checkbox"); | |||||
final Grid<Person> grid = new Grid<Person>(); | |||||
grid.setSelectionMode(Grid.SelectionMode.MULTI); | |||||
grid.addColumn(Person::isAdmin) | |||||
.setEditorComponent(adminEditor, Person::setAdmin) | |||||
.setCaption("Default"); | |||||
grid.addColumn(Person::isStaff) | |||||
.setEditorComponent(staffEditor, Person::setAdmin) | |||||
.setCaption("Custom"); | |||||
grid.addColumn(Person::isSpecialist).setRenderer( | |||||
s -> "<input type=\"checkbox\" onclick=\"return false;\"" | |||||
+ (s ? "checked " : "") + ">", | |||||
new HtmlRenderer()).setCaption("HTML"); | |||||
grid.addColumn(Person::isSpecialist).setRenderer( | |||||
s -> "<span><input type=\"checkbox\" onclick=\"return false;\"" | |||||
+ (s ? "" : "checked ") + "></span>", | |||||
new HtmlRenderer()).setCaption("Spanned"); | |||||
grid.getEditor().setBuffered(false); | |||||
grid.getEditor().setEnabled(true); | |||||
grid.setItems(items); | |||||
addComponents(grid); | |||||
} | |||||
public class Person { | |||||
private boolean admin; | |||||
private boolean staff; | |||||
private boolean specialist; | |||||
public Person(boolean admin, boolean staff, boolean specialist) { | |||||
this.admin = admin; | |||||
this.staff = staff; | |||||
this.specialist = specialist; | |||||
} | |||||
public boolean isAdmin() { | |||||
return admin; | |||||
} | |||||
public void setAdmin(final boolean admin) { | |||||
this.admin = admin; | |||||
} | |||||
public boolean isStaff() { | |||||
return staff; | |||||
} | |||||
public void setStaff(final boolean staff) { | |||||
this.staff = staff; | |||||
} | |||||
public boolean isSpecialist() { | |||||
return specialist; | |||||
} | |||||
public void setSpecialist(final boolean specialist) { | |||||
this.specialist = specialist; | |||||
} | |||||
} | |||||
} |
package com.vaadin.tests.components.grid; | |||||
import static org.hamcrest.MatcherAssert.assertThat; | |||||
import static org.hamcrest.number.IsCloseTo.closeTo; | |||||
import static org.junit.Assert.assertEquals; | |||||
import java.util.List; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.By; | |||||
import org.openqa.selenium.WebElement; | |||||
import com.vaadin.testbench.elements.GridElement; | |||||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||||
public class GridEditorCheckBoxTest extends MultiBrowserTest { | |||||
@Test | |||||
public void testPositions() { | |||||
openTestURL(); | |||||
GridElement grid = $(GridElement.class).first(); | |||||
// open editor for second row | |||||
grid.getCell(1, 1).doubleClick(); | |||||
waitForElementPresent(By.className("v-grid-editor")); | |||||
// regular row cells | |||||
List<WebElement> rowCells = grid.getRow(0) | |||||
.findElements(By.className("v-grid-cell")); | |||||
// editor cells are divided in two groups, first one for frozen columns, | |||||
// second one for the rest | |||||
List<WebElement> editorCellGroups = grid | |||||
.findElements(By.className("v-grid-editor-cells")); | |||||
int column = 0; | |||||
for (WebElement editorCellGroup : editorCellGroups) { | |||||
// find the actual editor cells (no shared class name) | |||||
List<WebElement> editorCells = editorCellGroup | |||||
.findElements(By.xpath("./child::*")); | |||||
for (WebElement editorCell : editorCells) { | |||||
// find the margin within the editor row | |||||
List<WebElement> checkBoxElements = editorCell | |||||
.findElements(By.className("v-checkbox")); | |||||
WebElement editorInput; | |||||
if (checkBoxElements.isEmpty()) { | |||||
// use the actual input element for position check | |||||
editorInput = editorCell.findElement(By.tagName("input")); | |||||
} else { | |||||
// v-checkbox positions a fake input element | |||||
editorInput = checkBoxElements.get(0); | |||||
} | |||||
int editorMargin = editorInput.getLocation().getX() | |||||
- editorCell.getLocation().getX(); | |||||
// find the margin within the regular row | |||||
WebElement rowCell = rowCells.get(column); | |||||
int comparisonMargin; | |||||
if (column == 1 || column == 2) { | |||||
// these columns have text content on regular rows, margin | |||||
// is created with padding | |||||
String padding = rowCell.getCssValue("padding-left"); | |||||
comparisonMargin = Integer.valueOf( | |||||
padding.substring(0, padding.indexOf("px"))); | |||||
} else { | |||||
WebElement rowContent = rowCell | |||||
.findElement(By.tagName("input")); | |||||
comparisonMargin = rowContent.getLocation().getX() | |||||
- rowCell.getLocation().getX(); | |||||
} | |||||
// ensure that the editor input position matches the regular row | |||||
// content position | |||||
assertThat( | |||||
"Unexpected input location for column " + column | |||||
+ " editor", | |||||
(double) editorMargin, closeTo(comparisonMargin, 1d)); | |||||
++column; | |||||
} | |||||
} | |||||
assertEquals("Unexpect amount of checked columns,", 5, column); | |||||
} | |||||
} |