[ELMA3] Отправка Ajax-запросов на сервер ELMA
Достаточно часто возникает необходимость работы с данными, которые пользователи вводят при заполнении форм, на лету. Сценарии при загрузке/при изменении значения полей формы частично позволяют решить эту проблему, однако и их функционал ограничен – например, если необходимо работать с системными свойствами объектов или выполнять достаточно сложные действия, такие как запуск процессов и т.п..
Ajax-запросы являются мощным инструментом, позволяющим решать подобные задачи – собирать нужные данные с формы, отправлять их на сервер ELMA, обрабатывать их необходимым нам образом, после чего возвращать результирующие данные обратно на форму.
В этой статье мы рассмотрим несколько примеров использования Ajax-запросов.
Пример 1. Необходимо на форме создания поручения указывать срок выполнения +2 дня по рабочему календарю от даты начала.
Для этого необходимо в файл разметки TaskEditor.cshtml, расположенный в папке ELMA3-Standart(Express)\Web\Modules\EleWise.ELMA.BPM.Web.Tasks\Views\Task, внести изменения, описанные ниже.
В первую очередь необходимо отключить выполнение стандартных Javascript–функций, срабатывающих при изменении даты начала. Для этого необходимо закомментировать строку
elma.SetDateTimeDependenceInputs(’@(Html.IDFor(m => m.StartDate))’, ’@(Html.IDFor(m => m.EndDate))’);
После этого нужно добавить следующий Javascript–сценарий, который будет срабатывать при изменении даты начала:
<script type="text/javascript"> $(document).ready(function () { //указание серверу, что необходимо выполнять сценарий после завершения загрузки формы $(’#StartDate’).bind(’change’, function () { // устанавливаем в качестве обработчика события при изменении значения даты начала нашу функцию var dat = $(’#StartDate’).val().toString(); // получаем текущее установленное значение даты начала $.ajax( { // создаем новый Аякс-запрос traditional: true, // поскольку передаем простые данные (в данном случае строку) - отключаем "глубокое" преобразование. Подробнее о преобразованиях данных можно узнать здесь (http://jquery.page2page.ru/index.php5/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BE%D0%B2_%D0%B4%D0%BB%D1%8F_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_url) url: "@(Url.Action("GetEndDate", "TaskExt", new { area = "EleWise.ELMA.TasksExtension.Web" }))", // указываем адрес, на который будет отправлен запрос - в нашем случае будет вызван метод GetEndDate() контроллера TaskExtController, находящийся в нашем веб-модуле EleWise.ELMA.TasksExtension.Web data: "StartDate=" + dat, // определяем данные для передачи в теле запроса dataType: "json", // указываем тип передаваемых данных type: "POST", // указываем тип запроса success: function(data) // определяем функцию - обработчик данных, который вернет метод контроллера в случае успешного выполнения { $(’#EndDate_date’).attr("value", data); // метод GetEndDate возвращает строку, содержащую дату в формате дд.мм.гг, записываем ее в дату окончания } }); }); }); </script>
Метод GetEndDate() определен в нашем веб-модуле EleWise.ELMA.TasksExtension.Web. Подробнее о создании веб-модуля написано здесь (https://www.elma-bpm.ru/kb/article-97.html) и здесь (https://www.elma-bpm.ru/kb/article-107.html).
Код метода представлен ниже:
public ActionResult GetEndDate(string StartDate) // объявление метода и передаваемых параметров { var date = DateTime.Parse(StartDate); // преобразовываем дату из строки в тип DateTime if (date != null) // если преобразование прошло успешно { var calendar = Locator.GetServiceNotNull<EleWise.ELMA.Scheduling.IProductionCalendarService>(); // загружаем рабочий календарь DateTime endDate = calendar.EvalTargetTime(date, new TimeSpan(2, 0, 0, 0)); // вычисляем +2 дня к дате начала return Json(endDate.ToShortDateString()); // приводим дату к нужному нам формату (дд.мм.гг), сериализуем (пробразовываем в json) и возвращаем обратно в представление } else // если при преобразовании произошла ошибка return Json(DateTime.Now.ToShortDateString()); // возвращаем в представление текущую дату }
Пример 2. Передать в Аякс-запрос более сложные данные можно, например, следующим образом:
<script type="text/javascript"> $(document).ready(function () { //указание серверу, что необходимо выполнять сценарий после завершения загрузки формы $(’#CommentActionModel_DocumentAttachments_Document_Id’).bind(’valueChange’, function () { // устанавливаем нашу функцию в качестве обработчика события при добавлении в список вложений нового документа var dat = $(’#StartDate’).val(); // получаем текущее установленное значение даты начала var arr = []; // инициализируем массив arr[’date’] = dat; // записываем в массив полученное значение даты начала var docIds = $(’#div-CommentActionModel_DocumentAttachments_Document_Id’).find(’input’); // получаем Id документов, прикрепленных пользователем к задаче и записываем их в массив docIds var i = 0; if (docIds.length) { // если в массиве содержатся элементы for (i = 0; i < docIds.length; i++) { arr[’docIds[’ + i.toString() + ’]’] = docIds[i].value; // последовательно записываем их в массив в формате arr[’docIds[i]’] = значение } arr[’docIds[’ + (i+1).toString() + ’]’] = this.value; // записываем последний добавленный нами в список элемент в конец массива } else { // если других документов добавлено не было arr[’docIds[0]’] = this.value; // записываем в массив Id добавленного нами документа } $.ajax( { // создаем новый Аякс-запрос url: "@(Url.Action("GetEndDate", "TaskExt", new { area = "EleWise.ELMA.TasksExtension.Web" }))", // указываем адрес, на который будет отправлен запрос - в нашем случае будет вызван метод GetEndDate() контроллера TaskExtController, находящийся в нашем веб - модуле EleWise.ELMA.TasksExtension.Web data: $.extend({ }, arr), // определяем данные для передачи в теле запроса dataType: "json", // указываем тип передаваемых данных type: "POST", // указываем тип запроса success: function(data) // определяем функцию - обработчик данных, которые вернет метод контроллера в случае успешного выполнения { var jsonData = JSON.stringify(data); // преобразуем возвращенные контроллером данные в строку json var newArr = JSON.parse(jsonData); // парсим строку - преобразуем в обычный массив if (newArr.length) { // если массив не пуст, обрабатываем элементы for (i = 0; i < newArr.length; i++) { // обработка элемента массива } } } }); }); }); </script>
Код метода контроллера в этом случае выглядит следующим образом:
public ActionResult GetEndDate(Nullable<DateTime> date, long[] docIds) // объявление метода и передаваемых параметров, дата в этом случае преобразуется в нужный тип контроллером, а массив с Id документов - в перечисление типа long { // здесь можно обрабатывать данные нужным способом, для теста поместим часть полученных данных в список и вернем его обратно на форму List<string> output = new List<string>(); // инициализируем список output.Add(date.Value.ToString()); // записываем элементы output.Add(docIds.ElementAt(0).ToString()); return Json(output); // преобразуем список в json и возвращаем на форму }
Для того, чтобы данные были правильно приняты контроллером, необходимо, чтобы названия элементов в парах json совпадали с названиями входных параметров в контроллере.