This is my another post in learning my Vaadin journey through Holon Platform. There is already an example here https://vaadin.com/learn/tutorials/dynamic-web-forms-with-validation-in-java explaining the concepts but I just want to mimic the same so that I can learn more about the Holon Platform APIs myself.
Here is the simplified code for the Dynamic WebForm example of SnackOrder
import com.holonplatform.core.property.PropertyBox; import com.holonplatform.vaadin.flow.components.Components; import com.holonplatform.vaadin.flow.components.PropertyInputForm; import com.holonplatform.vaadin.flow.components.PropertyListing; import com.holonplatform.vaadin.flow.components.SingleSelect; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.router.Route; import java.util.*; @Route("Snack") public class SnackOrderView extends VerticalLayout { private PropertyInputForm inputForm; private PropertyListing listing; public SnackOrderView() { initialize(); } private void initialize() { Map<String, List<String>> snacks = new HashMap<>(); snacks.put("Fruits", Arrays.asList("Banana", "Apple", "Orange", "Avocado")); snacks.put("Candy", Arrays.asList("Chocolate bar", "Gummy bears", "Granola bar")); snacks.put("Drinks", Arrays.asList("Soda", "Water", "Coffee", "Tea")); List<PropertyBox> snackOrders = new ArrayList<>(); ListDataProvider<PropertyBox> gridDataProvider = new ListDataProvider<>(snackOrders); Button orderBtn = Components.button() .text("Order") .withThemeName("primary") .enabled(false) .onClick(event -> { snackOrders.add(inputForm.getValue()); listing.refresh(); }) .build(); SingleSelect<String> snackSelect = Components.input.singleSelect(String.class) .required() .enabled(false) .withValueChangeListener(event -> { orderBtn.setEnabled(true); }) .build(); SingleSelect<String> snackTypeSelect = Components.input.singleSelect(String.class) .required() .items(snacks.keySet()) .withValueChangeListener(event -> { ((ComboBox<String>) snackSelect.getComponent()).setItems(snacks.get(event.getValue())); ((ComboBox<String>) snackSelect.getComponent()).setEnabled(true); }) .build(); HorizontalLayout hl = Components.hl().build(); inputForm = Components.input.form(hl, SnackOrder.PROPERTY_SET) .composer((content, source) -> { source.getComponents().forEach(component -> { content.add(component); }); content.add(orderBtn); }) .bind(SnackOrder.TYPE, snackTypeSelect) .bind(SnackOrder.SNACK, snackSelect) .initializer(content -> { content.setSpacing(true); content.setDefaultVerticalComponentAlignment(Alignment.BASELINE); }) .withValueChangeListener(event -> { orderBtn.setEnabled(inputForm.isValid()); }) .build(); listing = Components.listing.properties(SnackOrder.PROPERTY_SET) .dataSource(gridDataProvider) .build(); add(inputForm.getComponent(), listing.getComponent()); } }
Here is the screenprint showing the neat and simple web form
