Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Commit

Permalink
Disable client side validation on setRequiredIndicatorVisible (#202) (F…
Browse files Browse the repository at this point in the history
…ixes #179)
  • Loading branch information
Denis authored and ujoni committed Feb 11, 2019
1 parent b286c5b commit b950974
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 4 deletions.
11 changes: 10 additions & 1 deletion src/main/java/com/vaadin/flow/component/combobox/ComboBox.java
Expand Up @@ -49,6 +49,7 @@
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.internal.JsonUtils;
import com.vaadin.flow.shared.Registration;

import elemental.json.Json;
import elemental.json.JsonObject;
import elemental.json.JsonValue;
Expand Down Expand Up @@ -196,7 +197,8 @@ public interface ItemFilter<T> extends SerializableBiPredicate<T, String> {
private boolean renderScheduled;

// Filter set by the client when requesting data. It's sent back to client
// together with the response so client may know for what filter data is provided.
// together with the response so client may know for what filter data is
// provided.
private String lastFilter;

private DataCommunicator<T> dataCommunicator;
Expand Down Expand Up @@ -878,6 +880,13 @@ public Registration addCustomValueSetListener(
return new CustomValueRegistration(registration);
}

@Override
public void setRequiredIndicatorVisible(boolean requiredIndicatorVisible) {
super.setRequiredIndicatorVisible(requiredIndicatorVisible);
getElement().callFunction("$connector.enableClientValidation",
!requiredIndicatorVisible);
}

CompositeDataGenerator<T> getDataGenerator() {
return dataGenerator;
}
Expand Down
Expand Up @@ -162,6 +162,61 @@ window.Vaadin.Flow.comboBoxConnector = {
// Let server know we're done
comboBox.$server.confirmUpdate(id);
}

comboBox.$connector.enableClientValidation = function( enable ){
let input = comboBox.$["input"];
if (input){
if ( enable){
enableClientValidation(comboBox);
enableTextFieldClientValidation(input);
}
else {
disableClientValidation(comboBox);
disableTextFieldClientValidation(input,comboBox );
}
}
else {
setTimeout( function(){
comboBox.$connector.enableClientValidation(enable);
}, 10);
}
}

const disableClientValidation = function (combo){
if ( typeof combo.$checkValidity == 'undefined'){
combo.$checkValidity = combo.checkValidity;
combo.checkValidity = function() { return true; };
}
if ( typeof combo.$validate == 'undefined'){
combo.$validate = combo.validate;
combo.validate = function() { return true; };
}
}

const disableTextFieldClientValidation = function (field, comboBox){
if ( typeof field.$checkValidity == 'undefined'){
field.$checkValidity = field.checkValidity;
field.checkValidity = function() { return !comboBox.invalid; };
}
}

const enableTextFieldClientValidation = function (field){
if ( field.$checkValidity ){
field.checkValidity = field.$checkValidity;
delete field.$checkValidity;
}
}

const enableClientValidation = function (combo){
if ( combo.$checkValidity ){
combo.checkValidity = combo.$checkValidity;
delete combo.$checkValidity;
}
if ( combo.$validate ){
combo.validate = combo.$validate;
delete combo.$validate;
}
}

const commitPage = function (page, callback) {
let data = cache[page];
Expand Down
Expand Up @@ -21,13 +21,15 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import org.junit.Assert;
import org.junit.Ignore;
import org.openqa.selenium.WebElement;

import com.vaadin.flow.component.combobox.testbench.ComboBoxElement;
import com.vaadin.flow.testutil.AbstractComponentIT;
import com.vaadin.testbench.TestBenchElement;

import elemental.json.JsonObject;
import org.junit.Assert;
import org.junit.Ignore;
import org.openqa.selenium.WebElement;

@Ignore
public class AbstractComboBoxIT extends AbstractComponentIT {
Expand Down
@@ -0,0 +1,78 @@
/*
* Copyright 2000-2018 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.flow.component.combobox.test;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.flow.component.combobox.testbench.ComboBoxElement;
import com.vaadin.flow.testutil.AbstractComponentIT;
import com.vaadin.flow.testutil.TestPath;
import com.vaadin.testbench.TestBenchElement;

@TestPath("required-combobox")
public class RequiredComboboxIT extends AbstractComponentIT {

@Test
public void serverSideValidation_persistsOnBlur() {
open();

ComboBoxElement comboBox = $(ComboBoxElement.class).first();

// Select an invalid item
comboBox.openPopup();
executeScript(
"arguments[0].selectedItem = arguments[0].filteredItems[0]",
comboBox);

// The validation shows errors
assertValidationError(comboBox);

TestBenchElement msg = $(TestBenchElement.class).id("message");
Assert.assertEquals("Value changed from 'null' to 'foo'",
msg.getText());

// blur
msg.click();

// validation error is still shown
assertValidationError(comboBox);

// change the item to a valid one
comboBox.openPopup();
executeScript(
"arguments[0].selectedItem = arguments[0].filteredItems[1]",
comboBox);

// no invalid attribute
Assert.assertEquals(Boolean.FALSE.toString(),
comboBox.getAttribute("invalid"));
// the error message is not visible
TestBenchElement error = comboBox.$("vaadin-text-field").first()
.$(TestBenchElement.class).id("vaadin-text-field-error-0");
waitUntil(driver -> error.getSize().getHeight() == 0);
}

private void assertValidationError(ComboBoxElement comboBox) {
Assert.assertEquals(Boolean.TRUE.toString(),
comboBox.getAttribute("invalid"));

TestBenchElement error = comboBox.$("vaadin-text-field").first()
.$(TestBenchElement.class).id("vaadin-text-field-error-0");
Assert.assertTrue(error.getSize().getHeight() > 0);
Assert.assertEquals("'foo' is invalid value", error.getText());
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2018 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.flow.component.combobox.test;

import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.combobox.bean.TestItem;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;

@Route("required-combobox")
public class RequiredComboboxPage extends Div {

public RequiredComboboxPage() {
Div message = new Div();
message.setId("message");

Binder<TestItem> binder = new Binder<>();

ComboBox<String> comboBox = new ComboBox<>();
comboBox.setItems("foo", "bar");
comboBox.addValueChangeListener(event -> message
.setText(String.format("Value changed from '%s' to '%s'",
event.getOldValue(), event.getValue())));

binder.forField(comboBox).asRequired()
.withValidator(value -> !"foo".equals(value),
"'foo' is invalid value")
.bind(TestItem::getName, TestItem::setName);
TestItem item = new TestItem(0);
binder.setBean(item);

add(comboBox, message);
}
}

0 comments on commit b950974

Please sign in to comment.