Визуальные компоненты
N2O - компонентно-ориентированный фреймворк. Визуальные компоненты разработаны на React. Компоненты имеют иерархическую структуру.
Структура приложения
Структура приложения - описание компонентов общих для всего приложения:
заголовок с навигацией, боковая панель, подвал.
Структура приложения задается в файле *.application.xml
.
Обычно в приложении существует только один файл application.xml
Если их несколько, то необходимо задать идентификатор структуры приложения в настройке n2o.application.id
.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0"
welcome-page-id="index">
<header>
...
<header>
<sidebars>
...
</sidebars>
<footer>
...
</footer>
</application>
Шапка (header)
Шапка (header) - это заголовок каждой страницы, содержащий логотип и название, меню навигации, меню пользователя и строку поиска по приложению.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<header title="Мое приложение">
<nav>
...
</nav>
<extra-menu>
...
</extra-menu>
</header>
</application>
Боковая панель
Боковая панель - содержит меню навигации, может содержать логотип и название.
Боковая панель задается в файлах вида *.sidebar.xml
:
<?xml version='1.0' encoding='UTF-8'?>
<sidebar xmlns="http://n2oapp.net/framework/config/schema/sidebar-3.0"
subtitle="Simple subtitle"
path="/hello"
toggle-on-hover="true"
home-page-url="/home">
...
<nav>
<menu-item name="test"/>
</nav>
...
</sidebar>
Либо перечисляются в элементе <sidebars>
.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<sidebars>
<sidebar title="Мое приложение">
<nav>
...
</nav>
<extra-menu>
...
</extra-menu>
</sidebar>
</sidebars>
</application>
На боковую панель, заданной в отдельном файле, можно ссылаться
через атрибут ref-id
в элементах <sidebar>
:
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<sidebars>
<sidebar path="/home" ref-id="homeSidebar">
...
</sidebar>
<sidebar ref-id="profileSidebar"/>
</sidebars>
</application>
На странице отобразится та боковая панель, атрибут path
которой совпадет с адресом этой страницы.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<sidebars>
<sidebar path="/home" title="Домашняя страница">
<nav>
...
</nav>
<extra-menu>
...
</extra-menu>
</sidebar>
<sidebar path="/profile" title="Стра ница профиля">
<nav>
...
</nav>
</sidebar>
</sidebars>
</application>
На странице отобразится та боковая панель, атрибут path
которой совпадет с адресом этой страницы.
В случае, если path
не указан, то боковая панель будет отображаться во всем приложении, кроме тех страниц, для которых заданы конкретные боковые панели.
Задание путей через шаблоны
В качестве атрибута path
можно использовать шаблонные пути с использованием *
и **
:
-
*
используется для замены одного ресурса в пути. Например, паттерн/person/*/profile
отобразит боковую панель на страницах, пути которых соответствуют шаблону, под данный критерий попадут следующие пути:/person/1/profile
или/person/person1/profile
, но не/person/1/profile/img
. -
**
используется для замены одного и более ресурсов в пути. Например, паттерн/person/**
отобразит боковую панель на всех страницах, путь которых начинается с/person/
, кроме тех страниц, для которых заданы конкретные боковые панели.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<sidebars>
<sidebar path="/person/list" title="Список пользователей">
<nav>
...
</nav>
<extra-menu>
...
</extra-menu>
</sidebar>
<sidebar path="/person/*/profile" title="Профиль пользователя">
<nav>
...
</nav>
<extra-menu>
...
</extra-menu>
</sidebar>
<sidebar path="/profile/**" title="Другие страницы пользователей">
<nav>
...
</nav>
</sidebar>
</sidebars>
</application>
Подвал (footer)
Подвал (footer) - информация, отображаемая внизу страницы.
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<footer left-text="N2O ${n2o.version}"/>
</application>
Меню навигации
Меню навигации задаётся в файлах вида *.menu.xml
:
<?xml version='1.0' encoding='UTF-8'?>
<nav xmlns="http://n2oapp.net/framework/config/schema/menu-3.0">
<menu-item id="mi1" name="Первая страница">
<open-page page-id="menu1"/>
</menu-item>
<menu-item id="mi2" name="Вторая страница">
<open-page page-id="menu2"/>
</menu-item>
...
</nav>
Либо перечисляется внутри элементов <nav>
и <extra-menu>
шапки или боковой панели:
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<header title="Мое приложение">
<nav>
<menu-item id="mi1" name="Первая страница">
<open-page page-id="menu1"/>
</menu-item>
<menu-item id="mi2" name="Вторая страница">
<open-page page-id="menu2"/>
</menu-item>
</nav>
</header>
<sidebars>
<sidebar title="Мое приложение">
<extra-menu>
<menu-item id="mi1" name="Первая страница">
<open-page page-id="menu1"/>
</menu-item>
<menu-item id="mi2" name="Вторая страница">
<open-page page-id="menu2"/>
</menu-item>
</extra-menu>
</sidebar>
</sidebars>
</application>
На меню на вигации, заданному в отдельном файле, можно ссылаться
через атрибут ref-id
в элементах <nav>
и <extra-menu>
шапки или боковой панели:
<?xml version='1.0' encoding='UTF-8'?>
<application xmlns="http://n2oapp.net/framework/config/schema/application-3.0">
<header title="Мое приложение">
<nav ref-id="myMenu"/>
</header>
<sidebars>
<sidebar title="Мое приложение">
<extra-menu ref-id="myMenu"/>
</sidebar>
</sidebars>
</application>
Виды меню навигации
Вид | Описание |
---|---|
<menu-item> | Ссылка на страницу |
<dropdown-menu> | Вложенное меню |
Страница
Приложения на N2O состоят из страниц.
Страницы задаются в файлах вида *.page.xml
.
Страницы могут иметь простую или сложную разметку.
Простая страница содержит один-единственный компонент-виджет, занимающий всё свободное пространство.
<simple-page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<form>...</form><!-- Виджет -->
</simple-page>
Сложные страницы поделены на регионы, которые могут располагаться в разных областях страницы.
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<regions>
<!-- Регионы -->
</regions>
</page>
<?xml version='1.0' encoding='UTF-8'?>
<left-right-page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<left>
<panel>...</panel>
</left>
<right>
<panel>...</panel>
</right>
</left-right-page>
<?xml version='1.0' encoding='UTF-8'?>
<top-left-right-page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<top>
<panel>...</panel>
</top>
<left width="30%">
<panel>...</panel>
</left>
<right width="70%">
<panel>...</panel>
</right>
</top-left-right-page>
<?xml version='1.0' encoding='UTF-8'?>
<searchable-page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<search-bar search-filter-id="name" search-param="name"/>
<regions>
<!-- Регионы -->
</regions>
</searchable-page>
Виды страниц
Вид | React компонент | Описание |
---|---|---|
<simple-page> | SimplePage | Страница с единственным виджетом |
<page> | StandardPage | Страница с регионами |
<left-right-page> | LeftRightPage | Страница с разметкой регионов "слева и справа" |
<top-left-right-page> | TopLeftRightPage | Страница с разметкой регионов "сверху, слева и справа" |
<searchable-page> | SearchablePage | Страница с поисковой строкой |
Хлебные крошки (breadcrumbs)
На любой из вышеуказанных страниц можно разместить навигационную цепочку — хлебные крошки.
N2O позволяет генерировать хлебные крошки для открываемой страницы автоматически,
используя при этом названия и ссылки страниц предшествующих данной по порядку открытия.
За использование автоматической генерации на всех страницах отвечает настройка n2o.api.page.breadcrumbs
,
которая по умолчанию равна true. При переопределении значения данной настройки возможность
использования автоматической генерации на отдельной странице сохраняется, достаточно указать
закрытый тег <breadcrumbs/>
на этой странице
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<breadcrumbs/>
</page>
С помощью XML api можно сконфигурировать произвольную вложенность хлебных крошек
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<breadcrumbs>
<crumb label="Первая страница" path="/"/>
<crumb label="Вторая страница" path="/page2"/>
<crumb label="Третья страница"/>
</breadcrumbs>
</page>
В атрибуте path
задается путь внутри приложения, если данный атрибут не указан, то крошка будет некликабельной.
Также в path
можно использовать относительные пути с помощью плейсхолдера ../
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
name="Моя страница">
<breadcrumbs>
<crumb label="Первая страница" path="../../"/> <!-- 2 пути назад -->
<crumb label="Вторая страница" path="../"/> <!-- 1 путь назад -->
<crumb label="Третья страница"/>
</breadcrumbs>
</page>
В лейблах и путях хлебной крошки допускается использование параметров. При этом параметры в лейблах и в названии страницы разрешаются на клиенте с помощью источника данных страницы.
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0"
datasource="ds1"
model="resolve"
title="Страница {name}"> <!-- Параметр name разрешается на клиенте с помощью источника данных ds1 -->
<breadcrumbs>
<crumb label="Первая страница" path="/"/>
<crumb label="Вторая страница" path="/:id/page2"/> <!-- Параметр id разрешается согласно параметру пути -->
<crumb label="Третья {name} страница"/> <!-- Параметр name разрешается на клиенте с помощью источника данных ds1 -->
</breadcrumbs>
...
</page>
Также навигационную цепочку можно задать внутри элементов действий открытия страниц. Заданные таким образом хлебные крошки полностью заменят хлебные крошки открываемой страницы. При этом все используемые параметры должны ссылаться на текущую страницу, в которой определено действие открытия страницы
<button label="Изменить"
datasource="buttonDs"
model="resolve">
<open-page page-id="page3"
route="/:person_id/page3"
page-name="Страница {name}"> <!-- Параметр name разрешается с помощью источника данных buttonDs -->
<params>
<path-param name="person_id" value="{id}"/>
</params>
<breadcrumbs>
<crumb label="Первая страница" route="/"/>
<crumb label="Вторая страница" route="/:id/page2"/> <!-- Параметр id разрешается согласно параметру пути -->
<crumb label="Третья {name} страница"/> <!-- Параметр name разрешается с помощью источника данных buttonDs -->
</breadcrumbs>
</open-page>
</button>
Регион
В регион могут вкладываться произвольное количество виджетов и регионов. Регионы имеют свою верстку для различной компоновки виджетов.
<regions>
<tabs>
<!-- Вкладки -->
<tab name="Один">...</tab>
<tab name="Два">...</tab>
...
</tabs>
</regions>
Виды регионов
Вид | React компонент | Описание |
---|---|---|
<region> | NoneRegion | Виджеты без обрамления |
<tabs> | TabsRegion | Виджеты во в кладках |
<panel> | PanelRegion | Виджеты в панелях |
<line> | ListRegion | Горизонтальная черта над виджетом |
Виджет
Виджеты отображают и управляют данными одного объекта.
Виджеты задаются в файлах вида *.widget.xml
:
<?xml version='1.0' encoding='UTF-8'?>
<table xmlns="http://n2oapp.net/framework/config/schema/widget-5.0"
name="Моя таблица">
...
</table>
Можно вкладывать виджеты в страницу:
<?xml version='1.0' encoding='UTF-8'?>
<simple-page xmlns="http://n2oapp.net/framework/config/schema/page-4.0">
<table name="Моя таблица">
...
</table>
</simple-page>
Или в регион:
<?xml version='1.0' encoding='UTF-8'?>
<page xmlns="http://n2oapp.net/framework/config/schema/page-4.0">
<regions>
<table name="Моя таблица">
...
</table>
</regions>
</page>
Виды основных виджетов
Вид | React компонент | Описание |
---|---|---|
<form> | FormWidget | Форма |
<table> | TableWidget | Таблица |
<list> | ListWidget | Список |
<tree> | TreeWidget | Дерево |
<html> | HtmlWidget | Html |
<cards> | CardsWidget | Карточки |
<tiles> | TilesWidget | Плитки |
Описание других виджетов можно посмотреть здесь.
Таблица
Таблица - виджет N2O, представляющий данные в виде таблицы с возможностью сортировки, фильтрации, паджинации.
<?xml version='1.0' encoding='UTF-8'?>
<table xmlns="http://n2oapp.net/framework/config/schema/widget-5.0"
name="Моя таблица">
<datasource query-id="table"/>
<columns>
<column text-field-id="firstName" label="Имя"/>
<column text-field-id="lastName" label="Фамилия"/>
</columns>
</table>
Столбцы таблицы задаются внутри элемента <columns>
.
В выборке для таблицы обязательно должно быть поле id.
Без id нельзя будет выбрать конкретную запись и совершить с ней какие-либо действия.
Если в таблице записи будут иметь одинаковые id, то все они будут одновременно выделены.
id можно сгенерировать, используя <field id="id" select="false"/>
.
Форма
Форма - виджет N2O, представляющий одну запись данных в виде полей с возможностью просмотр а или редактирования.
<?xml version='1.0' encoding='UTF-8'?>
<form xmlns="http://n2oapp.net/framework/config/schema/widget-5.0"
name="Моя форма">
<fields>
<input-text id="firstName" label="Имя"/>
<input-text id="lastName" label="Фамилия"/>
</fields>
</form>
Поля формы задаются внутри элемента <fields>
.
Кнопки
В N2O можно вызывать различные действия над виджетами: открытие страниц, ссылок, выполнение запросов на сервер и т.п.
Панель кнопок
Кнопки задаются в теле виджета внутри панели инструментов <toolbar>
:
<table>
<toolbar>
<button>...</button>
<button>...</button>
...
</toolbar>
</table>
Элемент <toolbar>
так же можно задать на странице:
<page>
<toolbar>
<button>...</button>
<button>...</button>
...
</toolbar>
</page>
В этом случае в кнопках необходимо уточнить над каким источником данн ых они выполняют действия:
<page>
<toolbar>
<button datasource="main">...</button>
</toolbar>
</page>
Можно задать местоположение панели кнопок через атрибут place
:
<toolbar place="topLeft">
...
</toolbar>
<toolbar place="bottomRight">
...
</toolbar>
Местоположение панели кнопок зависит от реализации React компонента страницы и виджета.
Кнопки можно соединять в группы:
<toolbar>
<group>
<button>...</button>
<button>...</button>
...
</group>
<group>
...
</group>
</toolbar>
Кнопка
Кнопка - это визуальный элемент, на который можно нажать для выполнения действия. Кнопка может иметь разный размер, цвет, верстку:
<button label="Кнопка"/>
<button label="Кнопка с иконкой" icon="fa fa-plus"/>
<button description="Иконка" icon="fa fa-pencil"/>
<button label="Главная" color="primary"/>
<button label="Опасная" color="danger"/>
<button label="Ссылка" color="link"/>
<sub-menu label="Меню">
<menu-item label="Один">...</menu-item>
<menu-item label="Два">...</menu-item>
</sub-menu>
Кнопка является React компонентом и имеет несколько реализаций:
Виды кнопок
Вид | React компонент | Описание |
---|---|---|
<button> | PerformButton | Кнопка с действием |
<sub-menu> | DropdownButton | Кнопка с вложенным меню |
Филдсеты
Филдсеты группируют поля
и другие филдсеты со своей вёрсткой и логикой.
Филдсеты задаются в файлах вида *.fieldset.xml
.
<?xml version='1.0' encoding='UTF-8'?>
<set xmlns="http://n2oapp.net/framework/config/schema/fieldset-5.0">
...
</set>
Либо можно задать филдсет внутри формы:
<form>
<fields>
<set>
...
</set>
</fields>
</form>
Виды филдсетов
Вид | React компонент | Описание |
---|---|---|
<set> | StandardFieldset | Простой филдсет |
<line> | LineFieldset | Филдсет с горизонтальной чертой |
<multi> | MultiFieldset | Филдсет с динамическим числом полей |
В филдсете поля можно расположить в строку или столбец
с помощью элементов <row>
и <col>
.
<fields>
<set>
<row>
<!-- Первая строка с двумя столбцами -->
<col size="8">
... <!-- Поля первого столбца -->
</col>
<col size="4">
... <!-- Поля второго столбца -->
</col>
</row>
<row>
... <!-- Вторая строка -->
</row>
</set>
</fields>
Ширина столбца <col>
задается атрибутом size
.
Всего доступно 12 размеров согласно сетке Bootstrap.
Мульти-филдсеты
Существует возможность создавать филдсеты с динамическим числом полей. При нажатии кнопки добавления в филдсет будет добавлено еще одно поле или набор полей. Также имеется возможность удаления полей и копирования.
С помощью {index}
можно управлять нумерацией заголовков дочерних элементов
(Например: "Участник 1", "Участник 2" и т.д.). По умолчанию нумерация с нуля.
Для задания нумерации с единицы воспользуйтесь выражением {(index + 1)}
.
<form>
<fields>
<multi-set id="members"
children-label="Участник {index}"
add-label="Добавить участника"
can-remove-all="true"
remove-all-label="Удалить всех участников"
can-copy="true">
...
</multi-set>
</fields>
</form>
Идентификатор мультисета id
задает название спискового поля, в котором будут храниться все добавленные группы полей.
<multi-set id="members">
<input-text id="name"/>
...
</multi-set>
в модели данных:
"members": [
{ "name": "one", ... }, //первая группа полей
{ "name": "two", ... }, //вторая группа полей
...
]
Любые зависимости и валидации полей внутри мультисета необходимо задавать с помощью переменной index
.
Индекс определяет текущую группу полей мультисета.
<multi-set id="members">
<input-text id="firstName"/>
<input-text id="lastName">
<dependencies>
<visibility on="members[index].firstName">
members[index].firstName != null
</visibility>
</dependencies>
</input-text>
</multi-set>
Вложенные мультисеты
Обращение к внутреннему контексту в выражениях вложенных мультисетов осуществляется с помощью цепочки индексов $index_N
,
где N - соответствует уровню вложенного мультисета.
set[index].inner_set1[$index_1]...inner_setN[$index_N].field
Для мультисета верхнего уровня используется index
или $index_0
.
Пример
<multi-set id="groups" children-label="Группа {index}">
<multi-set id="persons" children-label="Участник {index}.{$index_1}">
<input-text id="name" label="{index}.{$index_1} Имя"/>
</multi-set>
</multi-set>
Поля ввода
Поля ввода - это простейшие компоненты N2O, предназначенные для ввода или вывода различных данных. Поля могу содержать заголовок, подсказку, сообщения валидации и многое другое.
Поля перечисляются на форме в элементе <fields>
:
<form>
<fields>
<input-text id="name" label="Наименование"/>
</fields>
</form>
Либо вкладываются в филдсет:
<line>
<input-text id="name" label="Наименование"/>
</line>
Все поля должны иметь уникальный в рамках виджета идентификатор id
.
По нему происходит (#_Связывание_с_данными[связывание с данными].
Основные виды полей
Вид | React компонент | Описание |
---|---|---|
<input-text> | InputText InputNumber | Поле ввода текста или чисел |
<output-text> | OutputText | Поле вывода текста |
<checkbox> | Checkbox | Поле чекбокса |
<date-time> | DatePicker | Поле ввода даты и времени |
<select> | Select | Поле выбора из выпадающего списка |
<input-select> | InputSelect | Поле ввода текста с выбором из выпадающего списка |
<radio-group> | RadioGroup | Поле группы радио кнопок |
<checkbox-group> | CheckboxGroup | Поле группы чекбоксов |
<text-area> | TextArea | Многострочное поле ввода |
<input-select-tree> | InputSelectTree | Компонент ввода с выбором в выпадающем списке в виде дерева |
<text> | Text | Компонент текста |
<text-editor> | TextEditor | Компонент редактора текста |
<date-interval> | DateInterval | Компонент ввода интервала дат |
<code-editor> | CodeEditor | Компонент редактора кода |
<file-upload> | FileUpload | Компонент загрузки файлов |
<slider> | Slider | Компонент ползунок |
<time-picker> | TimePicker | Компонент ввода времени |
Описание других видов полей мо жно посмотреть здесь.
Ячейка
Ячейки - это простейшие компоненты, которые отображают информацию в записях таблицы или списка.
Ячейки встраиваются в столбцы таблицы:
<table>
<columns>
<column text-field-id="birthday">
<text format="date DD.MM.YYYY"/>
</column>
</columns>
</table>
Или в содержимое виджета-списка:
<list>
<content>
<body text-field-id="birthday">
<text format="date DD.MM.YYYY"/>
</body>
</content>
</list>
<switch value-field-id="type">
<case value="type1">
<badge .../>
</case>
<case value="type2">
<icon .../>
</case>
...
<default>
<text/>
</default>
</switch>
Предоставляют возможность использовать различные виды ячеек в колонке в зависимости от условия.
Основные виды ячеек
Элемент | React компонент | Описание |
---|---|---|
<text> | TextCell | Текстовая ячейка |
<badge> | BadgeCell | Ячейка значок |
<icon> | IconCell | Ячейка иконка |
<link> | LinkCell | Ячейка ссылка |
<checkbox> | CheckboxCell | Ячейка чекбокс |
<toolbar> | ToolbarCell | Ячейка с меню кнопок |