package pt.ist.renderers.extensions; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import pt.ist.fenixframework.DomainObject; import pt.ist.renderers.OutputRenderer; import pt.ist.renderers.components.HtmlBlockContainer; import pt.ist.renderers.components.HtmlComponent; import pt.ist.renderers.components.HtmlContainer; import pt.ist.renderers.components.HtmlImage; import pt.ist.renderers.components.HtmlInlineContainer; import pt.ist.renderers.components.HtmlLink; import pt.ist.renderers.components.HtmlList; import pt.ist.renderers.components.HtmlListItem; import pt.ist.renderers.components.HtmlScript; import pt.ist.renderers.components.HtmlStyle; import pt.ist.renderers.components.HtmlText; import pt.ist.renderers.layouts.Layout; import pt.ist.renderers.schemas.Schema; import pt.ist.renderers.utils.RenderKit; import pt.ist.renderers.utils.RenderUtils; import pt.ist.renderers.utils.RendererPropertyUtils; /** * This renderer is a generic renderer that can be used to display simple list or tree views. * The usual way of using this renderer includes the configuration of the presentation of * each item and the indication of how to get the children of each item. Additionaliy you * can specify control link that target each item. * *
* The TreeRenderer also offers the possibility to include images in each items * and make the tree draggable using javascript. If you need a draggable tree then you * must choose a {@link #setTreeId(String) treeId} and a {@link #setFieldId(String) fieldId} * or a{@link #setSaveUrl(String) saveUrl}. * *
* You can also configure the style and class of several elements in the tree. You must * give special attention to the class you choose for the list items because when the tree * is draggable those classes have a special meaning. * *
* Example: *
* The given identifier can be used in javascript to invoke operations in the tree. * The most important are: * *
* Note that the form containing the field will be automatically submitted. So you * can have a form somewere in the page that looks like: * *
* <form action="/someAction.do"> * <input id="myFieldId" type="hidden" name="tree" value=""/> * </form> ** * @property */ public void setFieldId(String fieldId) { this.fieldId = fieldId; } public String getSaveUrl() { return this.saveUrl; } /** * This property is similar to {@link #setFieldId(String) fieldId}, that is, is also * specifies that you want a draggable tree. Nevertheless when you specify this propert * instead of the {@link #setFieldId(String) fieldId} the tree is saved is asynchronous * way to the server to the url indicated in this property. * * @see #setOnComplete(String) * @see #setOnError(String) * @see #setSaveParameter(String) * @see #setModuleRelative(boolean) * * @property */ public void setSaveUrl(String saveUrl) { this.saveUrl = saveUrl; } public boolean isModuleRelative() { return this.moduleRelative; } /** * This property indicates if the saveUrl is relative to the current module. * This property is
true
by default.
*
* @property
*/
public void setModuleRelative(boolean moduleRelative) {
this.moduleRelative = moduleRelative;
}
public String getSaveParameter() {
return this.saveParameter;
}
/**
* When the tree is saved in an asynchronous way this property chooses the name of the
* parameter that will contain the tree structure.
*
* @property
*/
public void setSaveParameter(String saveParameter) {
this.saveParameter = saveParameter;
}
public String getOnComplete() {
return this.onComplete;
}
/**
* This property specifies the javascript function to be executed when the tree structure
* is saved correctly, that is, submited without protocol errors to the server. You
* can specify an anonymous function like function() { alert('complete'); }
*
* @property
*/
public void setOnComplete(String onComplete) {
this.onComplete = onComplete;
}
public String getOnError() {
return this.onError;
}
/**
* This property specifies the javascript function to be executed when the tree structure
* cannot be saved correctly, that is, some error is reported by the server. You
* can specify an anonymous function like function() { alert('failed'); }
*
* @property
*/
public void setOnError(String onError) {
this.onError = onError;
}
public String getListClass() {
return this.listClass;
}
/**
* Chooses the html classes to apply to each list.
*
* @property
*/
public void setListClass(String listClass) {
this.listClass = listClass;
}
public String getListStyle() {
return this.listStyle;
}
/**
* Chooses the style to apply to each each list.
*
* @property
*/
public void setListStyle(String listStyle) {
this.listStyle = listStyle;
}
public String getItemClass() {
return this.itemClass;
}
/**
* The html classes to apply to each list item.
*
*
* Note: if the tree is draggable this class has a special
* meaning. If you don't specify images for the items this property will be
* used to determine the image that will be used for the item. Currently only the
* "folder" and "sheet" classes are supported. So, you you specify the list
* item class it's also a good idea to override the image for each item.
*
* @see #setImageFor(String, String)
*
* @property
*/
public void setItemClass(String itemClass) {
this.itemClass = itemClass;
}
public String getItemStyle() {
return this.itemStyle;
}
/**
* The css style for each list item.
*
* @property
*/
public void setItemStyle(String itemStyle) {
this.itemStyle = itemStyle;
}
public String getClassesFor(String type) {
return this.classesMap.get(type);
}
/**
* The css classes to be used in items corresponding to objects of the specified type.
*
* @property
*/
public void setClassesFor(String type, String method) {
this.classesMap.put(type, method);
}
public String getLinks() {
return this.links;
}
/**
* Specifies the default link text to be included near each item. The text will be passed
* through {@link RenderUtils#getFormattedProperties(String, Object)} with the object of the
* item. This way you can include references the object's properties in the text.
*
* @property
*/
public void setLinks(String links) {
this.links = links;
}
public String getHiddenLinks() {
return hiddenLinks;
}
/**
* This property is similar to the {@link #setLinks(String) links} property but the links
* defined with this property will be hidden when the tree is draggable. This property is
* usefull to specify links that simulate the same actions available by drag and drop.
*
* @property
*/
public void setHiddenLinks(String hiddenlinks) {
this.hiddenLinks = hiddenlinks;
}
public String getLinksFor(String type) {
return this.linksMap.get(type);
}
/**
* Specifies the links that should appear near items corresponding to objects of the
* given type. The link text is replaced in the same way than {@link #setLinks(String)}.
*
* @property
*/
public void setLinksFor(String type, String method) {
this.linksMap.put(type, method);
}
public String getHiddenLinksFor(String type) {
return this.hiddenLinksMap.get(type);
}
/**
* Specifies the hidden links that should appear near items corresponding to objects of the
* given type. The link text is replaced in the same way than {@link #setHiddenLinks(String)}.
*
* @property
*/
public void setHiddenLinksFor(String type, String method) {
this.hiddenLinksMap.put(type, method);
}
public String getLinksClasses() {
return this.linksClasses;
}
/**
* Chooses the css classes to apply to the container surrounding the item's links.
* If this property is not set a default class, based on the tree id, is applied.
*
* @property
*/
public void setLinksClasses(String linksClass) {
this.linksClasses = linksClass;
}
public String getLinksStyle() {
return this.linksStyle;
}
/**
* Chooses the css style to apply to each item's links.
*
* @property
*/
public void setLinksStyle(String linksStyle) {
this.linksStyle = linksStyle;
}
public String getMovedClass() {
return this.movedClass;
}
/**
* Chooses the css class to apply to elements that have been moved.
*
* @property
*/
public void setMovedClass(String moveClass) {
this.movedClass = moveClass;
}
public String getImage() {
return image;
}
/**
* Sets the path for the default image to be used for lists items.
*
* @property
*/
public void setImage(String image) {
setIncludeImage(false);
this.image = image;
}
public String getImageFor(String type) {
return this.imagesMap.get(type);
}
/**
* Sets the path of the image that should be used as a icon of items correponding
* to objects of the given type. The path is context relative.
*
* @property
*/
public void setImageFor(String type, String method) {
setIncludeImage(false);
this.imagesMap.put(type, method);
}
public boolean isIncludeImage() {
return this.includeImage;
}
/**
* Specifies if the renderer should include the default images when the
* tree is draggable.
*
* @property
*/
public void setIncludeImage(boolean includeImage) {
this.includeImage = includeImage;
}
public String getCurrent() {
return current;
}
/**
* @property
*/
public void setCurrent(String current) {
this.current = current;
}
public String getCurrentClasses() {
return currentClasses;
}
/**
* @property
*/
public void setCurrentClasses(String currentClasses) {
this.currentClasses = currentClasses;
}
public String getCurrentStyle() {
return currentStyle;
}
/**
* @property
*/
public void setCurrentStyle(String currentStyle) {
this.currentStyle = currentStyle;
}
@Override
public Layout getLayout(Object object, Class type) {
return new TreeLayout();
}
public boolean isDraggable() {
return getTreeId() != null && (getFieldId() != null || getSaveUrl() != null);
}
public boolean isExpandable() {
return this.expandable || isDraggable();
}
public void setExpandable(boolean expandable) {
this.expandable = expandable;
}
public LevelDecorator getDecorator() {
return this.decorator;
}
public void setDecorator(LevelDecorator decorator) {
this.decorator = decorator;
}
protected class TreeLayout extends Layout {
@Override
public HtmlComponent createComponent(Object object, Class type) {
HtmlList list = createList(new ArrayList