πŸ“œ ⬆️ ⬇️

New HTML5 Visual ZEN-components in CachΓ© 2013.2 DBMS

It is worth noting that new HTML5 visual components, the interface of which is optimized including for mobile devices, and which use the JSON format for data acquisition, have already appeared in the CachΓ© DBMS version 2013.1, but not all of them are still working β€œin full force”.

These are such components as:


In the class reference you can find all the documentation for these components. Here are some introductory examples of their use (with screenshots).
')

Example # 1: <accordionMenu>


This component is a special menu with the maximum allowable number of levels equal to three.
The example uses two components: one receives data from the client, the other from the server.
Sample code for <accordionMenu>
Class html5.test1 Extends% ZEN.Component.page
{

/// This Style block defines the CSS style for the page.
XData Style
{
< style type = "text / css" >
</ style >
}

/// This XML block describes the content of this page.
XData Contents [ XMLNamespace = " www.intersystems.com/zen" ]
{
< page xmlns = " www.intersystems.com/zen" title = "" >
< jsonProvider id = "json" OnGetArray = "SrvGetData" />
< hgroup cellVAlign = "top" >

<! - Receive data from server ->
< accordionMenu controllerId = "json" onselect = "zenPage.selectList (key, action, targetId);" selectedIndex = "2" />

<! - Receive data from client ->
< accordionMenu ongetdata = "return zenPage.getdata ();" onselect = "zenPage.selectList (key, action, targetId);" />

</ hgroup >
</ page >
}

ClientMethod getdata () [ Language = javascript]
{
return {children: [{key: 'key0' ,
caption: 'caption0' ,
action: 'action0' ,
targetId: 'id0' ,
image: 'deepsee / add_64.png' ,
imageStyle: 'border: 1px solid red;' ,
style: 'background: red;' ,
children: [{key: 'key01' ,
caption: 'caption01' ,
action: 'action01' ,
targetId: 'id01' ,
image: 'images / save.png' }]
}]
};
}

Method SrvGetData (
ByRef pParameters ,
Output pMetaData ,
Output pData ) As% Status
{
Set pMetaData = $ LB ( "key" , "caption" , "action" , "targetId" , "image" , "imageStyle" , "style" )

Set pData (1) = $ LB ( "key1" , "caption1" , "action1" , "id1" , "" )
Set pData (1,1) = $ LB ( "key11" , "caption11" , "action11" , "id11" , "images / saveas.png" )
Set pData (1,1,1) = $ LB ( "key111" , "caption111" , "action111" , "id111" , "deepsee / cancel_48.png" )
Set pData (1,1,2) = $ LB ( "key112" , "caption112" , "action112" , "id112" , "deepsee / cancel_48.png" )
Set pData (2) = $ LB ( "key2" , "caption2" , "action2" , "id2" , "images / save.png" , "border-radius: 10px;" )
Set pData (2,1) = $ LB ( "key21" , "caption21" , "action21" , "id21" , "images / saveall.png" )
Set pData (2,1,1) = $ LB ( "key211" , "caption211" , "action211" , "id211" , "deepsee / ds2_list_44.png" )
Set pData (2,1,2) = $ LB ( "key212" , "caption212" , "action212" , "id212" , "deepsee / ds2_list_44.png" )
Set pData (3) = $ LB ( "key3" , "caption3" , "action3" , "id3" , "" )
Set pData (3,1) = $ LB ( "key31" , "caption31" , "action31" , "id31" , "images / saveall.png" )
Set pData (3,1,1) = $ LB ( "key311" , "caption311" , "action311" , "id311" , "deepsee / add_64.png" , "border: 1px solid white;" )
Set pData (3,1,2) = $ LB ( "key312" , "caption312" , "action312" , "id312" , "deepsee / add_64.png" ,, "background: blue;" )

Quit $$$ OK
}

ClientMethod selectList (
key ,
action ,
targetId ) [ Language = javascript]
{
zenAlert ( 'key =' , key, '\ naction =' , action, '\ ntargetId =' , targetId);
}

}
Screenshots of <accordionMenu>
β„– 1
β„– 1

