Bakery app V10.0.2 and V10.0.4 different view result

Hi guys,

not sure did i do anything wrong.
but changing the version with the same code cause this.

V10.0.2 combobox display the item correctly all the time but not the checkbox at all.

V10.0.4 combobox display the item correctly the 1st time only but the checkbox is correct.

package weiliang.ui.views.admin.users;

import com.vaadin.flow.component.combobox.ComboBox;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.vaadin.flow.component.HasText;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dependency.HtmlImport;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.component.textfield.PasswordField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.provider.DataProvider;
import com.vaadin.flow.data.provider.ListDataProvider;
import com.vaadin.flow.router.AfterNavigationEvent;
import com.vaadin.flow.router.AfterNavigationObserver;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.spring.annotation.SpringComponent;
import com.vaadin.flow.templatemodel.TemplateModel;
import weiliang.backend.data.Role;
import weiliang.backend.data.entity.User;
import weiliang.ui.components.FormButtonsBar;
import weiliang.ui.crud.CrudView.CrudForm;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.checkbox.Checkbox;

@Tag("user-form")
@HtmlImport("src/views/admin/users/user-form.html")
@SpringComponent
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserForm extends PolymerTemplate<TemplateModel>
		implements CrudForm<User>, BeforeEnterObserver, AfterNavigationObserver {

	@Id("title")
	private H3 title;

	@Id("buttons")
	private FormButtonsBar buttons;

	@Id("first")
	private TextField first;

	@Id("last")
	private TextField last;

	@Id("email")
	private TextField email;

	@Id("password")
	private PasswordField password;

	@Id("role")
	private ComboBox<String> role;

	private boolean edit = false;

	private final PasswordEncoder passwordEncoder;

	@Id("displayName")
	private TextField displayName;

	@Id("userName")
	private TextField userName;

	@Id("Tel")
	private TextField tel;

	@Id("Mobile")
	private TextField mobile;

	@Id("SignatureURL")
	private TextField signatureURL;

	@Id("jobTitle")
	private TextField jobTitle;

	@Id("locked")
	private Checkbox locked;

	@Id("actived")
	private Checkbox actived;

	@Autowired
	public UserForm(PasswordEncoder passwordEncoder) {

		this.passwordEncoder = passwordEncoder;
		/*
		 * editButton1.addClickListener(event -> { Notification.show("Active", 100 * 10,
		 * Notification.Position.MIDDLE);
		 * 
		 * if (edit) { edit = false; // test.setTitle("123"); } else { edit = true; } //
		 * locked.setValue(edit); // active.setValue(edit); // test.setEnabled(edit);
		 * });
		 * 
		 * locked.addValueChangeListener( e ->
		 * Notification.show(e.getValue().toString(), 100 * 10,
		 * Notification.Position.MIDDLE));
		 */
//		test.getElement().setAttribute("colspan", "3");
	}

	@Override
	public void setBinder(BeanValidationBinder<User> binder) {
		ListDataProvider<String> roleProvider = DataProvider.ofItems(Role.getAllRoles());
		role.setItemLabelGenerator(s -> s != null ? s : "");
		role.setDataProvider(roleProvider);

		binder.bind(first, "firstName");
		binder.bind(last, "lastName");
		binder.bind(email, "email");
		binder.bind(role, "role");
		binder.bind(displayName, "displayName");
		binder.bind(jobTitle, "title");
		binder.bind(userName, "userName");
		binder.bind(userName, "userName");
		binder.bind(tel, "phoneNumber");
		binder.bind(mobile, "mobileNumber");
		binder.bind(signatureURL, "signatureUrl");
		binder.bind(locked, "locked");
		binder.bind(actived, "active");

		/*
		 * binder.forField(password).withValidator(pass -> { return
		 * pass.matches("^(|(?=.*\\d)(?=.*[a-z]
)(?=.*[A-Z]
).{6,})$"); },
		 * "need 6 or more chars, mixing digits, lowercase and uppercase letters")
		 * .bind(user -> password.getEmptyValue(), (user, pass) -> { if
		 * (!password.getEmptyValue().equals(pass)) {
		 * user.setPasswordHash(passwordEncoder.encode(pass)); } });
		 */
		binder.forField(password).withValidator(pass -> {
			return pass.matches("^(|(?=.*\\d)(?=.*[a-z]
)(?=.*[A-Z]
).{6,})$");
		}, "need 6 or more chars, mixing digits, lowercase and uppercase letters").bind(User::getPasswordHash,
				(user, pass) -> {
					if (!password.getEmptyValue().equals(pass)) {
						user.setPasswordHash(passwordEncoder.encode(pass));
					}
				});
		/*
		 * binder.addValueChangeListener(e -> System.out .println("Event: " +
		 * e.toString())); role.addValueChangeListener(e -> System.out .println("Role: "
		 * + e.toString())); // binder.getBean().getRole()
		 * 
		 */
	}

	@Override
	public FormButtonsBar getButtons() {
		return buttons;
	}

	@Override
	public HasText getTitle() {
		return title;
	}

	@Override
	public void afterNavigation(AfterNavigationEvent event) {
//		System.out.println("Inside after Navigation for user form");
//		Notification.show("Inside after Navigation for user form", 30 * 10, Notification.Position.MIDDLE);
//		email.setEnabled(false);
//		System.out.println("Setting email to true");
//		last.setEnabled(false);
	}

	@Override
	public void beforeEnter(BeforeEnterEvent event) {
		try {
			System.out.println("Inside before enter event for user form");
			Notification.show("Inside before enter event for user form ", 30 * 10, Notification.Position.MIDDLE);
//			email.setEnabled(false);
			System.out.println("Setting email to true");
//			last.setEnabled(false);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public void disableComponents(String roles) {
		System.out.println("inside disableComponets, userRole: " + roles);
//		 test.setEnabled(false);
//		 last.setEnabled(false);
//		Notification.show("Inside disableComponents for user form" + this.role.getValue(), 600 * 10,
//				Notification.Position.MIDDLE);

		if (roles.compareToIgnoreCase(Role.ADMIN) == 0) {
//			 email.setEnabled(false);
			System.out.println("this person is a admin");
		} else {
//			locked.setEnabled(false);
		}
//		locked.setValue(true);
//		active.setValue(true);
//		active.setEnabled(false);

	}

	public boolean getEdit() {
		return edit;
	}

	public void setEdit(boolean edit) {
		this.edit = edit;
	}

}

