Show/Hide Toolbars

Руководство администратора

Пример AJAX-запросов, Promise и SweetAlert

Ссылки Назад Вверх Вперед

Старый МТФ

В портальном блоке Smart Html слева выводится список незавершеных задач из категории, а справа — список завершенных. По клику на задачу она переводится в статус "Завершено" и переходит из левого списка в правый. После этого страница перезагружается, чтобы отобразить обновленные данные. Если переход невозможен, выдается окно с предупреждением (swal — SweetAlert — замена стандартного окна предупреждения).

portal-block-1

Полезные ссылки

Работа с блоком Smart Html описана здесь.

Для обращения к данным, отбираемым с помощью смарт-выражений, используется шаблонизатор mustache.

Описание шаблонизатора mustache на английском

Описание шаблонизатора mustache на русском

Решение

Верстка блока

<div class='block-wrapper'>
  <div class='block-wrapper__tasks'>
      <h3>Задачи <i id="addNewTask" class="add-task fa fa-plus-circle"></i></h3>
      <div>

           {{#smart555}}
                 <div>

                         <span data-state-id='{{stateID}}' data-task-id='{{taskID}}' class='task-item'>{{description}}</span>

                         <i data-task-id='{{taskID}}' class="to-complete fa fa-arrow-right"></i>

                 </div>

          {{/smart555}}

   </div>
  </div>
  <div class='block-wrapper__completed-tasks'>
      <h3>Завершенные задачи</h3>
      <div class="block-wrapper__completed-tasks-list"></div>
  </div>
</div>

JS-вставка

warning_icon   В начале JS-вставки подключаются скрипты polyfill и sweetalert. Их можно подключать непосредственно из HTML-верстки, но считается правилом хорошего тона подключать все скрипты из JS.

//polyfill
var promisePolyfill = document.createElement('script');
promisePolyfill.setAttribute('src','https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.js');
document.head.appendChild(promisePolyfill);
 
//sweetalert
var sweetAlertScript = document.createElement('script');
sweetAlertScript.setAttribute('src','https://cdn.jsdelivr.net/npm/sweetalert2@8');
document.head.appendChild(sweetAlertScript);
 
// обновление страницы
function reloadPage() {
 window.location.reload();
}

 

(window.firstForma.portal.block(1234)).onLoaded(function() {

  // назначаем обработчик для события клика по кнопке создания задачи
   document.getElementById('addNewTask').addEventListener('click', function() {
      var openedWindow = radopen('/NewTask.aspx?&SubCatID=123456&returnjs=window.top.reloadPage();');
   });
 

  // для каждой задачи назначаем обработчик для события клика по тексту задачи
  var tasks = document.getElementsByClassName('task-item');
  var completedTasks = [];
  for (var i = 0; i < tasks.length; i++) {
    var stateId = tasks[i].dataset.stateId;
    tasks[i].addEventListener('click', function() {
      var task = event.target;
      var taskId = task.dataset.taskId;
      var url = '/MainTaskForm.aspx?taskId=' + taskId;
      var openedWindow = radopen(url);
     });
    // stateId = 3 соответствует статусу "Завершено", завершенные задачи заносим в отдельный список
    if (+stateId === 3) {
      completedTasks.push({
        taskId: tasks[i].dataset.taskId,
        taskText: tasks[i].innerHTML
       });
     }
   }

  function isTasksArrayIncludedTask(taskArray, taskId) {
    var isTasksArrayIncludedTask = taskArray.find(function (task) {
        return task.taskId === taskId;
     });
    return !!isTasksArrayIncludedTask;
   }

  // готовим Promise, см. здесь
  function httpPostRequest(url, data) {
    var data = data || {};
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.open('POST', url);
      xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
 
      xhr.onload = function() {
        if (this.status == 200) {
          resolve(this.response);
         } else {
          reject(this.response);
         }
       };
 
      xhr.onerror = function() {
        reject(new Error("Network Error"));
       };
 
      xhr.send(data);
     });
   }

  // функция добавляет завершенные задачи в список в правой половине блока
  // tasks: {taskId: number; taskText: string}[]
  function addCompletedTasks(tasks) {
    var completedTaskWrapper = document.getElementsByClassName('block-wrapper__completed-tasks-list')[0];
    for (var i = 0; i < tasks.length; i++) {
        var completedTask = document.createElement('div');
        completedTask.innerHTML = tasks[i].taskText;
        completedTask.dataset.taskId = tasks[i].taskId;
        completedTask.classList.add('completed-task-item');
        completedTaskWrapper.appendChild(completedTask);
     }
   }

  // функция удаляет завершенные задачи из списка в левой половине блока
  // tasks: {taskId: number; taskText: string}[]
  function removeTasks(tasks) {
    var itemsToRemove = [];
    var taskItems = document.getElementsByClassName('task-item');
    for (var i = 0; i < taskItems.length; i++) {
      var currentTask = taskItems[i];
      if (isTasksArrayIncludedTask(tasks, currentTask.dataset.taskId)) {
          itemsToRemove.push(currentTask);
       }
     }
    for (var i = 0; i < itemsToRemove.length; i++) {
        itemsToRemove[i].parentNode.remove();
     }
   }

  // переносим завершенные задачи из левой части в правую
   addCompletedTasks(completedTasks);
   removeTasks(completedTasks);

  // назначаем обработчик для события клика для каждой кнопки завершения задачи
  var completeButtons = document.getElementsByClassName('to-complete');
  for (var i = 0; i < completeButtons.length; i++) {
      completeButtons[i].addEventListener('click', function(event) {
            var plusBtn = event.target;
            var taskId = plusBtn.dataset.taskId;
            var url = '/app/v1.0/api/task/step/' + taskId;
            var data = JSON.stringify({stepId: 99, comment: "Задача завершена"});
            var completedTask = [{
            taskId: taskId,
            taskText: event.target.parentNode.getElementsByClassName('task-item')[0].innerText
            }];
       
            httpPostRequest(url, data).then(
            function(response) {
              addCompletedTasks(completedTask);
              removeTasks(completedTask);
            },
            function(error) {
              Swal.fire({
                  type: 'error',
                  title: 'Ошибка',
                  text: JSON.parse(error).message,
                  footer: '<a href="https://1forma.ru/help.html" target="_blank">Помощь</a>'
               });
            }
         );
      });
   }
});