Отправка 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 совпадали с названиями входных параметров в контроллере.