TeamWox SDK: Построение пользовательского интерфейса

Введение

В предыдущей статье TeamWox SDK: Как добавить страницу в модуль TeamWox вы узнали, как в модуль добавляются страницы, а также ознакомились с простейшим способом вывода данных.

В этой статье мы рассмотрим, каким образом в системе TeamWox с помощью элементов управления создается пользовательский интерфейс. Также мы затронем использование шаблонов - как с их помощью задать формат и порядок вывода данных, а также указать параметры оформления страниц.

Для построения пользовательского интерфейса с помощью библиотеки компонентов TeamWox используется язык программирования JavaScript.

 

Библиотека JavaScript-компонентов TeamWox для построения пользовательского интерфейса

Пользовательский интерфейс создается из готовых типовых элементов управления, доступных в JavaScript библиотеке TeamWox. Напомним, что прежде всего в исходном коде страницы необходимо организовать вывод данных через файл шаблона (пример кода из предыдущей статьи):

//+------------------------------------------------------------------+
//| Обработка запроса                                                |
//+------------------------------------------------------------------+
TWRESULT CPageReference::Process(const Context *context,IServer *server,const wchar_t *path)
  {
//--- проверки
   if(context==NULL || path==NULL) ReturnError(RES_E_INVALID_ARGS);
   if(context->request==NULL)      ReturnError(RES_E_INVALID_CONTEXT);
//--- получаем сервер
   if(server==NULL)                ReturnError(RES_E_FAIL);
//---
   m_server=server;
//--- отображаем страницу
   return(server->PageProcess(context, L"templates\\number3.tpl", this, TW_PAGEPROCESS_NOCACHE));
  }

Поскольку страницы модуля отображаются в браузере, их шаблоны должны соответствовать стандарту HTML, т.е. включать в себя базовые теги <html></html>, <head></head> и <body></body>.

Чтобы иметь возможность использовать JavaScript-компоненты из библиотеки TeamWox, в tpl-файл шаблона страницы необходимо добавить код инициализации этой библиотеки:

<script type="text/javascript">
   top.TeamWox.Start(window);
</script>

Таким образом, мы инициализируем базовый объект TeamWox. Все остальные объекты наследуются от него и получают все его свойства и методы. Выполнение этого скрипта должно включаться в шаблон каждой страницы модуля.

 

Добавление элемента управления

Для создания всех элементов управления используется единый метод TeamWox.Control(), который выглядит следующим образом:

TeamWox.Control("controlType","controlProperty", ...)

