Автоматическая нумерация в карточке
Версии: 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 функции.
GenerateNewNumber('TestNum', null, $con, 1);
GenerateNewNumber() считывает текущее значение счетчика TestNum из таблицы iris_SystemVariable. Можно сделать это вручную, сделав запрос к БД, но эта функция облегчает этот процесс.
UpdateAutoNumber(stripslashes($_POST['_p_id']));
UpdateAutoNumber() выполняет следующие действия.
- Считывает текущее значение счетчика TestNum.
- Таблице iris_Auto для только что вставленной записи полю num устанавливает текущее значение счетчика (это необходимо, чтобы исключить ситуацию, когда у двух карточек может быть одинаковый номер, если их создали одновременно).
- Увеличивает значение счетчика на единицу.
Теперь, при создании новой записи, в поле «№» будет автоматически генерироваться новое значение. Поле при этом будет не редактируемым.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
-