β„– 2
β„– 2

Number 3
Number 3

Example 2: <toolbar>


This component is a sub-menu with the support of various types of sub-items.
The example uses two components: one is the simplest case, the other is more advanced with overriding some inline styles.
Sample code for <toolbar>
Class html5.test2 Extends% ZEN.Component.page
{

/// This Style block defines the CSS style for the page.
XData Style
{
< style type = "text / css" >
.ztb-caption-1 {
font-size: 12px;
padding: 4px 10px 4px 10px;
}

.ztb-menuItemSelected-1 {
background: white;
border: 1px solid;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}

td.ztb-choiceSelected {
background: white;
color: black;
opacity: 1.0;
font-size: 12px;
}
</ style >
}

/// This XML block describes the content of this page.
XData Contents [ XMLNamespace = " www.intersystems.com/zen" ]
{
< page xmlns = " www.intersystems.com/zen" title = "" >
< toolbar
ongetdata = "return zenPage.getdata1 ();"
onselect = "zenPage.selectList (key, action, targetId);"
/>
< spacer height = "10" />
< toolbar
ongetdata = "return zenPage.getdata2 ();"
onselect = "zenPage.selectList (key, action, targetId);"
onchange = "zenPage.change (key, value, final);"
onpagechange = "zenPage.pagechange (key, page);"
/>
</ page >
}

ClientMethod pagechange (
key ,
page ) [ Language = javascript]
{
zenAlert ( 'key =' , key, '\ npage =' , page);
}

ClientMethod change (
key ,
value ,
final ) [ Language = javascript]
{
zenAlert ( 'key =' , key, '\ nvalue =' , value, '\ nfinal =' , final);
}

ClientMethod selectList (
key ,
action ,
targetId ) [ Language = javascript]
{
zenAlert ( 'key =' , key, '\ n action =' , action, '\ ntargetId =' , targetId);
}

ClientMethod getdata1 () [ Language = javascript]
{
return {children: [{key: 'key1' ,
caption: 'caption1' ,
action: 'action1' ,
targetId: 'id1' ,
image: '' ,
children: [{key: 'key11' ,
caption: 'caption11' ,
action: 'action11' ,
targetId: 'id11' ,
image: 'images / save.png' }]
},
{key: 'key2' ,
caption: 'caption2' ,
action: 'action2' ,
targetId: 'id2' ,
image: 'deepsee / add_64.png' ,
children: [{key: 'key21' ,
caption: 'caption21' ,
action: 'action21' ,
targetId: 'id21' ,
image: 'images / save.png' }]
},
{key: 'key3' ,
caption: 'caption3' ,
action: 'action3' ,
targetId: 'id3' ,
image: 'deepsee / ds2_list_44.png' ,
children: [{key: 'key31' ,
caption: 'caption31' ,
action: 'action31' ,
targetId: 'id31' ,
image: 'images / save.png' }]
}]
};
}

ClientMethod getdata2 () [ Language = javascript]
{
return {
children: [
{key: 'key1' , caption: 'caption1' , action: 'action1' , targetId: 'id1' , image: '' , type: 'pages' , minValue: 1 , maxValue: 5 },
{key: 'key2' , caption: 'caption2' , action: 'action2' , targetId: 'id2' , image: 'deepsee / cancel_48.png' , type: 'tab' },
{key: 'key3' , caption: 'caption3' , action: 'action3' , targetId: 'id3' , image: '' , type: 'tab' },
{key: 'key4' , caption: 'caption4' , action: 'action4' , targetId: 'id4' , image: '' , type: 'item' ,
children: [{key: 'key41' , caption: 'caption41' , action: 'action41' , targetId: 'id41' , image: '' },
{separator: '' },
{key: 'key42' , caption: 'caption42' , action: 'action42' , targetId: 'id42' , image: '' }]},
{type: 'spacer' , style: 'width: 50px;' },
{key: 'key5' , caption: 'caption5' , action: 'action5' , targetId: 'id5' , image: 'images / save.png' , type: 'tab' , selected: true},
{key: 'key6' , caption: 'caption6' , action: 'action6' , targetId: 'id6' , image: '' , type: 'choice' , displayList: 'a1, b1, c1' , valueList: 'a , b, c ' , value: ' c ' , style: ' width: 90px; ' },
{key: 'key7' , caption: 'caption7' , action: 'action7' , targetId: 'id7' , image: '' , type: 'field' , value: 'field' },
{key: 'key8' , caption: 'caption8' , action: 'action8' , targetId: 'id8' , image: '' , type: 'string' , defaultValue: 'defaultValue' },
{key: 'key9' , caption: 'caption9' , action: 'action9' , targetId: 'id9' , image: '' , type: 'message' }
]
};
}

}
Screenshots of <toolbar>
β„– 1
β„– 1

