Dialogs are Groovy templates that generate forms by mixing static HTML fragments and Groovy calls to the components responsible for building the UI at runtime. The result is a simple but powerful syntax.

h1. Common parameters {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters}

These following parameters are common and can be used for all input fields.
||*Parameter*||*Type*||*Required*||*Description*||*Example*||
|*jcrPath*|String|!images/check.gif!|Relative path inside the current node.|_jcrPath=/node/exo:title_|
|*mixintype*|String with comma {{,}} character.|!images/error.gif!|List of mixin types you want to initialize when creating the content.|{example}mixintype=mix:i18n{example} {example}mixintype=mix:votable,mix:commentable,mix:i18n{example}|
|*validate*|String with comma {{,}} character|!images/error.gif!|List of validators you want to apply to the input. Possible values are: _name, email, number, empty, null, datetime, length_ OR validator classes.|{example}validate=empty{example} {example}validate=empty,name{example} {example}validate=org.exoplatform.webui.form.validator.StringLengthValidator{example}|
|*editable*|String|!images/error.gif!|The input will be editable only if the value of this parameter is {{if-null}} and the value of this input is null or blank.|_editable=if-null_|
|*multiValues*|Boolean|!images/error.gif!|Show a multi-valued component if true and must be used only with corresponding multi-valued properties. The default value of this parameter is false.|_multiValues=true_|
|*visible*|Boolean|!images/error.gif!|The input is visible if this value is true.|_visible=true_|

See also:

* [Text field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextField]
* [Hidden field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.HiddenField]
* [Text area field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextAreaField]
* [Rich text field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.RichTextField]
* [Calendar field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CalendarField]
* [Upload field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.UploadField]
* [Radio field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.RadioField]
* [Select box field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.SelectBoxField]
* [Checkbox field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CheckBoxField]
* [Mixin field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.MixinField]
* [Action field|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.ActionField]

{note}
The _mixintype_ can be used only in the root node field (commonly known as the name field).
{note}

h1. Text Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextField}
* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextField.AdditionParameters}
See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]
* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextField.Example}

{code:groovy}
<%
  String[] fieldTitle = ["jcrPath=/node/exo:title", "validate=empty"] ;
  uicomponent.addTextField("title", fieldTitle) ;
%>
{code}

h1. Hidden Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.HiddenField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.HiddenField.AdditionParameters}

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.HiddenField.Example}

{code:java}
String[] hiddenField5 = ["jcrPath=/node/jcr:content/dc:date", "visible=false"];  
  uicomponent.addCalendarField("hiddenInput5", hiddenField5);
{code}
h1. Text Area Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextAreaField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextAreaField.AdditionParameters}

|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *rows* | {{Number}} | !images/error.gif! | The initial text area's number of rows. The value is {{10}} by default. | {{rows=20}} |
| *cols* | {{Number}} | !images/error.gif! | The initial text area's number of cols. The value is {{30}} by default .| {{cols=50}} |

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.TextAreaField.Example}

{code:groovy}
<%
  String[] fieldDescription = ["jcrPath=/node/exo:description", "validate=empty"] ;
  uicomponent.addTextAreaField("description", fieldDescription) ; 
%>
{code}

h1. Rich Text Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RichTextField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RichTextField.AdditionParameters}

||*Parameter*||*Type*||*Required*||*Description*||*Example*||
|*options*|String with semicolon {{;}} character|!images/error.gif!|Some options for CKEditor field: toolbar, width and height.|{{options=CompleteWCM;width:'100%';height:'200px';}}|
|*toolbar*|{{String}}|!images/error.gif!|The predefined toolbar for CKEditor. The value can be: {{Default}}, {{Basic}}, {{CompleteWCM}}, {{BasicWCM}}, {{SuperBasicWCM}}|{{options=CompleteWCM}}|
|*width*|{{String}}|!images/error.gif!|The width of CKEditor. Its value can be the percent of pixel.|{{options=width:'100%'}}|
|*height*|{{String}}|!images/error.gif!|The height of CKEditor. Its value can be the percent of pixel.|{{options=height:'200px'}}|
See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RichTextField.Example}

{code:groovy}
<%
  String[] fieldSummary = ["jcrPath=/node/exo:summary", "options=toolbar:CompleteWCM,width:'100%',height:'200px'", "validate=empty"] ;
  uicomponent.addRichtextField("summary", fieldSummary) ;
