diff options
Diffstat (limited to 'documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc')
-rw-r--r-- | documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc b/documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc new file mode 100644 index 0000000000..f8b6eebac3 --- /dev/null +++ b/documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc @@ -0,0 +1,162 @@ +--- +title: Automatic Form Generation +order: 8 +layout: page +--- + +[[jpacontainer.fieldfactory]] += Automatic Form Generation + +The JPAContainer [classname]#FieldFactory# is an implementation of the +[interfacename]#FormFieldFactory# and [interfacename]#TableFieldFactory# +interfaces that can generate fields based on JPA annotations in a POJO. It goes +further than the [classname]#DefaultFieldFactory#, which only creates simple +fields for the basic data types. This way, you can easily create forms to input +entities or enable editing in tables. + +The generated defaults are as follows: + +[options="header"] +|=============== +|Annotation|Class Mapping +|[literal]#++@ManyToOne++#|[classname]#NativeSelect# +|[literal]#++@OneToOne++#, [literal]#++@Embedded++#|Nested [classname]#Form# +|[literal]#++@OneToMany++#, [literal]#++@ElementCollection++#|[classname]#MasterDetailEditor# (see below) +|[literal]#++@ManyToMany++#|Selectable [classname]#Table# + +|=============== + + + +The field factory is recusive, so that you can edit a complex object tree with +one form. + +[[jpacontainer.fieldfactory.configuring]] +== Configuring the Field Factory + +The [classname]#FieldFactory# is highly configurable with various configuration +settings and by +extending.//// +You need to make the configuration +before +//// + +The [methodname]#setMultiSelectType()# and [methodname]#setSingleSelectType()# +allow you to specify a selection component that is used instead of the default +for a field with [literal]#++@ManyToMany++# and [literal]#++@ManyToOne++# +annotation, respectively. The first parameter is the class type of the field, +and the second parameter is the class type of a selection component. It must be +a sub-class of [classname]#AbstractSelect#. + +The [methodname]#setVisibleProperties()# controls which properties (fields) are +visible in generated forms, subforms, and tables. The first paramater is the +class type for which the setting should be made, followed by the IDs of the +visible properties. + +The configuration should be done before binding the form to a data source as +that is when the field generation is done. + +Further configuration must be done by extending the many protected methods. +Please see the API documentation for the complete list. + + +[[jpacontainer.fieldfactory.using]] +== Using the Field Factory + +The most basic use case for the JPAContainer [classname]#FieldFactory# is with a +[classname]#Form# bound to a container item: + + +---- +// Have a persistent container +final JPAContainer<Country> countries = + JPAContainerFactory.make(Country.class, "book-examples"); + +// For selecting an item to edit +final ComboBox countrySelect = + new ComboBox("Select a Country", countries); +countrySelect.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY); +countrySelect.setItemCaptionPropertyId("name"); + +// Country Editor +final Form countryForm = new Form(); +countryForm.setCaption("Country Editor"); +countryForm.addStyleName("bordered"); // Custom style +countryForm.setWidth("420px"); +countryForm.setBuffered(true); +countryForm.setEnabled(false); + +// When an item is selected from the list... +countrySelect.addValueChangeListener(new ValueChangeListener(){ + @Override + public void valueChange(ValueChangeEvent event) { + // Get the item to edit in the form + Item countryItem = + countries.getItem(event.getProperty().getValue()); + + // Use a JPAContainer field factory + // - no configuration is needed here + final FieldFactory fieldFactory = new FieldFactory(); + countryForm.setFormFieldFactory(fieldFactory); + + // Edit the item in the form + countryForm.setItemDataSource(countryItem); + countryForm.setEnabled(true); + + // Handle saves on the form + final Button save = new Button("Save"); + countryForm.getFooter().removeAllComponents(); + countryForm.getFooter().addComponent(save); + save.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + try { + countryForm.commit(); + countryForm.setEnabled(false); + } catch (InvalidValueException e) { + } + } + }); + } +}); +countrySelect.setImmediate(true); +countrySelect.setNullSelectionAllowed(false); +---- +See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.fieldfactory.formonetoone[on-line example, window="_blank"]. + +This would create a form shown in <<figure.jpacontainer.fieldfactory.using>>. + +[[figure.jpacontainer.fieldfactory.using]] +.Using FieldFactory with One-to-Many Relationship +image::img/fieldfactory-form.png[] + +If you use Hibernate, you also need to pass an +[classname]#EntityManagerPerRequestHelper#, either for the constructor or with +[methodname]#setEntityManagerPerRequestHelper()# +ifdef::web[] +, as described in +<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.em-per-request,"The +EntityManager-Per-Request +pattern">> +endif::web[] +. + + +[[jpacontainer.fieldfactory.masterdetaileditor]] +== Master-Detail Editor + +The [classname]#MasterDetailEditor# is a field component that allows editing an +item property that has one-to-many relationship. The item can be a row in a +table or bound to a form. It displays the referenced collection as an editable +[classname]#Table# and allows adding and removing items in it. + +You can use the [classname]#MasterDetailEditor# manually, or perhaps more +commonly use a JPAContainer [classname]#FieldFactory# to create it +automatically. As shown in the example in +<<figure.jpacontainer.fieldfactory.using>>, the factory creates a +[classname]#MasterDetailEditor# for all properties with a +[literal]#++@OneToMany++# or an [literal]#++@ElementCollection++# annotation. + + + + |