Версии: 3.x, 2.x.
Данная статья описывает, каким образом можно сделать так, чтобы при создании записи в разделе автоматически генерировалось значение в поле «Номер». То есть, чтобы нумерация производилась автоматически.
Создадим поле «Номер» на карточке раздела «Автомобили», который описан в отдельной статье. Для этого добавим на карточку поле «№» (оно не несет смысловой нагрузки, просто оно нужно нам для примера). Чтобы добавить поле на карточку, выполним два действия.
Добавим данную колонку в таблицу.
ALTER TABLE iris_auto ADD COLUMN num character varying(15);
Изменим structure.xml и на карточку добавим созданное только что поле. Для этого в теге EDITCARD поместим в самое начало тег FIELD, описывающий поле num, а также атрибут layout.
<EDITCARD name="c_Auto" caption="Автомобиль" width="600" height="120" layout="1, 2, 2, 1, 1, 2, 2"> <ELEMENTS row_type="fk_column"> <FIELD elem_type="text" caption="№" db_field="num" mandatory="yes" datatype="string" row_type="common"/> .................... </ELEMENTS> </EDITCARD>
Поле добавлено и теперь карточка выглядит так.
Теперь приступим к созданию автоматической генерации номера в поле «№». Для этого необходимо создать пользовательскую логику для карточки, которая будет выполнять следующие действия.
- При открытии карточки делать поле «№» недоступным для редактирования.
- При открытии карточки считывать текущее значение счетчика и помещать его в поле «№».
-
После сохранения карточки произвести
update
вставленной записи, чтобы вставить правильное значение номера, а также увеличить счетчик, хранящий значение номера на 1.
Текущее значение счетчика нужно где-то хранить. Воспользуемся системной переменной. Для хранения системных переменных используется таблица iris_SystemVariable. При создании записи будем считывать из нее значение нужного параметра, а после сохранения карточки увеличивать его значение на 1. Создадим новый системный параметр «Тестовый номер». Можно добавить значение в справочник «Системные переменные» или выполнить такой скрипт.
INSERT INTO iris_SystemVariable (id, name, code, variabletypeid, intvalue) VALUES ('123d35fb-546b-485f-9596-bdf8e863c5c1', 'Тестовый номер', 'TestNum', '092a35fb-7e6b-482f-9596-3abde863c5c1', 0)
Теперь создадим два скрипта пользовательской логики в папке config/sections/Auto: клиентской — c_auto.js и серверной — c_auto.php.
Скрипт c_auto.js:
/**********************************************************************
Скрипт карточки раздела "Автомобили"
**********************************************************************/
var c_Auto_ScriptFileName = '/config/sections/Auto/c_auto.php';
//Инициализация карточки
function c_auto_init(p_wnd_id) {
// находим форму карточки. p_wnd_id - id на окно карточки. через него ищем само окно, а в нем форму
var l_form = document.getElementById(p_wnd_id).getElementsByTagName("form")[0];
// Делаем поле № неактивным
l_form.num.setAttribute('disabled', 'disabled');
// если открыта новая запись, то вставим значение в поле номер
if (l_form._mode.value == 'insert') {
// формируем ajax запрос к файлу c_auto.php для получения значения поля №
var l_auto_init_req = CreatePOSTReqest(c_Auto_ScriptFileName);
l_auto_init_req.onreadystatechange = function() { c_auto_init_end(l_auto_init_req, l_form); };
l_auto_init_req.send('_func=GetDefaultValues');
}
}
function c_auto_init_end(p_req, p_form) {
if (p_req.readyState == 4) {
// после того, как пришел ответ с сервера присвоим полю полученное значение
l_response = p_req.responseText.evalJSON(); // ответ приходит в JSON формате - преобразуем его в массив
p_form.num.value = l_response.Number;
}
}
// обработчик, вызывающийся после сохранения записи
function c_auto_onAfterSave(p_rec_id, p_mode) {
if (p_mode == 'insert') {
var req_number = CreatePOSTReqest(c_Auto_ScriptFileName);
req_number.send('_func=UpdateNumber&_p_id=' + p_rec_id);
}
}
Скрипт c_auto.php:
<?php
/**********************************************************************
Скрипт карточки раздела "Автомобили"
**********************************************************************/
//Значения по умолчанию
function Auto_GetDefaultValues() {
$con = GetConnection();
// Номер
$result['Number'] = GenerateNewNumber('TestNum', null, $con, 1);
return $result;
}
function UpdateAutoNumber($p_id) {
$con = GetConnection();
$res = Auto_GetDefaultValues();
// обновим значение систмной переменной
SetSystemVariableValue('TestNum', $res['Number'], $con);
//обновим номер
$update_sql = "update iris_Auto set num='".$res['Number']."' where ID=:p_id";
$statement = $con->prepare($update_sql);
$statement->bindParam(':p_id', $p_id);
$statement->execute();
}
///////////////////////////////////////////////////////
if (!session_id()) {
@session_start();
if (!session_id()) {
echo 'Невозможно создать сессию!';
}
}
$path = $_SESSION['INDEX_PATH'];
include $path.'/core/engine/applib.php';
include $path.'/config/common/Lib/lib.php';
SendRequestHeaders();
if (!isAuthorised()) {
echo '<b>Не авторизован</b><br>';
die;
}
if (strlen($_POST['_func']) == 0) {
$response = PrintError('Имя функции не задано');
}
else {
switch ($_POST['_func']) {
case 'GetDefaultValues':
$response = Auto_GetDefaultValues();
break;
case 'UpdateNumber':
UpdateAutoNumber(stripslashes($_POST['_p_id']));
break;
default:
$response = 'Неверное имя функции: '.$_POST['_func'];
}
}
// посылаем ответ в JSON формате
echo json_encode($response);
Теперь необходимо подключить скрипт c_auto.js к карточке. Добавим в тег EDITCARD атрибуты js_source_file (имя скрипта пользовательской логики), js_function (имя функции, которая должна быть вызвана при открытии карточки), on_after_save (имя функции, которая должна быть вызвана после сохранения карточки).
<EDITCARD name="c_Auto" caption="Автомобиль" width="600" height="120" layout="1, 2, 2, 1, 1, 2, 2" js_source_file="c_auto.js" js_function="c_auto_init" on_after_save="c_auto_onAfterSave">
<ELEMENTS>
..........
</ELEMENTS>
</EDITCARD>
После того, как скрипт подключен, поле «№» будет получать значение автоматически. Рассмотрим работу скриптов более подробно.
c_auto.js
Функция c_auto_init()
делает неактивным поле num формы и если это карточка новой записи, то посылает ajax запрос скрипту c_auto.php, который обращается к БД и возвращает текущее значение для поля «№» (п.1).
Функция c_auto_init_end()
вызывается после того, как пришел ответ с сервера (от скрипта c_auto.php). Данная функция просто вставляет значение номера в карточку (п. 2).
Функция c_auto_onAfterSave()
вызывается после того, как запись была сохранена. Если это была новая запись, то пошлем ajax запрос скрипту c_auto.php, чтобы он сделал действия из п.3.
c_auto.php
Этот php-скрипт выполняет действия в зависимости от параметра _func. Если _func = GetDefaultValues, то скрипт вернет текущее значение счетчика TestNum. Если _func = UpdateNumber, то скрипт поведет update
записи, вствит нужное значение счетчика и увеличит значение счетчика на 1. Сам скрипт имеет около 50 строк, но основную роль выполняют 2 функции.
<?php
GenerateNewNumber('TestNum', null, $con, 1);
GenerateNewNumber()
считывает текущее значение счетчика TestNum из таблицы iris_SystemVariable. Можно сделать это вручную, сделав запрос к БД, но эта функция облегчает этот процесс.
<?php
GenerateNewNumber('TestNum', null, $con, 1);
UpdateAutoNumber()
выполняет следующие действия.
- Считывает текущее значение счетчика TestNum.
- Таблице iris_Auto для только что вставленной записи полю num устанавливает текущее значение счетчика (это необходимо, чтобы исключить ситуацию, когда у двух карточек может быть одинаковый номер, если их создали одновременно).
- Увеличивает значение счетчика на единицу.
Теперь, при создании новой записи, в поле «№» будет автоматически генерироваться новое значение. Поле при этом будет не редактируемым.