package app.views.personform; import app.data.entity.SamplePerson; import app.data.service.SamplePersonService; import app.views.main.MainView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.customfield.CustomField; import com.vaadin.flow.component.datepicker.DatePicker; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.H3; import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.textfield.EmailField; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; @CssImport("app/views/personform/person-form-view.css") @Route(value = "person-form", layout = MainView.class) @PageTitle("Person Form") public class PersonFormView extends Div { private TextField firstName = new TextField("First name"); private TextField lastName = new TextField("Last name"); private EmailField email = new EmailField("Email address"); private DatePicker dateOfBirth = new DatePicker("Birthday"); private PhoneNumberField phone = new PhoneNumberField("Phone number"); private TextField occupation = new TextField("Occupation"); private Button cancel = new Button("Cancel"); private Button save = new Button("Save"); private Binder binder = new Binder<>(SamplePerson.class); public PersonFormView(SamplePersonService personService) { addClassName("person-form-view"); add(createTitle()); add(createFormLayout()); add(createButtonLayout()); binder.bindInstanceFields(this); clearForm(); cancel.addClickListener(e -> clearForm()); save.addClickListener(e -> { personService.update(binder.getBean()); Notification.show(binder.getBean().getClass().getSimpleName() + " details stored."); clearForm(); }); } private void clearForm() { binder.setBean(new SamplePerson()); } private Component createTitle() { return new H3("Personal information"); } private Component createFormLayout() { FormLayout formLayout = new FormLayout(); email.setErrorMessage("Please enter a valid email address"); formLayout.add(firstName, lastName, dateOfBirth, phone, email, occupation); return formLayout; } private Component createButtonLayout() { HorizontalLayout buttonLayout = new HorizontalLayout(); buttonLayout.addClassName("button-layout"); save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); buttonLayout.add(save); buttonLayout.add(cancel); return buttonLayout; } private static class PhoneNumberField extends CustomField { private ComboBox countryCode = new ComboBox<>(); private TextField number = new TextField(); public PhoneNumberField(String label) { setLabel(label); countryCode.setWidth("120px"); countryCode.setPlaceholder("Country"); countryCode.setPattern("\\+\\d*"); countryCode.setPreventInvalidInput(true); countryCode.setItems("+354", "+91", "+62", "+98", "+964", "+353", "+44", "+972", "+39", "+225"); countryCode.addCustomValueSetListener(e -> countryCode.setValue(e.getDetail())); number.setPattern("\\d*"); number.setPreventInvalidInput(true); HorizontalLayout layout = new HorizontalLayout(countryCode, number); layout.setFlexGrow(1.0, number); add(layout); } @Override protected String generateModelValue() { if (countryCode.getValue() != null && number.getValue() != null) { return countryCode.getValue() + " " + number.getValue(); } return ""; } @Override protected void setPresentationValue(String phoneNumber) { String[] parts = phoneNumber != null ? phoneNumber.split(" ", 2) : new String[0]; if (parts.length == 1) { countryCode.clear(); number.setValue(parts[0]); } else if (parts.length == 2) { countryCode.setValue(parts[0]); number.setValue(parts[1]); } else { countryCode.clear(); number.clear(); } } } }