%>
{code}

h1. Calendar Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CalendarField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CalendarField.AdditionParameters}
|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *options* | {{String}} | !images/error.gif! | An option for the calendar field: Display time | {{options=displaytime}} |

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CalendarField.Example}

{code:groovy}
<%
  String[] fieldPublishedDate = ["jcrPath=/node/exo:publishedDate", "options=displaytime", "validate=datetime", "visible=true"] ;
  uicomponent.addCalendarField("publishedDate", fieldPublishedDate) ;
%>
{code}

h1. Upload Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.UploadField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.UploadField.AdditionParameters}

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.UploadField.Example}

When you create an upload form, there are two main ways to store an image:
* If you want to store as property, use the following code:

{code:groovy}
<%
  String[] fieldMedia = ["jcrPath=/node/exo:image"] ;
  uicomponent.addUploadField("media", fieldMedia) ;		
%>
{code}

* If you want to store as node, use the following code:

{code:groovy}
<%
  String[] hiddenField1 = ["jcrPath=/node/exo:image", "nodetype=nt:resource", "visible=false"] ; 
  String[] hiddenField2 = ["jcrPath=/node/exo:image/jcr:encoding", "visible=false", "UTF-8"] ;
  String[] hiddenField3 = ["jcrPath=/node/exo:image/jcr:lastModified", "visible=false"] ;
  uicomponent.addHiddenField("hiddenInput1", hiddenField1) ;
  uicomponent.addHiddenField("hiddenInput2", hiddenField2) ;
  uicomponent.addHiddenField("hiddenInput3", hiddenField3) ;

  String[] fieldMedia = ["jcrPath=/node/exo:image"] ;
  uicomponent.addUploadField("media", fieldMedia) ;		
%>
{code}

* But, this code is not complete. If you want to display the *upload* field, the image must be blank, otherwise you can display the image and an action enables you to remove it. You can do as follows:

{code:groovy}
<%
	def image = "image";
	// If you're trying to edit the document
	if(uicomponent.isEditing()) { 
		def curNode = uicomponent.getNode();
		// If the image existed
		if (curNode.hasNode("exo:image")) {
			def imageNode = curNode.getNode("exo:image") ;
			// If the image existed and available
			if (imageNode.getProperty("jcr:data").getStream().available() > 0 && (uicomponent.findComponentById(image) == null)) {
				def imgSrc = uicomponent.getImage(curNode, "exo:image");
				def actionLink = uicomponent.event("RemoveData", "/exo:image");
				%>		
					<div>
						<img src="$imgSrc" width="100px" height="80px"/>
						<a href="$actionLink">
							<img src="/eXoResources/skin/DefaultSkin/background/Blank.gif" alt="" class="ActionIcon Remove16x16Icon"/>
						</a>
					</div>
				<%
			} else {
				String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
				uicomponent.addUploadField(image, fieldImage) ;								
			}
		} else {
				String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
				uicomponent.addUploadField(image, fieldImage) ;								
		}
	}  else if(uicomponent.dataRemoved()) {
		String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
		uicomponent.addUploadField(image, fieldImage) ;
	} else {
		String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
		uicomponent.addUploadField(image, fieldImage) ;
	}
%>
{code}

h1. Radio Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RadioField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RadioField.AdditionParameters}
|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *options* | {{String}} with comma {{,}} characters | !images/error.gif! | Some radio values | {{options=radio1,radio2,radio3}} |
See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.RadioField.Example}

{code:groovy}
<%
  String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=radio1,radio2,radio3"];		 
  uicomponent.addRadioBoxField("isDeep", fieldDeep);
%>
{code}

h1. Select box Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.SelectBoxField}
|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *options* | {{String}} with comma {{,}} characters | !images/error.gif! | Some option values | {{options=option1,option2,option3}} |
See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.SelectBoxField.Example}

{code:groovy}
<%
  String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=checkbox1,checkbox2,checkbox3"];
  uicomponent.addCheckBoxField("isDeep", fieldDeep);
%>
{code}

h1. Checkbox Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CheckBoxField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CheckBoxField.AdditionParameters}
|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *options* | {{String}} with comma {{,}} characters | !images/error.gif! | Some checkbox values | {{options=checkbox1,checkbox2,checkbox3}} |
See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.CheckBoxField.Example}

