Pull to refresh
0
InterSystems
InterSystems IRIS: СУБД, ESB, BI, Healthcare

Новые визуальные HTML5 ZEN-компоненты в СУБД Caché 2013.2

Reading time31 min
Views3.8K
Стоит отметить, что новые визуальные HTML5 компоненты, интерфейс которых оптимизирован в том числе и под мобильные устройства, и которые используют формат JSON для получения данных, появились уже в СУБД Caché версии 2013.1, но не все из них пока работают «в полную силу».

Это такие компоненты как:

  • %ZEN.Component.accordionMenu
  • %ZEN.Component.toolbar
  • %ZEN.Component.navigator
  • %ZEN.Component.lookup
  • %ZEN.Component.dataGrid

В справочнике классов вы можете найти всю документацию по этим компонентам. Здесь же будут приведены несколько вводных примеров их использования (со скриншотами).

Пример №1: <accordionMenu>


Данный компонент представляет собой специальное меню с максимально допустимым числом уровней равным три.
В примере используется два компонента: один получает данные с клиента, другой — с сервера.
Пример кода для <accordionMenu>
Class html5.test1 Extends %ZEN.Component.page
{

/// Этот блок Style содержит определение CSS-стиля страницы.
XData 
Style
{
<
style type="text/css">
</
style>
}

/// Этот XML блок описывает содержимое этой страницы.
XData 
Contents [ XMLNamespace "www.intersystems.com/zen" ]
{
<
page xmlns="www.intersystems.com/zen" title="">
<
jsonProvider id="json" OnGetArray="SrvGetData"/>
<
hgroup cellVAlign="top">

<!-- Получение данных с сервера -->
<accordionMenu controllerId="json" onselect="zenPage.selectList(key,action,targetId);" selectedIndex="2"/>

<!-- Получение данных с клиента -->
<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 pDataAs %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);
}

}
Скриншоты <accordionMenu>
№ 1
№ 1

№ 2
№ 2

№ 3
№ 3

Пример №2: <toolbar>


Данный компонент представляет собой подвид меню с поддержкой разнообразных типов подпунктов.
В примере используется два компонента: один представляет собой простейший случай, другой — более расширенный с переопределением некоторых встроенных стилей.
Пример кода для <toolbar>
Class html5.test2 Extends %ZEN.Component.page
{

/// Этот блок Style содержит определение CSS-стиля страницы.
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>
}

/// Этот XML блок описывает содержимое этой страницы.
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'}
    ]
  };
}

}
Скриншоты <toolbar>
№ 1
№ 1

№ 2
№ 2

Пример №3: <navigator>


Данный компонент предоставляет богатый интерфейс, заточенный под мобильные устройства, где каждый элемент меню управляется определённым типом с настраиваемыми параметрами присущими данному типу.
Имеется возможность вставлять собственный html в подпункты, если встроенных типов недостаточно.
Некоторые типы элементов позволяют совершать переходы на следующие уровни, которые в свою очередь могут содержать свои элементы меню. Глубина вложенности для перехода типа drill неограничена.
На каждом уровне доступны свои собственные верхние и нижние колонтитулы.
Элементы меню можно передвигать, используя drag&drop; есть готовые методы для выбора цвета и шрифта.
Кроме того, доступны обработчики событий для «пальцевого» управления.
Пример кода для <navigator>
Class html5.test3 Extends %ZEN.Component.page
{

/// Этот блок Style содержит определение CSS-стиля страницы.
XData 
Style
{
  <
style type="text/css">
  </
style>
}

/// Этот XML блок описывает содержимое этой страницы.
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
='Заголовок';
    
    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
='Изображение';
    
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
='Цвет';
    content.html
=zen('navigator').getColorChooserHTML(key,value,'html');
  }
else if(key=='keyFont'){
    content.title
='Шрифт';
    content.html
=zen('navigator').getFontChooserHTML(key,value);
  }
