<JSET CLASS="jset.gui.control.JsTab" STYLE="0x600032" NAME="tabCpn"
	LEFT="10" 
	RIGHT="10" 
	TOP="5" 
	BOTTOM="7" 
	RIGHT_STEP="0" 
	LEFT_STEP="0" 
	STEP_OVER="3
">
	<RECT X="10" Y="10" W="500" H="300"/>
	<TAB ORDER="0" CAPTION="Basic text caption" SELECTED="1">
		<JSET CLASS="jset.gui.JsContainer" STYLE="0x1030">
			<COLOR CODE="0" RGB="0xf2f2f2"/>
			<TOOLTIP>"This tab item has a basic text caption"</TOOLTIP>
		</JSET>
	</TAB>
	<TAB ORDER="1">
		<JSET CLASS="jset.gui.JsContainer" STYLE="0x1030">
			<COLOR CODE="0" RGB="0xf2f2f2"/>
			<DATA>
				<JSET CLASS="jset.gui.gadget.JsArrayRenderItem">
					<DATA>
						<JSET CLASS="jset.gui.gadget.JsImageRenderItem" PATH="/addOn/iset/ico.png"/>
					</DATA>
					<DATA>
						<JSET CLASS="jset.gui.JsTextRenderItem" CAPTION="Text caption"/>
					</DATA>
				</JSET>
			</DATA>
			<TOOLTIP>"This tab item has an ArrayRender caption."</TOOLTIP>
		</JSET>
	</TAB>
</JSET>

First component placed within TAB node will have strech parent style even if you do not specify it.

It is therefore recommended to place a JsContainer as first component of a tabItem of a tabCpn, as it allows you to not only to start content at X and Y > 0, but also allows you to set an array render in XML for the tabItem.

You can also create the XML without TABs, and add them in code (see METHOD).


Hex Common styles Style description
Border Shows a border (COLOR CODE 3)
Border 3d Shows a 3D border (COLOR CODE 3 & COLOR CODE 4)
Visible Shows / hides the component and its content
Enabled Enables / disables the component
Strech parent Will use all parent WIDTH and HEIGHT regardless of X, Y, W, H, CONSTRAINT W, and CONSTRAINT H.
Strech right Will use all parent WIDTH from X until (parent right border - (CONSTRAINT W)), regardless of W.
Strech bottom Will use all parent HEIGHT from Y until (parent bottom border - (CONSTRAINT H)), regardless of H.
Follow right Will stick to (parent component right border - CONSTRAINT W), regardless of X.
Follow bottom Will stick to (parent component bottom border - CONSTRAINT H), regardless of Y.
Hex Important styles Style description
Bottom tabs Reverse tabs.
0x606032
"/>

Style names in red means displayed state (true/false) differs from the default component state.

Code Name XML
0 Background
<COLOR CODE="0" RGB="0xD0D0D0"/>
1 Foreground
<COLOR CODE="1" RGB="0x000000"/>
2 Disabled foreground
<COLOR CODE="2" RGB="0xBEBEBE"/>
3 Dark border
<COLOR CODE="3" RGB="0x666666"/>
4 Bright border (with 3D style)
<COLOR CODE="4" RGB="0xFFFFFF"/>
5 Inactive tabs background
<COLOR CODE="5" RGB="0xDCDCDC"/>
6 Active tab background
<COLOR CODE="6" RGB="0xD2D2FF"/>
7 Active tab foreground
<COLOR CODE="7" RGB="0x7C7C7C"/>


All components receive EVENTS, which are declared after each others, within the component XML node, as follows:

<JSET CLASS="..." STYLE="..." NAME="..."/>
	<RECT .../>
	<COLOR .../>
	<EVENT built{...}>
	<EVENT create{...}>
	<EVENT ...{...}>
</JSET>


built event, for the top level component only (main)

<EVENT built{
	// test if event[0] equals 0 or 1
	if(event[0] == 1) trace('This is a new file instance, its state is the initial state');
	else trace('This is an existing file instance, its state is the last state in which it was');
	// test if event[1] param exists, see getFileInstance(path, param, reload);
	if(event[1] != null) param = event[1];
}>


create event, to know when a component is created.

<EVENT create{
	trace('component has been created');
}>


action event, called when a tabItem of a tabCpn is selected.

