<!-- Jset Dialogs & Windows library -->
<IMPORT@CLIENT NAME="Windows" CLASS="jset.client.lib.Windows">
<!-- A JsDataForm must be declared at the top of your XML files, after IMPORTS, not in a container -->
<FORM CLASS="jset.client.data.view.form.JsDataForm" NAME="FORM_NAME" STYLE="0">
	<VIEW NAME="VIEW_NAME" TABLE="TABLE_NAME" SOURCE="SERVICE_NAME" ASYNC="1" STYLE="0x3">
		<JOIN FROM="statusUid" TO="uid" TABLE="OBJSTATUS"/>
		<JOIN FROM="broker_usrUid" TO="uid" TABLE="USR"/>
		<JOIN FROM="owner_usrUid" TO="uid" TABLE="USR"/>
		<JOIN FROM="catUid" TO="uid" TABLE="CAT"/>
		<JOIN FROM="sttUid" TO="uid" TABLE="STT">
			<JOIN FROM="ctrUid" TO="uid" TABLE="CTR"/>
		</JOIN>
	</VIEW>
	<EVENT ACTION{trace('triggered when a record is selected');}>
	<EVENT END_EDIT {
		trace('allows to abort insert or update of a record, or set some fields values before update.');
		trace('END_EDIT event is not null so user did not click on form cancel button.');
		trace(event);
	}>
	<EVENT CHANGE
	{
		trace('record has been modified or created.');
		trace(getControl(event).getData();
	}>
	<EVENT DELETE
	{
		trace('allows you to abort delete operation.');
		icon=Windows.MB_WARNING;
		buttons=Windows.MB_YESNO;
		dlg=new Windows.msgBox(caption,message,icon+buttons);
		btn=dlg.doModal();
		if(btn != ID_YES) return false;
	}>
</FORM>


Hex JsDataForm style Description Default
0x4 Force required .
0x2 Limit edit .
0x1 Select on load Auto selects first record when loading is completed.


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');
}>


loaded event, to know when a dataCpn download has completed.

<EVENT action{
	record=getSlected();
	if(record != null)
	{
		uid=record.getAttribute('uid');
		lookupValue=record.getAttribute('LOOKUP_TABLE.lookupField');
	}
}>


action event, to retrieve dataCpn selected record values.

// 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;}
		}
	}
}>


dbl_click event, to receive dataCpn double clicks (style must be set).

// 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;}
		}
	}
}>


change event, to know when any component binded to the form has changed.

<EVENT CHANGE
{
	trace('record has been modified or created.');
	trace(getControl(event).getData();
}>
The getControl(event); will return the component that has changed value.
Before you know if you should do a dataCPn.getSelected() () or a cpn.getData(), you can use the getType() instruction to know the component class...


end_edit event, allows to abort form or grid form updates, or override some values.

<EVENT END_EDIT {
	trace('allows to abort insert or update of a record, or set some fields values before update.');
	trace('END_EDIT event is not null so user did not click on form cancel button.');
	trace(event);
}>


delete event, allows to abort form or grid form updates, or launch confirmation box,....

<EVENT END_EDIT {
	trace('allows to abort insert or update of a record, or set some fields values before update.');
	trace('END_EDIT event is not null so user did not click on form cancel button.');
	trace(event);
}>




All client side data components must have a view to display result sets. There are two ways to populate content of a data component.
You can declare the VIEW settings in the component XML node, in which case the data is automatically downloaded when an XML file is instance is loaded with getFileInstance() and added to a container with .add();

<JSET CLASS="...Data...." .../>
	<VIEW NAME="CONTACTS_VIEW" TABLE="CONTACTS" SOURCE="DatabaseDynamicServiceName" ASYNC="1" STYLE="0x1">
		<JOIN FROM="countryUid" TO="uid" TABLE="COUNTRIES">
			<JOIN FROM="continentUid" TO="uid" TABLE="CONTINENTS"/>
		</JOIN>
		<JOIN FROM="companyUid" TO="uid" TABLE="COMPANIES">
			<JOIN FROM="sectorUid" TO="uid" TABLE="SECTORS"/>
		</JOIN>
	</VIEW>
	<DATA CODE="..."/>
</JSET>

JOINS declared in XML format (on Dynamic services, see host config file) are LEFT JOINS. These JOINS are performed by the Jset server, and result sets updates are automatically reflected in real-time in the Jset client data components.

SQL views consists of defining the view information, vs. XML views which do represent the result sets themselves.

Views declared in XML format are the easiest to use, and download data

Hex View style Description
0x10 Allow empty new
0x1 Auto delete The view is deleted when it component is unloaded (such as with fileInstance.close(); or when closing a tab or a window)
0x4 Delay schema
0x2 Share select
0x8 Wait in load

View method Method description
getView(viewName); Returns a view object.
viewObj.getByCol(field,value[,field2,value2,...]); Returns a view record.
Ex:


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