| сб 16 Апрель 2011 | | Разместил(а): ib | | Просмотров: 15 |
Рассмотрим разработку справочников информационной системы в ручном режиме на примере справочника "Ингредиенты". Разработка в полуавтоматическом режиме будет рассмотрена на примере разделов "Каталог рецептов" и "Заказы".
2.2. Вкладка "Edit"
2.3. Вкладка "Move"
2.4. Вкладка "Delete"
3.2. Вкладка "Edit"
3.3. Вкладка "Move"
3.4. Вкладка "Delete"
10. Итоги
В предыдущих этапах мы зарегистрировали разделы и формы информационной системы веб-приложения "Каталог рецептов". В разделе "Формы информационной системы" отфильтруем формы по разделу "hcr - [id] - elements - Ингредиенты" и выбирем основную форму (elements - Ингредиенты). У основных форм класс всегда должен быть "Section".
Внесём следующий HTML-код для формы "Ингредиенты":
|
|
Код для копирования:
<div id="frm_elements_elements"> <div id="elements_elements_spt1"> <div id="lr_elements_groups" class="oaf"></div> <div id="lr_elements_elements" class="oaf"></div> </div> <script type="text/javascript"> var spt = $('#elements_elements_spt1'); $(spt).splitter({ sizeLeft: 300, outline: outline, anchorToWindow: true }); </script> </div> |
Здесь frm_elements_elements - id элемента-контейнера, по которому данная форма будет определяться в веб-браузере. Состоит из обязательного префикса frm, кода раздела ИС (elements) и кода формы (elements). elements_elements_spt1 - контейнер для создания сплиттеров на основной форме справочника, программируется через JavaScript, который присутствует в контейнере frm_elements_elements. lr_elements_groups - Контейнер для вставки дерева групп, состоит из обязательного префикса lr, кода формы elements и кода секции данных groups. lr_elements_elements - Контейнер для таблицы ингредиентов.
Далее, добавим и запрограммируем две секции данных - "Группы" и "Ингредиенты":
Заполните основные данные как указано на изображении. Доступные действия заполняются после того, как будет выбран бизнес-объект и добавлена секция данных (создана запись в базе данных):
Для секции данных "Группы" зададим следующие алгоритмы:
<? $sql = 'select f.id, f.number, f.name from hcr_group as f '; ?>
Здесь $sql - переменная, в которой должен быть сформирован SQL-запрос для выгрузки из БД записей из нужной нам таблицы. Таблица, которая реализует дерево папок обязательно должна иметь поле parent_id, а в запросе названа буквой f. Только тогда система автоматически правильно присоединит нужные таблицы, если они потребуются, и сформирует правильные условия выборки (то, что идёт после where).
<?
function seaMain($PKEY_ID, $_MSF, $_SEA, $_FIELDS, $_USER) {
if (!$_FIELDS->name) jxErr('Не указано название группы');
if (!$_FIELDS->number) $_FIELDS->number = nextNum('hcr_group');
if ($_SEA->action == 2) $PKEY_ID = $_SEA->createRec(); else $_SEA->updateRec();
return $PKEY_ID;
}
?>
function seaMain($PKEY_ID, $_MSF, $_SEA, $_FIELDS, $_USER) {
if (!$_FIELDS->name) jxErr('Не указано название группы');
if (!$_FIELDS->number) $_FIELDS->number = nextNum('hcr_group');
if ($_SEA->action == 2) $PKEY_ID = $_SEA->createRec(); else $_SEA->updateRec();
return $PKEY_ID;
}
?>
Здесь seaMain - функция, которая вызывается системой в алгоритмах редактирования. В неё передаются несколько параметров:
$PKEY_ID - ИД редактируемой записи. Если запись добавляется, то $PKEY_ID = -1.
$_MSF - Мета-информация (текущий модуль, раздел, форма, бизнес-объект, секция данных и др.). См. подробности здесь. (TODO: адресовать на отдельную страницу про $_MSF).
$_SEA - Класс для работы с записями (автоматическое добавление/изменение на основании объектных описаний). См. подробности здесь.(TODO: адресовать на отдельную страницу про $_SEA).
$_FIELDS - Список значений полей. Поля доступны как свойства класса, т.е. через ->.
$_USER - Объект с информацией о текущем пользователе. См. подробности здесь. (TODO: адресовать на отдельную страницу про $_USER).
Функция nextNum() возвращает следующий свободный номер. Принимает 4 не обязательных аргумента: function nextNum($tbl = 'folder', $fld = 'number', $fk = 'parent_id', $fk_id = null).
<?
function seaMain($PKEY_ID, $_SEA, $_MSF) {
$qr = new TSQL('update hcr_group set parent_id = ? where (id = ?)', $_SEA->destRecID, $PKEY_ID);
$qr->free();
return 1;
}
function seaMain($PKEY_ID, $_SEA, $_MSF) {
$qr = new TSQL('update hcr_group set parent_id = ? where (id = ?)', $_SEA->destRecID, $PKEY_ID);
$qr->free();
return 1;
}
?>
Это типичный алгоритм перемещения папки из одной в другую папку. Класс TSQL предназначен для работы с базой данных. Позволяет выполнить любой SQL-запрос и получить данные в удобном формате.
<?
function seaMain($PKEY_ID, $_SEA, $_MSF) {
if ($PKEY_ID == $_MSF->root_id) jxErr('Нельзя удалить корневую группу раздела!');
if (getValFromDB('count(*)', 'hcr_elements', 'group_id = '.$PKEY_ID)) jxErr('Ошибка! Удалите или переместите все ингредиенты в группе!');
if (getValFromDB('count(*)', 'hcr_group', 'parent_id = '.$PKEY_ID)) jxErr('Ошибка! Необходимо удалить или переместить все вложенные группы!');
$qr = new TSQL('delete from hcr_group where (id = ?);', $PKEY_ID);
$qr->free();
return 1;
}
?>
function seaMain($PKEY_ID, $_SEA, $_MSF) {
if ($PKEY_ID == $_MSF->root_id) jxErr('Нельзя удалить корневую группу раздела!');
if (getValFromDB('count(*)', 'hcr_elements', 'group_id = '.$PKEY_ID)) jxErr('Ошибка! Удалите или переместите все ингредиенты в группе!');
if (getValFromDB('count(*)', 'hcr_group', 'parent_id = '.$PKEY_ID)) jxErr('Ошибка! Необходимо удалить или переместить все вложенные группы!');
$qr = new TSQL('delete from hcr_group where (id = ?);', $PKEY_ID);
$qr->free();
return 1;
}
?>
Это пример алгоритма удаления одной записи бизнес-объекта. Функция jxErr() генерирует исключительную ситуацию и прерывает выполнение алгоритма. Функция getValFromDB() предназначена для получения значения одного или нескольких полей записи в одной строчке кода.
Заполните основные данные как указано на изображении:
Для секции данных "Ингредиенты" зададим следующие алгоритмы:
<?
$sql = 'select id, code, name from hcr_elements';
?>
$sql = 'select id, code, name from hcr_elements';
?>
<?
function seaMain($PKEY_ID, $_MSF, $_SEA, $_FIELDS, $_USER) {
if ($_SEA->action == 2) {
$PKEY_ID = $_SEA->createRec();
} else {
$_SEA->updateRec();
}
return $PKEY_ID;
}
?>
function seaMain($PKEY_ID, $_MSF, $_SEA, $_FIELDS, $_USER) {
if ($_SEA->action == 2) {
$PKEY_ID = $_SEA->createRec();
} else {
$_SEA->updateRec();
}
return $PKEY_ID;
}
?>
<?
function seaMain($PKEY_ID, $_SEA, $_MSF) {
$qr = new TSQL('update hcr_elements set group_id = ? where (id = ?)', $_SEA->destRecID, $PKEY_ID);
$qr->free();
return 1;
}
?>
function seaMain($PKEY_ID, $_SEA, $_MSF) {
$qr = new TSQL('update hcr_elements set group_id = ? where (id = ?)', $_SEA->destRecID, $PKEY_ID);
$qr->free();
return 1;
}
?>
<?
function seaMain($PKEY_ID, $_SEA, $_MSF) {
if (getValFromDB('count(*)', 'hcr_composition', 'element_id = '.$PKEY_ID)) jxErr('Индигриент используется в рецептах!');
$qr = new TSQL();
$qr->execute('delete from hcr_elements where (id = ?)', $PKEY_ID);
$qr->free();
}
?>
function seaMain($PKEY_ID, $_SEA, $_MSF) {
if (getValFromDB('count(*)', 'hcr_composition', 'element_id = '.$PKEY_ID)) jxErr('Индигриент используется в рецептах!');
$qr = new TSQL();
$qr->execute('delete from hcr_elements where (id = ?)', $PKEY_ID);
$qr->free();
}
?>
Добавим первое поле в секцию данных "Группы" формы "Группы":
|
|
ИД и номер заполняются автоматически. Код прописываем строчными латинскими буквами. Он используется в шаблонах форм редактирования (в т.н. контейнерах). Название отображается в заголовке столбцов грида или дерева. Для наборов данных доступны первые несколько типов полей. Для записей - все. Стили используются для форматирования текста, вот несколько часто используемых стилей: l - (left) выравнивание слева, r - (right) выравнивание справа, cn - (center) выравнивание по центру, jsf - (justify) выравнивание по ширине, pr6 - выравнивание справа +правый отступ 6px (используется для числовых полей), nw - (nowrap) перенос слов запрещён, f6, f6b, f7, f7b, f8, f8b, f8bi, f9, f9b, f9bi, f10 и др. - размер шрифта, жирность, наклон. Например, комбинация "cn f10b nw" означает, что значение в ячейках столбца центрируется, перенос слов запрещён, размер шрифта 10pt, жирность - жирный. Ширина в пикселях указывается для столбцов, если требуется запретить растягивание ячеек по горизонтали. Видимость указывается по умолчанию (какие столбцы будут видны при первом открытии справочника). Остальные поля доступны в зависимости от текущего типа секции данных и выбранного типа поля.
|
Добавим ещё два поля так что бы у нас получился следующий список полей:
После добавления можно менять порядок следования полей. Для этого используются пользовательские действия "Поднять позицию" и "Опустить позицию":
Кнопка "Включить поле в SQL-запрос" предназначена для быстрого изменения поля "Используется в SQL".
Аналогично предыдущему пункту сформируем список полей и для ингредиентов:
|
|
ИД и номер заполняются автоматически. Код прописываем строчными латинскими буквами. Название потом выводится в окне фильтрации слева напротив каждого фильтра. Опция может принимать следующие значения: "Обычный", "Foreign Key" (подстановка ИД записей секций данных, от которых зависит текущая), "ИД группы пользователя", "SAR (tree/grid) по таблице" (подключается к таблице-гриду, что бы выводить только те записи, которые доступны при отключённом фильтре "С учётом папки ..."), "Корневая запись - группа пользователя" (используется для вывода дерева групп пользователей). Описание классов фильтров см. здесь. CSS - набор стилей, применяемый к элементу ввода данных (input, select, textarea). Набор значений - перечень значений выпадающего списка значений (select). Бизнес-объект - php-код с вызовом функции getBObjectValues(), которая формирует список записей бизнес-объекта, например, <?getBObjectValues('sec_user','login','id<>0');?> вернёт список пользователей из таблицы sec_user, причём ИД записей сформируются автоматически, а отображаться будут значения поля login. Можно задать значение фильтра и по умолчанию (при первом открытии справочника) активировать сразу.
SQL - подключаемые строки SQL-запроса (подстановка выполняется в конце базового SQL-запроса, который прописывается во вкладке PHP/SQL-запрос на форме редактирования секции данных).
|
Добавим ещё два фильтра так, что бы получился следующий список фильтров:
Далее настроим формы редактирования.
Внесём следующий HTML-код в форму "Группа":
<div id="frm_elements_group">
<br/>
<br/>
<table width="100%"><tr><td class="td50"></td><td id="lr_group_group">
<table cellspacing="0px">
<tr><td>Номер:</td><td><div id="group_group_number"></div></td></tr>
<tr><td>Название:</td><td><div id="group_group_name"></div></td></tr>
</table>
</td><td class="td50"></td></tr></table>
</div>
Здесь frm_elements_group - главный контейнер формы редактирования "Группа", elements - код формы, group - код секции данных. Все элементы ввода данных должны находиться внутри контейнера lr_group_group. На форме всего два элемента ввода данных: group_group_number и group_group_name. Их id состоят из кода формы group, кода секции данных group и кода поля (number и name).
Далее добавим новую секцию данных в форме "Группа":
Добавим поля так, что бы получился следующий список полей секции данных "Группа":
Внесём следующий HTML-код в форму "Ингредиент":
<div id="frm_elements_element">
<br/>
<br/>
<table width="100%"><tr><td class="td50"></td><td id="lr_element_element">
<table cellspacing="0px" width="260px">
<tr><td>Код:</td><td><div id="element_element_code"></div></td></tr>
<tr><td>Название:</td><td><div id="element_element_name"></div></td></tr>
</table>
</td><td class="td50"></td></tr></table>
</div>
Далее добавим новую секцию данных в форме "Ингредиент":
Добавим поля так, что бы получился следующий список полей секции данных "Ингредиент":
После того как справочник был разработан или были произведены какие-нибудь изменения в его структуре, необходимо выполнить выгрузку html-кода формы, описания логической структуры формы, алгоритмов редактирования и SQL-запросов в папку клиента на сервере-приложений. Для этот выбираем одну или несколько нужных нам форм и в контекстном меню запускаем пользовательское действие "Экспорт формы".
На разработку справочника "Ингредиенты" мы затратили всего пару десятков минут! Разделы в принципе ни чем не отличаются от справочников, но разрабатываются в несколько раз дольше, т.к. количество полей и фильтров в них, как правило, на порядок больше, чем в справочниках, кроме того часто требуется предусмотреть дополнительные функции, реализованные через пользовательские действия.
Updated: 2011-06-17 15:36:09







