package org.vaadin.jefferson.demo.addressbook.content; import java.util.Arrays; import java.util.List; import org.vaadin.jefferson.Presentation; import org.vaadin.jefferson.View; import org.vaadin.jefferson.demo.addressbook.domain.Person; import org.vaadin.jefferson.demo.addressbook.domain.PersonContainer; import com.vaadin.data.Item; import com.vaadin.data.util.BeanItem; import com.vaadin.data.validator.EmailValidator; import com.vaadin.data.validator.RegexpValidator; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.DefaultFieldFactory; import com.vaadin.ui.Field; import com.vaadin.ui.Form; import com.vaadin.ui.Layout; import com.vaadin.ui.TextField; @SuppressWarnings("serial") public class PersonForm extends View<Form> implements ClickListener { private Button save = new Button("Save", this); private Button cancel = new Button("Cancel", this); private Button edit = new Button("Edit", this); private final ComboBox cities = new ComboBox("City"); private boolean newContactMode = false; private Person newPerson = null; private PersonContainer dataSource; public PersonForm(AddressBookView root) { super("Person form", Form.class); dataSource = root.getDataSource(); } @Override public Form createFallback() { return new Form(); } @Override protected Form accept(Presentation presentation) { Form rendition = super.accept(presentation); /* * Enable buffering so that commit() must be called for the form before * input is written to the data. (Form input is not written immediately * through to the underlying object.) */ rendition.setWriteThrough(false); Layout footer = rendition.getFooter(); footer.addComponent(save); footer.addComponent(cancel); footer.addComponent(edit); footer.setVisible(false); /* Allow the user to enter new cities */ cities.setNewItemsAllowed(true); /* We do not want to use null values */ cities.setNullSelectionAllowed(false); /* Add an empty city used for selecting no city */ cities.addItem(""); /* Populate cities select using the cities in the data container */ PersonContainer ds = dataSource; for (Person person : ds.getItemIds()) { String city = person.getCity(); cities.addItem(city); } /* * Field factory for overriding how the component for city selection is * created */ rendition.setFormFieldFactory(new DefaultFieldFactory() { @Override public Field createField(Item item, Object propertyId, Component uiContext) { if (propertyId.equals("city")) { cities.setWidth("200px"); return cities; } Field field = super.createField(item, propertyId, uiContext); if (propertyId.equals("postalCode")) { TextField tf = (TextField) field; /* * We do not want to display "null" to the user when the * field is empty */ tf.setNullRepresentation(""); /* Add a validator for postalCode and make it required */ tf.addValidator(new RegexpValidator("[1-9][0-9]{4}", "Postal code must be a five digit number and cannot start with a zero.")); tf.setRequired(true); } else if (propertyId.equals("email")) { /* Add a validator for email and make it required */ field.addValidator(new EmailValidator( "Email must contain '@' and have full domain.")); field.setRequired(true); } field.setWidth("200px"); return field; } }); return rendition; } public void buttonClick(ClickEvent event) { Button source = event.getButton(); Form form = getRendition(); if (source == save) { /* If the given input is not valid there is no point in continuing */ if (!form.isValid()) { return; } form.commit(); if (newContactMode) { /* We need to add the new person to the container */ Item addedItem = dataSource.addItem(newPerson); /* * We must update the form to use the Item from our datasource * as we are now in edit mode (no longer in add mode) */ setDataSource(addedItem); newContactMode = false; } setReadOnly(true); } else if (source == cancel) { if (newContactMode) { newContactMode = false; /* Clear the form and make it invisible */ setDataSource(null); } else { form.discard(); } setReadOnly(true); } else if (source == edit) { setReadOnly(false); } } protected void setDataSource(Item newDataSource) { newContactMode = false; Form form = getRendition(); if (newDataSource != null) { List<String> orderedProperties = Arrays.asList( PersonContainer.NATURAL_COL_ORDER); form.setItemDataSource(newDataSource, orderedProperties); setReadOnly(true); form.getFooter().setVisible(true); } else { form.setItemDataSource(null); form.getFooter().setVisible(false); } } private void setReadOnly(boolean readOnly) { getRendition().setReadOnly(readOnly); save.setVisible(!readOnly); cancel.setVisible(!readOnly); edit.setVisible(readOnly); } protected void addContact() { // Create a temporary item for the form newPerson = new Person(); setDataSource(new BeanItem<Person>(newPerson)); newContactMode = true; setReadOnly(false); } }