else if(key=='keyText1'){
    content.title
='Текст1';
    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
='Текст2';
    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:
'Заголовок', value:'v1', hint:'Использовать заголовок'},
      { caption:
'Категория', value:'v2', hint:'Использовать категорию'},
      { caption:
'Тип', value:'v3', hint:'Использовать тип'},
    ];
    content.html 
zen('navigator').getChooserListHTML(list,key,value,'Текстовые теги','Это специальные теги.');
  }
  
return content;
}

/// Убеждаемся, что мы заставляем Internet Explorer использовать последний движок рендеринга.
Method 
%OnDrawHTMLMeta() As %Status
{
  
If $$$ZENISIE &html<<meta http-equiv="X-UA-Compatible" content="IE=edge" />>
  
Quit $$$OK
}

}
Скриншоты <navigator>
№ 1
№ 1

№ 2
№ 2

№ 3
№ 3

№ 4
№ 4

№ 5
№ 5

№ 6
№ 6

№ 7
№ 7

Пример №4: <lookup>


Данный компонент представляет собой выпадающий список с возможностью быстрого поиска нужного элемента.
Элементы списка могут содержать несколько столбцов и картинки.
Поиск осуществляется по всем столбцам.
Данный компонент используется в следующем, более сложном компоненте.
Пример кода для <lookup>
Class html5.test4 Extends %ZEN.Component.page
{

/// Этот блок Style содержит определение CSS-стиля страницы.
XData 
Style
{
  <
style type="text/css">
  </
style>
}

/// Этот XML блок описывает содержимое этой страницы.
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<<meta http-equiv="X-UA-Compatible" content="IE=edge" />>
  
Quit $$$OK
}

}
Скриншоты <lookup>
№ 1
№ 1

№ 2
№ 2

№ 3
№ 3

Пример №5: <dataGrid>


Данный компонент представляет собой упрощённый аналог электронной таблицы для работы с данными, где столбцы могут иметь различные типы: картинки, выпадающие списки и т.д.
Также поддерживаются формулы и страницы.
Пример кода для <dataGrid>
Class html5.test5 Extends %ZEN.Component.page
{

Parameter JSINCLUDES As STRING = "zenCSLM.js";

/// Этот XML блок описывает содержимое этой страницы.
XData 
Contents [ XMLNamespace "www.intersystems.com/zen" ]
{
  <
page xmlns="www.intersystems.com/zen" title="">
    <
jsonProvider id="json" OnGetArray="SrvGetData"/>
    <
hgroup>
      <
button caption="Добавить строку" onclick="zenPage.addRow();"/>
      <
button caption="Добавить столбец" onclick="zenPage.addColumn();"/>
    </
hgroup>
    <
hgroup>
      <
dataGrid
        
controllerId="json"
        
selectMode="cells"
        
hasFormulas="false"
        
currRow="2"
        
currColumn="2"
        
gridTitle="Заголовок1"
        
multiSelect="false">
        <
summaryRow caption="Сумма"/>
      </
dataGrid>
      <
dataGrid
        
id="dg2"
        
selectMode="cells"
        
currRow="1"
        
currColumn="3"
        
gridTitle="Заголовок3"
        
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 pDataAs %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 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 = 0; n model.children.length; n++) {
    
if (model.children[n]) {
      model.children[n][grid.getColumnCount()] 
n;
    }
  }
  zen(
'json').setContentObject(model);
}

}
Скриншоты <dataGrid>
№ 1
№ 1

№ 2
№ 2

№ 3
№ 3

Скачать исходники всех примеров.
PS: конечно же, вы можете изменить стандартный внешний вид компонент под свой вкус, поменяв у них стили, или же можно создать собственные компоненты, унаследовавшись от существующих, если нужно расширить их функциональность, благо объектная СУБД легко позволяет это сделать.
Tags:
Hubs:
+4
Comments0

Articles

Change theme settings

Information

Website
www.intersystems.com
Registered
Founded
1978
Employees
1,001–5,000 employees
Location
США