Во многих организациях используются телефонные справочники сотрудников. Сначала у нас был красивый бумажный вариант, разработанный в редакторе векторной графики. Но постепенно мне стало надоедать, что приходится его распечатать, затем вырезать и скрепить, а таких справочников варировалось от 10 до 25 штук. В общем, занимало много времени, и особого желания заниматься этим не было. Далее справочник эволюционировал в электронную версию в Excel. Для меня это был идеальный вариант: работает поиск, простота заполнения. Но акктуализировать информацию приходилось мне, возможно из-за сложности формы, а возможно из-за нежелания сотрудника заниматься изучением справочника. В общем со временем мне надоел и этот вариант. Поспрашивав друзей из других компаний, я выяснил, что online телефонный справочник у них реализован с использованием LDAP или PHP+MySQL. Мне не понравились данные реализации по ряду причин:
- при использовании LDAP пришлось бы забивать в базу контакты людей, которые не пользуются корпоративной сетью вообще;
- при использовании LDAP для поддержания акктуальной информации пришлось кому-то из сотрудников давать доступ к серверу, а точнее к редактированию данных LDAP;
- при использовании PHP+MySQL необходимо было бы писать и серверную, и клиентскую часть с нуля, либо модифицировать наработки товарищей под свои нужды. Поскольку, я не силен в PHP, то рассматривать данный вариант не стал.
В итоге я решил использовать в качестве хранения и обработки данных 1C, а для удобного вывода HTML и JavaScript.
Задача разделилась на 3 этапа:
1. Разработка серверной части, т.е. разработать HTTP-сервис для конфигурации 1С: ЗУП
2. Разработка клиентской части. Вот тут для меня было сложнее всего, поскольку HTML и JavaScript я знал меньше чем на базовом уровне.
3. Публикация на web-сервере. Об этом я в статье писать не буду, поскольку информации в интернете, да и на infostart.ru много по этому вопросу.
В результате получилась система отображающая контактыне данные о сотрудниках и их ближайшие дни рождения. Итак начнем.
Разработка серверной части
Для начала давайте разберемся, как работать с HTTP-сервисами в 1С. HTTP-сервисы представляют обработчики HTTP-запросов по определенному URL. URL HTTP-сервиса используется специальный, например:
http://<адрес сервера>/<имя базы>/hs/<корневой URL>/<относительный URL>
где
- адрес сервера - это адрес серевера публикации базы 1С;
- имя базы - это название базы данных конфигурации 1С;
- hs - указывает на то, что мы обращаемся к HTTP-сервису;
- корневой URL - это группа запросов, объеденных общим смыслом. Указывается в свойствах HTTP-запроса;
- относительный URL - это сам запрос, который может использоваться по шаблону и указывается в объекте Шаблон URL.
Для телефонного справочника используем корневой URL - person, а относительные URL следующие (рисунок 1):
- personList - получение списка сотрудников;
- personInfo - получение контактной информации по сотруднику;
- birthdayList - получение списка дней рождения и дней оставшихся до него.
- Проверяем парметры HTTP-запроса;
- Составляем запрос к базе данных
- Обрабатываем результаты базы данных в объекты массив и структуры
- Формируем из полученных объектов сериализированную строку JSON
- Формируем ответ и отправляем обратно клиенту
Поскольку, алгоритмы схожи, то расмотрим только функцию personList, если вы поймете как работает эта функция, то разобраться с другими не составит труда. При формировании HTTP-ответа мы создаем JSON строку, в которой будут содержаться данные для отображения.
Для начала создадим объект HTTPСервисОтвет с числовым параметром, соответствующий коду HTTP-состояния и укажем тип возвращаемых данных (javascript). Более подробнее про коды HTTP состояния можно почитать тут.
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-type","application/javascript");
Пока работа с объектом HTTPСервисОтвет закончена. Для того, чтобы получить параметры от клиента мы обрабатываем Запрос методом Получить, аргументом которого идет название параметра:
ПараметрСостояния = ?(Запрос.ПараметрыЗапроса.Получить("fired") = "0", Перечисления.СостоянияСотрудника.Увольнение, Неопределено);
В данном случае, параметр состояния указывает на состояние сотрудника: уволен или нет. Поскольку, руководству иногда требуются контактные данные уволенных сотрудников, я решил реализовать данную возможность.
Дальше мы производим запрос к базе данных с параметром:
ЗапросКБазе = Новый Запрос;
ЗапросКБазе.Параметры.Вставить("Состояние",ПараметрСостояния);
ЗапросКБазе.Текст = "ВЫБРАТЬ
| ДанныеДляПодбораСотрудников.Сотрудник.Код КАК КодСотрудника,
| ДанныеДляПодбораСотрудников.Подразделение.Наименование КАК Подразделение,
| ДанныеДляПодбораСотрудников.Подразделение.Код КАК КодПодразделения,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Фамилия КАК Фамилия,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Имя КАК Имя,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Отчество КАК Отчество
|ИЗ
| РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудников
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСотрудников.СрезПоследних КАК СостоянияСотрудниковСрезПоследних
| ПО ДанныеДляПодбораСотрудников.Сотрудник.Ссылка = СостоянияСотрудниковСрезПоследних.Сотрудник.Ссылка
|ГДЕ
| ДанныеДляПодбораСотрудников.Подразделение.Наименование <> """"
| И СостоянияСотрудниковСрезПоследних.Состояние.Ссылка <> &Состояние
|
|СГРУППИРОВАТЬ ПО
| ДанныеДляПодбораСотрудников.Подразделение.Наименование,
| ДанныеДляПодбораСотрудников.Сотрудник.Код,
| ДанныеДляПодбораСотрудников.Подразделение.Код,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Фамилия,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Имя,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Отчество
|
|УПОРЯДОЧИТЬ ПО
| Подразделение,
| Фамилия
|ИТОГИ
| МАКСИМУМ(КодСотрудника),
| МАКСИМУМ(Подразделение)
|ПО
| КодПодразделения";
Результат = ЗапросКБазе.Выполнить();
Заострять внимание на зпросе не будем, поскольку я писать запросы не умею, тема публикации меньше отностися к запросам и поэтому перейду к обработке результатов запроса:
ВыборкаПодразделений = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"КодПодразделения");
СписокПодразделений = Новый Массив;
Пока ВыборкаПодразделений.Следующий() Цикл
Подразделение = Новый Структура;
Подразделение.Вставить("id",Строка(ВыборкаПодразделений.КодПодразделения));
Подразделение.Вставить("open","true");
Подразделение.Вставить("value",Строка(ВыборкаПодразделений.Подразделение));
СписокСотрудников = Новый Массив;
ВыборкаСотрудники = ВыборкаПодразделений.Выбрать();
Пока ВыборкаСотрудники.Следующий() Цикл
Сотрудник = Новый Структура;
ФИО = ВыборкаСотрудники.Фамилия + " " + Лев( ВыборкаСотрудники.Имя, 1) + ". " + Лев( ВыборкаСотрудники.Отчество, 1) + ".";
Сотрудник.Вставить("id",Строка(ВыборкаСотрудники.КодСотрудника));
Сотрудник.Вставить("value",Строка(ФИО));
СписокСотрудников.Добавить(Сотрудник);
КонецЦикла;
Подразделение.Вставить("data",СписокСотрудников);
СписокПодразделений.Добавить(Подразделение);
КонецЦикла;
При обработке результата формируется массив подразделений, состоящий из массива структур Подразделение. Подразделение включает в себя код подразделения, наименование и массив сотрудников. В подразделении также есть поле open, которое в дальнейшем в клиенте будет указывать на раскрытый элемент дерева. Структура Сотрудник состоит из фамилиии и инициалов. Поля в структурах указываются на английском языке, чтобы в дальнейшем не возникло проблем при написании клиента.
Джсон = Новый ЗаписьJSON;
Джсон.УстановитьСтроку();
Настройка = Новый НастройкиСериализацииJSON;
ЗаписатьJSON(Джсон, СписокПодразделений,Настройка);
РезультатСтрока = Джсон.Закрыть();
Ответ.УстановитьТелоИзСтроки(РезультатСтрока,КодировкаТекста.UTF8);
Возврат Ответ;
При формировании JSON использовал пример с its.1c.ru.
Код функции GetPersonsList
Функция GetPersonsList(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-type","application/javascript");
ПараметрСостояния = ?(Запрос.ПараметрыЗапроса.Получить("fired") = "0", Перечисления.СостоянияСотрудника.Увольнение, Неопределено);
ЗапросКБазе = Новый Запрос;
ЗапросКБазе.Параметры.Вставить("Состояние",ПараметрСостояния);
ЗапросКБазе.Текст = "ВЫБРАТЬ
| ДанныеДляПодбораСотрудников.Сотрудник.Код КАК КодСотрудника,
| ДанныеДляПодбораСотрудников.Подразделение.Наименование КАК Подразделение,
| ДанныеДляПодбораСотрудников.Подразделение.Код КАК КодПодразделения,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Фамилия КАК Фамилия,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Имя КАК Имя,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Отчество КАК Отчество
|ИЗ
| РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудников
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСотрудников.СрезПоследних КАК СостоянияСотрудниковСрезПоследних
| ПО ДанныеДляПодбораСотрудников.Сотрудник.Ссылка = СостоянияСотрудниковСрезПоследних.Сотрудник.Ссылка
|ГДЕ
| ДанныеДляПодбораСотрудников.Подразделение.Наименование <> """"
| И СостоянияСотрудниковСрезПоследних.Состояние.Ссылка <> &Состояние
|
|СГРУППИРОВАТЬ ПО
| ДанныеДляПодбораСотрудников.Подразделение.Наименование,
| ДанныеДляПодбораСотрудников.Сотрудник.Код,
| ДанныеДляПодбораСотрудников.Подразделение.Код,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Фамилия,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Имя,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Отчество
|
|УПОРЯДОЧИТЬ ПО
| Подразделение,
| Фамилия
|ИТОГИ
| МАКСИМУМ(КодСотрудника),
| МАКСИМУМ(Подразделение)
|ПО
| КодПодразделения";
Результат = ЗапросКБазе.Выполнить();
ВыборкаПодразделений = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"КодПодразделения");
СписокПодразделений = Новый Массив;
Пока ВыборкаПодразделений.Следующий() Цикл
Подразделение = Новый Структура;
Подразделение.Вставить("id",Строка(ВыборкаПодразделений.КодПодразделения));
Подразделение.Вставить("open","true");
Подразделение.Вставить("value",Строка(ВыборкаПодразделений.Подразделение));
СписокСотрудников = Новый Массив;
ВыборкаСотрудники = ВыборкаПодразделений.Выбрать();
Пока ВыборкаСотрудники.Следующий() Цикл
Сотрудник = Новый Структура;
ФИО = ВыборкаСотрудники.Фамилия + " " + Лев( ВыборкаСотрудники.Имя, 1) + ". " + Лев( ВыборкаСотрудники.Отчество, 1) + ".";
Сотрудник.Вставить("id",Строка(ВыборкаСотрудники.КодСотрудника));
Сотрудник.Вставить("value",Строка(ФИО));
СписокСотрудников.Добавить(Сотрудник);
КонецЦикла;
Подразделение.Вставить("data",СписокСотрудников);
СписокПодразделений.Добавить(Подразделение);
КонецЦикла;
Джсон = Новый ЗаписьJSON;
Джсон.УстановитьСтроку();
Настройка = Новый НастройкиСериализацииJSON;
ЗаписатьJSON(Джсон, СписокПодразделений,Настройка);
РезультатСтрока = Джсон.Закрыть();
Ответ.УстановитьТелоИзСтроки(РезультатСтрока,КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Код функции GetPersonInfo
Функция GetPersonInfo(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-type","application/javascript");
КодФизлица = Запрос.ПараметрыЗапроса.Получить("id");
ЗапросКБазе = Новый Запрос;
ЗапросКБазе.Параметры.Вставить("КодФизлица",КодФизлица);
ВидыКонтактнойИнформации = Новый Массив;
ВидыКонтактнойИнформации.Добавить(Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Мобильный телефон").Ссылка);
ВидыКонтактнойИнформации.Добавить(Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Email").Ссылка);
ВидыКонтактнойИнформации.Добавить(Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Домашний телефон").Ссылка);
ВидыКонтактнойИнформации.Добавить(Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Рабочий телефон").Ссылка);
ВидыКонтактнойИнформации.Добавить(Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Адрес места проживания").Ссылка);
ЗапросКБазе.УстановитьПараметр("ВидыКонтактов",ВидыКонтактнойИнформации);
ЗапросКБазе.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ФизическиеЛицаКонтактнаяИнформация.Вид,
| ФизическиеЛицаКонтактнаяИнформация.Представление,
| ФизическиеЛицаКонтактнаяИнформация.Ссылка.Ссылка КАК СсылкаФизЛицо
|ПОМЕСТИТЬ Контакты
|ИЗ
| Справочник.ФизическиеЛица.КонтактнаяИнформация КАК ФизическиеЛицаКонтактнаяИнформация
|ГДЕ
| ФизическиеЛицаКонтактнаяИнформация.Вид В(&ВидыКонтактов)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ФИО КАК ФИО,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения КАК ДатаРождения,
| ДанныеДляПодбораСотрудников.Должность.Наименование КАК Должность,
| Контакты.Вид КАК ТипКонтакта,
| Контакты.Представление КАК Контакт
|ИЗ
| Контакты КАК Контакты
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудников
| ПО Контакты.СсылкаФизЛицо = ДанныеДляПодбораСотрудников.ФизическоеЛицо.Ссылка
|ГДЕ
| ДанныеДляПодбораСотрудников.Сотрудник.Код = &КодФизлица
| И ДанныеДляПодбораСотрудников.Должность.Наименование <> """"
|
|СГРУППИРОВАТЬ ПО
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ФИО,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения,
| ДанныеДляПодбораСотрудников.Должность.Наименование,
| Контакты.Вид,
| Контакты.Представление
|
|УПОРЯДОЧИТЬ ПО
| ФИО
|ИТОГИ ПО
| ФИО";
Результат = ЗапросКБазе.Выполнить();
ВыборкаСотрудник = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"ФИО");
Пока ВыборкаСотрудник.Следующий() Цикл
Сотрудник = Новый Структура;
Сотрудник.Вставить("fio",Строка(ВыборкаСотрудник.ФИО));
СписокКонтактов = Новый Массив;
ВыборкаКонтактов = ВыборкаСотрудник.Выбрать();
Пока ВыборкаКонтактов.Следующий() Цикл
Контакт = Новый Структура;
Контакт.Вставить("type",Строка(ВыборкаКонтактов.ТипКонтакта));
Контакт.Вставить("value",Строка(ВыборкаКонтактов.Контакт));
Сотрудник.Вставить("birthday",Строка(Лев(ВыборкаКонтактов.ДатаРождения,10)));
Сотрудник.Вставить("who",Строка(ВыборкаКонтактов.Должность));
СписокКонтактов.Добавить(Контакт);
КонецЦикла;
Сотрудник.Вставить("contacts",СписокКонтактов);;
КонецЦикла;
Джсон = Новый ЗаписьJSON;
Джсон.УстановитьСтроку();
Настройка = Новый НастройкиСериализацииJSON;
ЗаписатьJSON(Джсон, Сотрудник, Настройка);
РезультатСтрока = Джсон.Закрыть();
Ответ.УстановитьТелоИзСтроки(РезультатСтрока,КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Код функции GetBirthdayList
Функция GetBirthdayList(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
КоличествоДней = Запрос.ПараметрыЗапроса.Получить("days");
ЗапросКБазе = Новый Запрос();
ЗапросКБазе.Параметры.Вставить("Дней", Число(КоличествоДней));
ЗапросКБазе.Параметры.Вставить("Сегодня", ТекущаяДата());
ЗапросКБазе.Текст = "ВЫБРАТЬ
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Наименование КАК ФИО,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения КАК ДатаРождения,
| ДЕНЬГОДА(ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения) - ДЕНЬГОДА(&Сегодня) КАК ДоДняРождения
|ИЗ
| РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудников
|ГДЕ
| ДЕНЬГОДА(ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения) - ДЕНЬГОДА(&Сегодня) <= &Дней
| И ДЕНЬГОДА(ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения) - ДЕНЬГОДА(&Сегодня) > 0
|
|СГРУППИРОВАТЬ ПО
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.ДатаРождения,
| ДанныеДляПодбораСотрудников.ФизическоеЛицо.Наименование
|
|УПОРЯДОЧИТЬ ПО
| ДоДняРождения";
Результат = ЗапросКБазе.Выполнить();
ВыборкаСотрудник = Результат.Выбрать();
СписокСотрудников = Новый Массив;
Пока ВыборкаСотрудник.Следующий() Цикл
Сотрудник = Новый Структура;
Сотрудник.Вставить("fio",Строка(ВыборкаСотрудник.ФИО));
Сотрудник.Вставить("days",Строка(ВыборкаСотрудник.ДоДняРождения));
Сотрудник.Вставить("birthday",Строка(Лев(ВыборкаСотрудник.ДатаРождения,10)));
СписокСотрудников.Добавить(Сотрудник);
КонецЦикла;
Джсон = Новый ЗаписьJSON;
Джсон.УстановитьСтроку();
Настройка = Новый НастройкиСериализацииJSON;
ЗаписатьJSON(Джсон, СписокСотрудников, Настройка);
РезультатСтрока = Джсон.Закрыть();
Ответ.УстановитьТелоИзСтроки(РезультатСтрока,КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Алгоритм остальных функций аналогичен. Переходим к разработке клиентской части
Разработка клиентской части
При разработке клиентской части я использовал библиотеку Webix. Данная библиотека позволяет ускорить разработку интерфейса и его алгоритма работы, а также уменьшить количество строк для написания кода.
До использования библиотеки Webix я пробовал сам сделать интерфейс, но получилось мягко говоря не очень. Для сравнения покажу старый и новый интерфейс:
Рисунок 2. Интерфейс до использования Webix UI
Рисунок 3. Исопльзование Webix UI
Помимо данной библиотеки клиентская часть, состоит из следующих файлов:
- index.html - точка входа, именно на эту страницу попадает клиент и с нее уже подгружаются logic.js и ui.js
- logic.js - файл описывающий логику интерфейса: действия при нажатии на элементы, запросы к серверу и т. д.
- ui.js - файл описывающий сам интерфейс.
Код ui.js
var ui_scheme = {
id:"phonebook",
rows: [
{view: "toolbar", cols: [
{view: "label", label: "Телефонный справочник", align:"left"},
{},
{view: "label", label: "Отображать уволенных: ", align:"right"},
{view: "toggle", id:"fired", offLabel:"нет", onLabel:"да", width:50},
{view: "icon", id:"birthday", icon:"birthday-cake"}
]},
{cols:[
{
width: 300,
rows:[
{view: "search",id:"search", placeholder:"Поиск..."},
{view: "tree", select:"true", id:"list_person"}
]},
{
id: "info",
hidden:true ,
width: "800",
rows:[
{view:"template", id:"main_info", template:"<h1>#fio#</h1><h3>Должность: #who#</h3><h5>Дата рождения: #birthday#</h5>", autoheight:true},
{
view:"datatable",
id: "contact_info",
header:false,
autowidth:true,
columns:[
{ id:"type", header:"", width:200},
{ id:"value", header:"", width:600}
],
fixedRowHeight:false, rowLineHeight:25, rowHeight:25
}
]
}
]}
]
};
var win_birthday = {
view:"window",
id:"wBirthday",
position: "center",
modal: "true",
resize: "true",
move: "true",
width: 500,
head:{
view: "toolbar", cols: [
{view: "label", label: "Ближайшие дни рождения"},
{view: "icon", icon:"close", id:"win_close", align: "right", click:"$$('wBirthday').hide();"}
]
},
body:{
rows:[
{view:"counter", id:"days", label:"До дня рождения", labelWidth: 150, step:1, value:14, min:4, max:365},
{view:"list", id: "birthday_persons", template:"#fio# - #birthday# (#days#)", hidden:true, width:400}
]
}
};
Интерфейс страницы (ui_scheme) представляет собой рабочую област,ь разделенную на три части:
- панель инструментов в верхней части, на которой отображется заголовок, кнопка отображения уволенных сотрудников и кнопка отображения списка дней рождений;
- дерево подразделений и сотрудников в левой части;
- информация о сотруднике в правой части.
Дерево подразделений и сотрудников - это иерархический список где родителями являются подразделения, а подчиненными являются сотрудники.
Также имеется окно (win_birthday), которое состоит из заголовка окна, кнопки закрыть и списка сотрудников с указанием даты рождения и дней до дня рождения. Размеры и положения окна можно изменять и оно является модальным.
Код logic.js
function update_list()
{
var url = "/../zup3/hs/person/personList?fired="+$$('fired').getValue();
var auth = 'Basic ' + btoa(unescape(encodeURIComponent("web:web")))
var res = null;
webix.attachEvent("onBeforeAjax",
function(mode, url, data, request, headers, files, promise){
headers["Authorization"]= auth;
});
webix.ajax(url,{
error:function(text, data, XmlHttpRequest){
alert("Ошибка работы с сервером");
},
success:function(text, data, XmlHttpRequest){
$$("list_person").clearAll();
$$("phonebook").disable();
$$("phonebook").showProgress({
type:"icon",
delay:100,
hide:true
});
setTimeout(function(){
$$("list_person").parse(data.json());
$$("phonebook").enable();
}, 100);
}
});
}
function update_info(id)
{
var url = "/../zup3/hs/person/personInfo?id="+id;
var auth = 'Basic ' + btoa(unescape(encodeURIComponent("web:web")))
var res = null;
webix.attachEvent("onBeforeAjax",
function(mode, url, data, request, headers, files, promise){
headers["Authorization"]= auth;
});
webix.ajax(url,{
error:function(text, data, XmlHttpRequest){
alert("Ошибка работы с сервером");
},
beforeSend:function(req) {
req.setRequestHeader('Authorization', auth);
},
success:function(text, data, XmlHttpRequest){
$$("phonebook").disable();
$$("phonebook").showProgress({
type:"icon",
delay:100,
hide:true
});
setTimeout(function(){
$$("main_info").parse(data.json());
$$("contact_info").clearAll();
$$("contact_info").parse(data.json().contacts);
$$("contact_info").adjustRowHeight("value", true);
$$("contact_info").render();
$$("phonebook").enable();
$$("info").show();
}, 100);
}
});
}
function update_birthday(days)
{
var url = "/../zup3/hs/person/birthdayList?days="+days;
var auth = 'Basic ' + btoa(unescape(encodeURIComponent("web:web")))
var res = null;
webix.attachEvent("onBeforeAjax",
function(mode, url, data, request, headers, files, promise){
headers["Authorization"]= auth;
});
webix.ajax(url,{
error:function(text, data, XmlHttpRequest){
alert("Ошибка работы с сервером");
},
beforeSend:function(req) {
req.setRequestHeader('Authorization', auth);
},
success:function(text, data, XmlHttpRequest){
$$("birthday_persons").disable();
$$("birthday_persons").showProgress({
type:"icon",
delay:100,
hide:true
});
setTimeout(function(){
$$("birthday_persons").clearAll();
$$("birthday_persons").parse(data.json());
$$("birthday_persons").enable();
$$("birthday_persons").show();
}, 100);
}
});
}
webix.ready(function(){
webix.ui(ui_scheme);
webix.ui(win_birthday);
webix.extend($$("phonebook"), webix.ProgressBar);
webix.extend($$("birthday_persons"), webix.ProgressBar);
update_list();
$$('fired').attachEvent("onItemClick", function(){
update_list();
})
$$('list_person').attachEvent("onItemClick", function(id, e, node){
if ($$('list_person').isBranch(id) == false)
update_info(id);
})
$$('birthday').attachEvent("onItemClick", function(){
$$("wBirthday").show();
update_birthday($$('days').getValue());
})
$$("days").attachEvent("onChange",function(){
update_birthday(this.getValue());
})
$$("search").attachEvent("onTimedKeyPress",function(){
$$("list_person").filter("#value#",this.getValue());
})
})
Когда выполняется файл logic.js, он загружает интерфейс и подключает индикатор загрузки
webix.ui(ui_scheme);
webix.ui(win_birthday);
webix.extend($$("phonebook"), webix.ProgressBar);
webix.extend($$("birthday_persons"), webix.ProgressBar);
Затем вызывается функция update_list(), которая формирует список сотрудников и подразделений, отправляя запрос на сервер. После чего добавляются события к следующим объектам
$$('fired').attachEvent("onItemClick", function(){
update_list();
})
При нажатии на клавишу "Показывать уволенных сотрудников" происходит обновление списка подразделений и сотрудников
$$('list_person').attachEvent("onItemClick", function(id, e, node){
if ($$('list_person').isBranch(id) == false)
update_info(id);
})
При нажатии на элементе дерева подразделений и сотрудников проверяется, является ли этот элемент сотрудником или подразделением (имеет ли дочерние объекты), если сотрудник, то обновляется область информации.
$$('birthday').attachEvent("onItemClick", function(){
$$("wBirthday").show();
update_birthday($$('days').getValue());
})
При нажатии на кнопку "День рождения" отображается окно и обновляется список сотрудников и дат рождений в данном окне.
$$("search").attachEvent("onTimedKeyPress",function(){
$$("list_person").filter("#value#",this.getValue());
})
При изменении значения "До дня рождения" обновляется список сотрудников и дат рождений
$$("search").attachEvent("onTimedKeyPress",function(){
$$("list_person").filter("#value#",this.getValue());
})
Если поле search будет изменено то применяется фильтр к дереву подразделений и сотрудников.
Алгоритмы обновления информации о сотрудниках, подразделениях и дат рождения очень схожи:
- Формируется URL для запроса
- Формируется строка авторизации
- До отправки запроса отправляется запрос авторизации
- Отправляется запрос на сервер
- Обрабатывается результат и парсится в объекты страницы.
Я надеюсь, что данный материал был интересен и полезен для читателя. С радостью отвечу на вопросы в комментариях и выслушаю критику по данному материалу.