β„– 2
β„– 2

Example 3: <navigator>


This component provides a rich interface, sharpened for mobile devices, where each menu item is controlled by a certain type with customizable parameters inherent to this type.
It is possible to insert your own html in sub-items if the built-in types are not enough.
Some types of items allow you to navigate to the next levels, which in turn may contain their own menu items. The nesting depth for the drill type transition is unlimited.
Each level has its own headers and footers available.
Menu items can be moved using drag & drop; There are ready-made methods for choosing colors and fonts.
In addition, event handlers are available for finger control.
Sample code for <navigator>
Class html5.test3 Extends% ZEN.Component.page
{

/// This Style block defines the CSS style for the page.
XData Style
{
< style type = "text / css" >
</ style >
}

/// This XML block describes the content of this page.
XData Contents [ XMLNamespace = " www.intersystems.com/zen" ]
{
< page xmlns = " www.intersystems.com/zen" title = "" >
< navigator
id = "navigator"
footerHeight = "40"
showDisclosure = "true"
expanded = "true"
ongetcontent = "return zenPage.getContent (level, key, value);"
onselect = "zenPage.selectItem (key, value, which);"
onchange = "zenPage.dataChange (key, value, final);"
onbuttonclick = "zenPage.buttonClick (key);"
onclosebuttonclick = "zenPage.closeButtonClick (key);"
/>
</ page >
}

ClientMethod buttonClick ( key ) [ Language = javascript]
{
zenAlert ( 'key =' , key);
}

ClientMethod closeButtonClick ( key ) [ Language = javascript]
{
zenAlert ( '(closebutton) key =' , key);
}

ClientMethod dataChange (
key ,
value ,
final ) [ Language = javascript]
{
if (final) zenAlert ( 'key =' , key, '\ nvalue =' , value, '\ nfinal =' , final);
}

ClientMethod selectItem (
key ,
value ,
which ) [ Language = javascript]
{
if (which ! = 'drill' ) zenAlert ( 'key =' , key, '\ nvalue =' , value, '\ nwhich =' , which);
}

ClientMethod getContent (
level ,
key ,
value ) [ Language = javascript]
{
var content = {title: '' , items: [], headerButtons: [], footerButtons: []};
if (key == '' ) {
content.title = 'Title' ;

content.headerButtons = [{caption: 'Caption1' , key: 'key1' , image: 'deepsee / add_64.png' },
{caption: 'Caption2' , key: 'key2' , image: 'deepsee / cancel_48.png' },
{caption: 'Caption3' , key: 'key3' , image: 'deepsee / calendar_48.gif' }]];

content.footerButtons = [{caption: 'Caption1' , key: 'key1' , image: 'deepsee / delete_24.png' },
{caption: 'Caption2' , key: 'key2' , image: 'deepsee / lamp_48.gif' },
{caption: 'Caption3' , key: 'key3' , image: 'deepsee / delete_24.png' }]];

content.items [content.items.length] = {display: 'caption' , caption: 'Select' , action: 'select' , style: 'color: darkblue;' , key: 'keySelect' , value: 'value' };
content.items [content.items.length] = {display: 'value' , text: 'Value' , disabled: true};
content.items [content.items.length] = {display: 'info' , caption: 'Info' , help: 'Help' , image: 'deepsee / add_64.png' , text: 'Text' };
content.items [content.items.length] = {display: 'html' , content: '<hr /> <p> bla-bla-bla </ p>' };
content.items [content.items.length] = {display: 'section' , caption: 'Section' , captionStyle: 'color: red;' , style: 'background: blue;' };
content.items [content.items.length] = {display: 'value-cells' , style: 'height: 55px;' , cellsPerRow: 3 , cells: [{caption: 'C1' , value: 'V1' },
{caption: 'C2' , value: 'V2' },
{caption: 'C3' , value: 'V3' }]};
content.items [content.items.length] = {display: 'caption-value-vt' , caption: 'Switch' , value: false, edit: 'switch' , key: '' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Switch' , value: false, edit: 'switch' , key: '' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'String' , value: '$$$ bla' , edit: 'string' , action: 'drill' , key : 'keyText1' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Slider' , value: 70 , edit: 'slider' , minValue: 0 , maxValue: 100 };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Slider-Toggle' , value: 70 , edit: 'slider-toggle' , minValue: 0 , maxValue: 100 , stepSize: 10 };
content.items [content.items.length] = {display: 'caption-value-hz' ,
caption: 'Choice' ,
edit: 'choice' ,
valueList: 's1, s2, s3, s4' ,
displayList: 'd1, d2, d3, d4' ,
value: 's2' ,
valueStyle: 'font-size: 12pt; font-weight: bold;' ,
choiceStyles: 'color: red; ^ color: blue; ^ color: yellow; ^ color: black;' };
content.items [content.items.length] = {display: 'caption-value-hz' ,
caption: 'Choice-Multi' ,
edit: 'choice-multi' ,
valueList: 's1, s2, s3, s4' ,
displayList: 'd1, d2, d3, d4' ,
value: 's1, s4' ,
valueStyle: 'font-size: 12pt; font-weight: bold;' ,
choiceStyles: 'color: red; ^ color: blue; ^ color: yellow; ^ color: black;' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Image' , edit: 'string' , action: 'drill' , key: 'keyImage' , value: 'deepsee /add_64.png ' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Color' , action: 'drill' , key: 'keyColor' };
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'Font' , action: 'drill' , key: 'keyFont' , value: 'tahoma' };
content.items [content.items.length] = {display: 'image-caption' , caption: 'Image-Caption' };
content.items [content.items.length] = {display: 'image-caption-value' , caption: 'Image-Caption-Value' , text: 'Image-Caption-Value' };
content.items [content.items.length] = {display: 'image-caption-value-hz' ,
caption: 'Caption' ,
text: 'Text' ,
action: 'popup' ,
url: 'mailto: test@gmail.com' ,
key: 'key' ,
canDrag: true
closeButton: true};
} else if (key == 'keyImage' ) {
content.title = 'Image' ;
var list = [];
list [list.length] = {image: '' , caption: 'empty' , value: '' , style: '' };
list [list.length] = {image: value, caption: value, value: value};
list [list.length] = {image: 'deepsee / cancel_48.png' , caption: 'deepsee / cancel_48.png' , value: 'deepsee / cancel_48.png' , style: '' };
content.html = zen ( 'navigator' ). getIconListHTML (list, key, value);
} else if (key == 'keyColor' ) {
content.title = 'Color' ;
content.html = zen ( 'navigator' ). getColorChooserHTML (key, value, 'html' );
} else if (key == 'keyFont' ) {
content.title = 'Font' ;
content.html = zen ( 'navigator' ). getFontChooserHTML (key, value);
} else if (key == 'keyText1' ) {
content.title = 'Text1' ;
content.footerButtons = [{caption: 'Caption1' , key: 'key1' , image: 'deepsee / add_64.png' },
{caption: 'Caption2' , key: 'key2' , image: 'deepsee / lamp_48.gif' },
{caption: 'Caption3' , key: 'key3' , image: 'deepsee / lamp_48.gif' }]];
content.items [content.items.length] = {display: 'caption-value-hz' , caption: 'String' , value: 'v2' , edit: 'string' , action: 'drill' , key: 'keyText2 ' };
} else if (key == 'keyText2' ) {
content.title = 'Text2' ;
content.headerButtons = [{caption: 'Caption1' , key: 'key1' , image: 'deepsee / add_64.png' },
{caption: 'Caption2' , key: 'key2' , image: 'deepsee / lamp_48.gif' },
{caption: 'Caption3' , key: 'key3' , image: 'deepsee / lamp_48.gif' }]];
var list = [
{caption: 'Title' , value: 'v1' , hint: 'Use title' },
{caption: 'Category' , value: 'v2' , hint: 'Use category' },
{caption: 'Type' , value: 'v3' , hint: 'Use type' },
];
content.html = zen ( 'navigator' ). getChooserListHTML (list, key, value, 'Text tags' , 'These are special tags.' );
}
return content;
}