package weiliang.backend.data.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Entity(name = "UserInfo")
public class User extends AbstractEntity {

	@NotEmpty
	@Email
	@Size(max = 255, message = "max 255 characters")
	@Column(unique = true)
	private String email;

	@NotNull
	@Size(min = 2, max = 255, message = "About Me must be between 2 and 255 characters")
	private String passwordHash;

	@NotBlank
	@Size(max = 255, message = "max 255 characters")
	private String firstName;

	@NotBlank
	@Size(max = 255, message = "max 255 characters")
	private String lastName;

	@NotBlank
	@Size(max = 255, message = "max 255 characters")
	private String role;

	@Size(max = 2083)
	private String photoUrl;

	@NotBlank
	@Size(max = 255, message = "max 255 characters")
	private String displayName;

	@Size(max = 255, message = "max 255 characters")
	private String title;

	@NotBlank
	@Size(max = 255, message = "max 255 characters")
	@Column(unique = true)
	private String userName;

//	@NotBlank
	@Size(min = 8, max = 20, message = "{bakery.phone.number.invalid}")
	// A simple phone number checker, allowing an optional international prefix
	// plus a variable number of digits that could be separated by dashes or
	// spaces
//	@Pattern(regexp = "^(\\+\\d+)?([ -]
?\\d+){4,14}$", message = "{bakery.phone.number.invalid}")
	private String phoneNumber;

	@NotBlank
	@Size(min = 8, max = 20, message = "{bakery.phone.number.invalid}")
	// A simple phone number checker, allowing an optional international prefix
	// plus a variable number of digits that could be separated by dashes or
	// spaces
//	@Pattern(regexp = "^(\\+\\d+)?([ -]
?\\d+){4,14}$", message = "{bakery.phone.number.invalid}")
	private String mobileNumber;

	@Size(max = 2083)
	private String signatureUrl;

	private boolean locked = false;

	@NotNull
	private boolean active = false;

	@PrePersist
	@PreUpdate
	private void prepareData() {
		this.email = email == null ? null : email.toLowerCase();
	}

	public User() {
		// An empty constructor is needed for all beans
	}

	public String getPasswordHash() {
		return passwordHash;
	}

	public void setPasswordHash(String passwordHash) {
		this.passwordHash = passwordHash;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getRole() {
		System.out.println("getting role: " + role);
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhotoUrl() {
		return photoUrl;
	}

	public void setPhotoUrl(String photoUrl) {
		this.photoUrl = photoUrl;
	}

	public boolean isLocked() {
		return locked;
	}

	public boolean getLocked() {
		return locked;
	}

	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public boolean getActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getMobileNumber() {
		return mobileNumber;
	}

	public void setMobileNumber(String mobileNumber) {
		this.mobileNumber = mobileNumber;
	}

	public String getSignatureUrl() {
		return signatureUrl;
	}

	public void setSignatureUrl(String signatureUrl) {
		this.signatureUrl = signatureUrl;
	}
}

17247285.png
17247288.png
17247291.png
17247294.png
17247297.png

Hi.

The combobox behavior is a known issue in V10.0.4: https://github.com/vaadin/vaadin-combo-box-flow/issues/118

It’s now fixed in V10.0.5.

Hi Tulio ,yes it is solved!