// action is one of the most important events
<EVENT action{
	type = getType(this);
	trace(type);
	type = type.lower();
	trace(type);
	if(type.index('data') != -1)
	{
		// component having this event is a data component.
		record = getSelected();
		if(record != null)
		{
			value=record['field'];
			lookupValue=record['LOOKUP_TABLE.lookupField'];
		}
	}
	else
	{
		if(type.index('tab') == -1)
		// component is a JsTab
		tabItem = getSelected();
		// get position of tab
		for(t=0; t < tabCpn.getTabs().length();t++)
		{
			tab = tabCpn.getTabs()[t];
			if(tab == tabItem) {tabItemPos = t; break;}
		}
	}
}>




Method name Method description   Method name Method description
cpn.getColor(code); Returns a component color.   cpn.setColor(code, value); Changes a component color.
cpn.getRect(); Returns an array of 4 elements, X, Y , W, and H.   cpn.setRect(X,Y,W,H); Sets position and size of a component.
Use null to not modify one of the params.
cpn.hasStyle(style); Returns true if component has the style.   cpn.setStyle(style, true/false); Changes a component style.
Use true or 1 to add, false of 0 to remove.
tabCpn.getSelected(); Returns the selected tabItem (object).   tabCpn.setSelected(tabItem, sendEvent); Select a tabItem of a tabCpn.
tabCpn.addTab(instance, caption, close); Adds a getFileInstance() as a new tab item.
Second param can be text, or any render type.
Third param (true/false) adds a close cross symbol to the added tabItem.
  tabCpn.closeTab(tabCpn.getTabs()[pos]); Closes a tab item in a tabCpn (JsTab).
Ex: close selected tab item:
tabCpn.closeTab(tabCpn.getSelected());
tabCpn.getTabs(); Returns an array of tabItems.
Attention, you cannot do tabCpn.length(); to return the number of tabItems, but you should do:
tabCpn.getTabs().length();
Sample codeJsTab methods:
/*
This code could be in the action event of a dataCpn
Suppose you want to open a new tab for every new record a user clicks on a dataCpn, but you do not want to reopen a new tabItem if a tabItem for this record has already been opened.
First, retrieve seleted record of a the dataCpn, to open details in a new tabItem.
*/

// If this event belongs to the dataCpn
record = getSelected();
// or
record = this.getSelected();
// or is event belongs to another dataCpn
record = dataCpn.getSelected();
// make sure a record has been clicked, and not empty space in the dataCpn.

if(record != null)
{
	uid = rec['TABLE_NAME.uid'];
	found=0;
	// search for a tabItem having this uid.
	for(t=0; t< tabCpn.getTabs().length(); t++)
	{
		tabItem = tabCpn.getTabs()[t];
		if(uid==tabItem.uid) 
		{
			found=1;
			// select the found tabItem that has the same uid
			// set senEvent to 0 if you want to avoid tabCpn action event.
			tabCpn.setSelected(tabItem,0);
			break;
		}
	}
	if(found == 0) 
	{
		// add a new tabItem
		param=uid;
		reload=1;
		// send uid to built event of tabItem.app, in which you will set it like this: uid=event[1];
		tabItem = getFileInstance('xml/.../tabItem.app',param,reload);
		// you could alternatively do tabItem.uid = uid, and pass a null param instead of uid...
		// in this case no need to code  uid=event[1]; in the tabItem XML file in the built event.
		icoPth = 'iset/dir/clr/green.png';
		textCaption = 'My tabItem text caption';
		// 16 aligns an ArrayRender horizontally
		tabItemCaption = new ArrayRender(16,new ImageRender(icoPth),textCaption);
		// finally add the new tabItem to the tabCpn
		tabCpn.add(tabItem);
	}
}	


Data components, text and number edits, and buttons can be binded to a form.
You do not need to place the binded component within the XML forms tags or at any special place, as forms are declared on the top of your XML file.

All you need to do is add the FORM_FIELD node to your component XML, with the FORM_NAME.fieldName.
The fieldName must be a field of the FORM VIEW main table, not a field of a lookup table.

...



Containers


 JsContainer

 JsExpand

 JsScrollContainer

 JsSplitContainer

 JsTab


 JsDialog

 JsWindow


Data (SQL & XML result sets)


 JsDataCombo

 JsDataGrid

 JsDataGridForm

 JsListBox

 JsDataPanel

 JsDataTreeBox


 JsDataForm


Text, number, &date


 JsWordPadEdit

 JsTextArea

 JsEdit

 JsXmlTextArea


 JsNumberEdit

 JsSpinEdit


 JsExpandCalendar

 JsDatePicker


Other components


 JsButton

 JsCheckbox

 JsGroupBox

 JsMenu

 JsProgressBar

 JsRadio

 JsStatic