/// Make sure that we force Internet Explorer to use the latest rendering engine.
Method % OnDrawHTMLMeta () As% Status
{
If $$$ ZENISIE & html << http-equiv = "X-UA-Compatible" content = "IE = edge" / >>
Quit $$$ OK
}

}
Screenshots of <navigator>
β„– 1
β„– 1

β„– 2
β„– 2

Number 3
Number 3

β„– 4
β„– 4

β„– 5
β„– 5

β„– 6
β„– 6

β„– 7
β„– 7

Example 4: <lookup>


This component is a drop-down list with the ability to quickly find the desired item.
List items can contain multiple columns and images.
Search all columns.
This component is used in the next, more complex component.
Sample code for <lookup>
Class html5.test4 Extends% ZEN.Component.page
{

/// This Style block defines the CSS style for the page.
XData Style
{
< style type = "text / css" >
</ style >
}

/// This XML block describes the content of this page.
XData Contents [ XMLNamespace = " www.intersystems.com/zen" ]
{
< page xmlns = " www.intersystems.com/zen" title = "" >
< lookup
id = "lookup"
idProperty = "key"
textProperty = "caption"
imageProperty = "image"
styleList = "color: red ;, color: blue;"
propertyList = "key, caption, a, b"
ongetdata = "return zenPage.getdata (context);"
/>
</ page >
}

ClientMethod getdata ( context ) [ Language = javascript]
{
return [{key: 'key1' , caption: 'caption1' , image: 'deepsee / add_16.png' , a: 'a1' , b: 'b1' },
{key: 'key2' , caption: 'caption2' , a: 'a2' , b: 'b2' },
{key: 'key3' , caption: 'caption3' , a: 'a3' , b: 'b3' },
{key: 'key4' , caption: 'caption4' , a: 'a4' , b: 'b4' }
];
}

ClientMethod onloadHandler () [ Language = javascript]
{
zen ( 'lookup' ) .setValue ( 'key3' , 'caption3' );
}

Method % OnDrawHTMLMeta () As% Status
{
If $$$ ZENISIE & html << http-equiv = "X-UA-Compatible" content = "IE = edge" / >>
Quit $$$ OK
}

}
Screenshots of <lookup>
β„– 1
β„– 1

