blob: 85c3c6652019a689f209f75ad600ea41514ec344 [file] [log] [blame]
// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry5.corelib.components;
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.internal.beaneditor.BeanModelUtils;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.BeanModelSource;
import org.apache.tapestry5.services.ComponentDefaultProvider;
/**
* A component that creates an entire form editing the properties of a particular bean. Inspired by <a
* href="http://www.trailsframework.org/">Trails</a> and <a href="http://beanform.sourceforge.net/">BeanForm</a> (both
* for Tapestry 4). Generates a simple UI for editing the properties of a JavaBean, with the flavor of UI for each
* property (text field, checkbox, drop down list) determined from the property type, and the order and validation for
* the properties determined from annotations on the property's getter and setter methods.
* <p/>
* You may add &lt;t:parameter&gt;s to the component; when the name matches (case insensitive) the name of a property,
* then the corresponding Block is renderered, rather than any of the built in property editor blocks. This allows you
* to override specific properties with your own customized UI, for cases where the default UI is insufficient, or no
* built-in editor type is appropriate.
*
* @see BeanModel
* @see BeanModelSource
* @see PropertyEditor
*/
@SupportsInformalParameters
public class BeanEditForm implements ClientElement, FormValidationControl
{
/**
* The text label for the submit button of the form, by default "Create/Update".
*/
@Parameter(value = "message:submit-label", defaultPrefix = BindingConstants.LITERAL)
@Property
private String submitLabel;
/**
* The object to be edited. This will be read when the component renders and updated when the form for the component
* is submitted. Typically, the container will listen for a "prepare" event, in order to ensure that a non-null
* value is ready to be read or updated. Often, the BeanEditForm can create the object as needed (assuming a public,
* no arguments constructor). The object property defaults to a property with the same name as the component id.
*/
@SuppressWarnings("unused")
@Parameter(required = true)
@Property
private Object object;
/**
* A comma-separated list of property names to be retained from the {@link org.apache.tapestry5.beaneditor.BeanModel}.
* Only these properties will be retained, and the properties will also be reordered. The names are
* case-insensitive.
*/
@SuppressWarnings("unused")
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String include;
/**
* A comma-separated list of property names to be removed from the {@link org.apache.tapestry5.beaneditor.BeanModel}.
* The names are case-insensitive.
*/
@SuppressWarnings("unused")
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String exclude;
/**
* A comma-separated list of property names indicating the order in which the properties should be presented. The
* names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
* order.
*/
@SuppressWarnings("unused")
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String reorder;
/**
* If true, the default, then the embedded Form component will use client-side validation.
*/
@Parameter
private boolean clientValidation = true;
/**
* Binding the zone parameter will cause the form submission to be handled as an Ajax request that updates the
* indicated zone. Often a BeanEditForm will update the same zone that contains it.
*/
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String zone;
@Component(parameters = { "clientValidation=inherit:clientValidation", "zone=inherit:zone" })
private Form form;
/**
* The model that identifies the parameters to be edited, their order, and every other aspect. If not specified, a
* default bean model will be created from the type of the object bound to the object parameter.
*/
@SuppressWarnings("unused")
@Parameter
@Property
private BeanModel model;
@Inject
private ComponentDefaultProvider defaultProvider;
@Inject
private ComponentResources resources;
@Inject
private BeanModelSource beanModelSource;
/**
* Defaults the object parameter to a property of the container matching the BeanEditForm's id.
*/
Binding defaultObject()
{
return defaultProvider.defaultBinding("object", resources);
}
void onPrepareFromForm()
{
resources.triggerEvent(Form.PREPARE, null, null);
if (model == null)
{
Class beanType = resources.getBoundType("object");
model = beanModelSource.create(beanType, true, resources.getContainerResources());
}
BeanModelUtils.modify(model, null, include, exclude, reorder);
}
/**
* Returns the client id of the embedded form.
*/
public String getClientId()
{
return form.getClientId();
}
public void clearErrors()
{
form.clearErrors();
}
public boolean getHasErrors()
{
return form.getHasErrors();
}
public boolean isValid()
{
return form.isValid();
}
public void recordError(Field field, String errorMessage)
{
form.recordError(field, errorMessage);
}
public void recordError(String errorMessage)
{
form.recordError(errorMessage);
}
}