{code:groovy}
<%
  String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=checkbox1,checkbox2,checkbox3"];
  uicomponent.addCheckBoxField("isDeep", fieldDeep);
%>
{code}
  
h1. Mixin Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.MixinField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.MixinField.AdditionParameters}

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.MixinField.Example}

{code:groovy}
<%
  String[] fieldId = ["jcrPath=/node", "editable=false", "visible=if-not-null"] ;
  uicomponent.addMixinField("id", fieldId) ; 
%>
{code}

h1. Action Field {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.ActionField}

* *Additional parameters* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.ActionField.AdditionParameters}

|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *selectorClass* | {{String}} | !images/check.gif! | The component to display. | {{selectorClass=org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector}} |
| *selectorIcon* | {{String}} | !images/check.gif! | The action icon | {{selectorIcon=SelectPath24x24Icon}} |

Depending on the {{selectorClass}}, some other parameters can be added.

For example, the component {{org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector}} needs the following parameters:

|| *Parameter* || *Type* || *Required* || *Description* || *Example* ||
| *workspaceField* | {{String}} | !images/error.gif! | The field which enables you to select a workspace. | {{workspaceField=targetWorkspace}} |

The component {{org.exoplatform.ecm.webui.selector.UIPermissionSelector}} does not need any special parameters.

See also: [Common parameters|#CONTref.InsideWCMTemplates.ContentTypes.Dialog.CommonParameters]

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.ActionField.Example}

{code:groovy}
<% 
  String[] fieldPath = ["jcrPath=/node/exo:targetPath", "selectorClass=org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector", "workspaceField=targetWorkspace", "selectorIcon=SelectPath24x24Icon"] ;
  uicomponent.addActionField("targetPath", fieldPath)  ;
%>
{code}

h1. Interceptors {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.Interceptors}

To add an interceptor to a dialog, you can use this method {{*uicomponent.addInterceptor(String scriptPath, String type)*}}
|| || || *Parameters* ||
| *scriptPath* | {{String}} | The relative path to the script file. |
| *type* | {{String}} | The type of interceptor: {{prev}} or {{post}}. |

* *Example* {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.Interceptors.Example}

{code:groovy}
<%
  uicomponent.addInterceptor("ecm-explorer/interceptor/PreNodeSaveInterceptor.groovy", "prev");
%>
{code}

h1. How to add a new ECM template with tabs {anchor:id=CONTref.InsideWCMTemplates.ContentTypes.Dialog.HowToAddNewECMTemplateWithTabs}

To avoid refreshing the first tab for every action execution, add a new private function to the template with tabs.
In the template, you must insert a new piece of code like the following:

{code:groovy}
private String getDisplayTab(String selectedTab) {
  if ((uicomponent.getSelectedTab() == null && selectedTab.equals("mainWebcontent"))
			|| selectedTab.equals(uicomponent.getSelectedTab())) {
		return "display:block";
	}
	return "display:none";
}

private String getSelectedTab(String selectedTab) {
	if (getDisplayTab(selectedTab).equals("display:block")) {
		return "SelectedTab";
	}
	return "NormalTab";
}
{code}

Changing in every event of onclick must be done like the following:

{code:html}        
<div class="UITab NormalTabStyle">
  <div class="<%=getSelectedTab("mainWebcontent")%>
    ">
    <div class="LeftTab">
      <div class="RightTab">
        <div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "mainWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.MainContent")%></div>
      </div>
    </div>
  </div>
</div>

<div class="UITab NormalTabStyle">
  <div class="<%=getSelectedTab("illustrationWebcontent")%>
    ">
    <div class="LeftTab">
      <div class="RightTab">
        <div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "illustrationWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.Illustration")%></div>
      </div>
    </div>
  </div>
</div>

<div class="UITab NormalTabStyle">
  <div class="<%= getSelectedTab("contentCSSWebcontent")%>
    ">
    <div class="LeftTab">
      <div class="RightTab">
        <div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "contentCSSWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.Advanced")%></div>
      </div>
    </div>
  </div>
</div>
{code}

Finally, to display the selected tab, simply add it to the style of UITabContent class.

{code:html}
<div class="UITabContent" style="<%=getDisplayTab("mainWebcontent")%>">
{code}