β„– 2
β„– 2

Number 3
Number 3

Example 5: <dataGrid>


This component is a simplified analogue of a spreadsheet for working with data, where columns can be of different types: pictures, drop-down lists, etc.
Formulas and pages are also supported.
Sample code for <dataGrid>
Class html5.test5 Extends% ZEN.Component.page
{

Parameter JSINCLUDES As STRING = "zenCSLM.js" ;

/// This XML block describes the content of this page.
XData Contents [ XMLNamespace = " www.intersystems.com/zen" ]
{
< page xmlns = " www.intersystems.com/zen" title = "" >
< jsonProvider id = "json" OnGetArray = "SrvGetData" />
< hgroup >
< button caption = "Add row" onclick = "zenPage.addRow ();" />
< button caption = "Add column" onclick = "zenPage.addColumn ();" />
</ hgroup >
< hgroup >
< dataGrid
controllerId = "json"
selectMode = "cells"
hasFormulas = "false"
currRow = "2"
currColumn = "2"
gridTitle = " Header1 "
multiSelect = "false" >
< summaryRow caption = "Amount" />
</ dataGrid >
< dataGrid
id = "dg2"
selectMode = "cells"
currRow = "1"
currColumn = "3"
gridTitle = " Header3 "
showRowSelector = "false"
multiSelect = "true"
pageSize = "3"
hasFormulas = "true"
onaction = "zenAlert ('row =', row, '\ nname =', name, '\ nvalue =', value);"
ongetlookupdata = "return zenPage.getdata (context);" >
< columnDescriptor caption = "f1" value = "= power (2.4)" />
< columnDescriptor caption = "f2" value = "= concat (2, & quot; a & quot;, rowno ())" />
< columnDescriptor caption = "f3" value = "= sum (2,3,3, colno ())" />
< columnDescriptor caption = "f4" value = "= [$ col # 2]. [$ row # 3]" />
< columnDescriptor caption = "a" value = "6" />
< columnDescriptor caption = "b" value = "5" />
< columnDescriptor caption = "c" value = "4" />
< columnDescriptor caption = "d" type = "button" name = "n1" value = "= [$ col # 3]. [$ row # 1]" />
< columnDescriptor caption = "e" type = "checkbox" name = "n2" />
< columnDescriptor caption = "f" type = "image" image = "images / save.png" />
< columnDescriptor caption = "g" type = "link" name = "n3" value = "link" />
< columnDescriptor caption = "h" type = "lookup" name = "n4" aux = "aux4" value = "qwerty" />
< rowDescriptor caption = "r1" />
< rowDescriptor caption = "r2" />
< rowDescriptor caption = "r3" />
</ dataGrid >
</ hgroup >
</ page >
}

Method SrvGetData (
ByRef pParameters ,
Output pMetaData ,
Output pData ) As% Status
{
Set pMetaData = $ LB (1,2,3)

Set pData (1) = $ LB (1,2,3)
Set pData (2) = $ LB (4,5,6)
Set pData (3) = $ LB (7,8,9)

Quit $$$ OK
}

ClientMethod getdata ( context ) [ Language = javascript]
{
zenAlert (ZLM.jsonStringify (context));
return [{id: 'id1' , text: 'text1' }, {id: 'id2' , text: 'text2' }, {id: 'id3' , text: 'text3' }, {id: 'id4' , text: 'text4' }];
}

ClientMethod addRow () [ Language = javascript]
{
var model = zen ( 'json' ). getContentObject ();
var record = {};
for ( var p in model.children [ 0 ]) {
record [p] = 10 ;
}
model.children [model.children.length] = record;
zen ( 'json' ) .setContentObject (model);

var grid = zen ( 'dg2' );
var rowDesc = zenPage.createComponent ( 'rowDescriptor' );
grid.rowDescriptors [grid.rowDescriptors.length] = rowDesc;
rowDesc.caption = 'r' + grid.rowDescriptors.length;
grid.updateGrid (false);
}

ClientMethod addColumn () [ Language = javascript]
{
var grid = zen ( 'dg2' );
var colDesc = zenPage.createComponent ( 'columnDescriptor' );
grid.columnDescriptors [grid.columnDescriptors.length] = colDesc;
colDesc.caption = 'c' + grid.columnDescriptors.length;
colDesc.value = grid.columnDescriptors.length +3 ;
grid.updateGrid (false);

var model = zen ( 'json' ). getContentObject ();
for ( var n = 0 ; n < model.children.length; n ++ ) {
if (model.children [n]) {
model.children [n] [grid.getColumnCount ()] = n;
}
}
zen ( 'json' ) .setContentObject (model);
}

}
Screenshots of <dataGrid>
β„– 1
β„– 1

β„– 2
β„– 2

Number 3
Number 3

Download the source of all the examples.
PS: Of course, you can change the standard appearance of the component to your taste, changing their styles, or you can create your own components, inheriting from the existing ones, if you need to expand their functionality, the benefit of the object DBMS easily allows you to do this.

Source: https://habr.com/ru/post/181131/


All Articles