где:

  • controlType - Тип добавляемого элемента управления (например, это может быть шапка страницы, текст, таблица, форма для ввода данных и т.д.;

  • controlProperty - Свойство элемента управления. Свойств может быть произвольное количество, все зависит от конкретного типа элемента управления.

Все экземпляры элементов управления располагаются на странице в порядке их создания. Каждый элемент управления обладает следующими методами:

.Append("onclick", function() { alert("Hello World!") }) - добавляет обработчик события;
.Remove("onclick") - удаляет обработчик события;
.Style( {width: "80px", "padding-top": "4px" } ) - устанавливает стиль;
.Title("<lngj:TRANSLATION/>") - всплывающая подсказка для элемента управления;
.Class("header-decor", false) - добавляет или удаляет CSS-класс;
.Attr("page-id", 12) - устанавливает произвольный атрибут для элемента управления;
.Document() - возвращает DOM документ, к которому относится элемент управления;
.Window() - возвращает браузерное окно, к которому относится элемент управления.

Рассмотрим процесс разработки интерфейса на примере страницы PageNumberTwo из учебного модуля Hello World.

Рис. 1. Страница PageNumberTwo

Эта страница состоит из трех основных элементов управления: шапки, текстового блока и таблицы с данными. Рассмотрим детально, как создается каждый из этих элементов. Для этого откройте в текстовом редакторе шаблон страницы - файл number2.tpl.

 

Шапка страницы - это стандартный элемент интерфейса TeamWox, который включает в себя основные команды, строку поиска, кнопки фильтрации и помощи. Шапка должна присутствовать на каждой странице.

Рис. 2. Шапка страницы

Шапка страницы создается с помощью элемента управления типа PageHeader:

TeamWox.Control("PageHeader","#41633C")
       .Command("<lngj:MENU_HELLOWORLD_LIST>","/helloworld/index","<lngj:MENU_HELLOWORLD_LIST>")
       .Search(65536)
       .Help("/helloworld/index");

У элемента управления PageHeader имеется только одно свойство - шестнадцатеричный код цвета, с которого начинается градиентная заливка полосы по вертикали (снизу вверх, с затемнением указанного цвета).

С помощью метода Command создается команда (т.е. ссылка), которая осуществляют переход на главную страницу модуля. Первый параметр команды - это текст ссылки, второй - ее адрес, а третий - текст всплывающей подсказки при наведении на команду курсора мыши. Текст ссылок представлен в виде системных токенов переводов.

Метод Search добавляет строку поиска. В качестве параметра этому методу передается id модуля.

Метод Help добавляет кнопку-ссылку, которая открывает раздел в справке. В качестве параметра указывается ссылка на раздел в справке.

 

Text - блок с текстом

Иногда может потребоваться вывести часть страницы, которая оформлена с использованием средств HTML (например, описание таблицы).

Рис. 3. Блок с текстом

В таких случаях блоки текста вставляются с помощью элемента управления типа Text:

TeamWox.Control("Text","<strong><lngj:HELLOWORLD_INFO/></strong>","html")
       .Style({"font-size":"24px", "padding-top":"12px"});

Первым параметром задается сам текст. Если при этом используются HTML тэги, то необходимо указать второй параметр - html. Обратите внимание, что в этом элементе управления мы вызвали метод .Style(), который задает размер текста и его отступ.

Примечание: Не рекомендуется использовать этот элемент управления для создания блоков текста со сложным форматированием (с различными цветами и гарнитурами шрифтов).

 

ViewTable - таблица с данными

Таблицы создаются с помощью элемента управления типа ViewTable:

TeamWox.Control("ViewTable",ids,headers,data);

Первый параметр ids - это идентификаторы столбцов, второй headers - текстовые заголовки столбцов, третий data - массив данных, которыми заполняется таблица. В нашем примере таблица содержит имена и сроки правления пяти первых президентов США:

Рис. 4. Таблица

Рассмотрим реализацию этой таблицы в шаблоне:

//+----------------------------------------------+
//| Таблица с общедоступной информацией          |
//+----------------------------------------------+

//--- Конфигурация таблицы
var table_cfg =
{
   //--- Заголовки столбцов
   id:     ['number','name'],
   header: [
               {id:'number', content:'<lng:HELLOWORLD_POSITION/>', style:'width:20px'},
               {id:'name',   content:'<lng:HELLOWORLD_NAME/>'}
           ]
};
//--- Функция записи данных из менеджера в таблицу (массив)
function RecordToTable(data)
{
   var records = [];
   for(var i in data)
      //--- Записываем данные в массив records
      records.push([
         {id:'number', content:data[i].id},
         {id:'name',   content:TeamWox.StrSafe(data[i].name)}
                  ]);
   //---
   return records;
}
//--- Создание таблицы и заполнение ее данными
TeamWox.Control("ViewTable",table_cfg.id,table_cfg.header, RecordToTable(<tw:info_list/>))
//--- Токен info_list передает данные из менеджера модуля в функцию RecordToTable,
//    которая возвращает массив для отображения в таблице

Для начала создается объект table_cfg, определяющий конфигурацию таблицы - это количество столбцов, их идентификаторы, имена заголовков, ширина. Затем создается функция RecordToTable(), которая подготавливает данные в виде массива для его последующего отображения в таблице.

Наконец, создается элемент управления типа ViewTable, который создает таблицу по конфигурации table_cfg и заполняет ее данными, передаваемыми функции RecordToTable() в качестве параметра. Обратите внимание, что параметром функции в данном примере является токен <tw:info_list/>.

 

Шаблоны - средство вывода данных на страницу

Вывод данных через шаблоны страниц осуществляется с помощью токенов TeamWox. Токены создаются в исходном коде страниц модуля.

По своему виду в шаблоне токены напоминают HTML-тэги (открытые и закрытые), однако путать их нельзя. Токен TeamWox начинается с угловой скобки (<), затем идет префикс (tw, tws или lngj - подробности см. далее), затем после двоеточия (:) идет значение токена, затем (опционально) следуют атрибуты токена в виде свойство="значение", после чего токен завершается угловой скобкой (>), либо косой чертой и угловой скобкой (/>). В первом случае (>) токен считается открытым (содержащим дочерние элементы-токены), во втором случае (/>) — закрытым (без дочерних элементов-токенов).

Обработка текстового файла шаблона идет последовательно, сверху вниз. Когда в шаблоне встречается токен, управление передается классу страницы. После его обработки возвращается либо значение true (в этом случае обрабатываются его дочерние токены и текстовые тэги), либо false (обработка токена завершается).

 

Вывод данных из менеджера модуля на страницу

Рассмотрим реализацию токена <tw:info_list/>, с помощью которого наша таблица заполняется данными. Токен <tw:info_list/> создан в исходном коде страницы PageNumberTwo.cpp. Откройте его и перейдите в раздел Обработка тэга:

//+------------------------------------------------------------------+
//| Обработка тэга                                                   |
//+------------------------------------------------------------------+
bool CPageNumberTwo::Tag(const Context *context,const TagInfo *tag)
  {
//--- проверки
   if(context==NULL || tag==NULL || m_server==NULL)  return(false);
   if(context->request==NULL || context->user==NULL) return(false);
//---
   wchar_t tmp[64]={0};
//---
   if(TagCompare(L"info_list",tag))
     {
      CJSON json(context->response);
      json << CJSON::ARRAY;
      for(int i=0;i<m_info_count;i++)
        {
         json << CJSON::OBJECT;
         //---
         json << L"id"   << m_info[i].id;
         json << L"name" << m_info[i].name;
         //---
         json << CJSON::CLOSE;
        }
      //---
      json << CJSON::CLOSE;
      //---
      return(false);
     }

Поскольку данные сервером выдаются в формате JSON (JavaScript Object Notation), удобном для автоматической обработки, нам потребуется в качестве ответа на запрос сформировать простой двумерный массив из пар ключ/значение. Для удобного и безопасного вывода данных в формате JSON используется класс CJSON, входящий в поставку TeamWox SDK.

Все токены на странице обрабатывается с помощью метода Tag(), в котором с помощью функции TagCompare() каждый токен проверяется на соответствие обрабатываемому имени.

В нашем случае - это токен с именем info_list. С его помощью мы будем отправлять данные от сервера на страницу. В нем создается объект json, который представляет собой текст ответа в формате JSON.

Создается массив (CJSON::ARRAY - в тексте JSON ответа создается открывающая квадратная скобка [). Каждый объект в массиве содержит две пары ключ/значение. Первая пара будет содержать номер (id), а вторая - текст (name). Для каждого объекта сначала открывается фигурная скобка { (CJSON::OBJECT), затем ставится запятая , (если есть следующий элемент массива), после чего фигурная скобка закрывается } (CJSON::CLOSE). Как только массив будет заполнен, он также закрывается квадратной скобкой ] (CJSON::CLOSE).

Данные для массива берутся из менеджера (подробнее см. исходный код менеджера - файл Managers\HelloWorldManager.cpp). Таким образом, токен info_list отправляет ответ следующего вида:

[
 {"id":1,"name":"George Washington (April 30, 1789 - March 4, 1797)"},
 {"id":2,"name":"John Adams (March 4, 1797 - March 4, 1801)"},
 {"id":3,"name":"Thomas Jefferson (March 4, 1801 - March 4, 1809)"},
 {"id":4,"name":"James Madison (March 4, 1809 - March 4, 1817)"},
 {"id":5,"name":"James Monroe (March 4, 1817 - March 4, 1825)"}
]

Это и есть простой, человеко-понятный формат данных, который также легко и естественно обрабатывается объектом типа ViewTable.

 

Заключение

В этой статье мы рассмотрели лишь три элемента управления из библиотеки TeamWox. Вот еще некоторые из них:

  • PageNumerator - Номера страниц с возможностью переключения;
  • Form - Форма ввода;
  • Input.text - Ввод простого текста;
  • Input.rte - Ввод текста с возможностью форматирования;
  • Input.combobox - Выпадающий список;
  • Input.comboedit - Выпадающий список с возможностью ввода;
  • Input.date - Дата;
  • Calendar - Календарь.

2010.10.01