subjects.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**
  2. * ЭЛЕКТРОННЫЙ ЖУРНАЛ «ШКАЛА»: БЛОК РЕДАКТИРОВАНИЯ СПИСКА ПРЕДМЕТОВ
  3. * Copyright © 2019, А.М.Гольдин. Modified BSD License
  4. */
  5. "use strict";
  6. // Объект названий предметов {"s110": "Русский язык", ...}
  7. // (в ini.js определен еще объект названий предметов по умолчанию subjDef)
  8. let subjList = {};
  9. // Публикация списка предметов на страничке из объекта sbObj
  10. const sbListPubl = sbObj => {
  11. // Сначала сортируем объект по числовым полям ключей (d480 > s110),
  12. // затем публикуем с иконками удаления (только для ключей, начинающихся с d)
  13. let sbObjSort = subjSort(sbObj); // определена в ini.js
  14. let cont = '';
  15. for (let sbKey in sbObjSort) {
  16. let divDel = (sbKey[0] == 'd') ?
  17. `<div onclick="subjDel('${sbKey}')" title="Удалить">&#10060;</div>` :
  18. "<div class='noCur'></div>";
  19. let divEdit = (sbKey[0] == 'd') ?
  20. `<div onclick="subjEdit.getInp('${sbKey}', '${sbObjSort[sbKey]}')" title="Редактировать">&#9874;</div>` :
  21. "<div class='noCur'></div>";
  22. cont += `<span id="sb-${sbKey}">${divDel}${divEdit}`
  23. + `${sbKey.substr(1,3)}&emsp;${sbObjSort[sbKey]}</span>`;
  24. }
  25. dqs("#sbList").innerHTML = cont;
  26. };
  27. // Отправка запроса к API для добавления дополнительного предмета
  28. const subjAdd = async () => {
  29. let newSubjKey = 'd' + dqs("#sbNewKod").value.trim();
  30. let newSubjName = dqs("#sbNewName").value.trim();
  31. dqs("#sbNewKod").value = '';
  32. dqs("#sbNewName").value = '';
  33. let rK = /^d\d{3}$/;
  34. if (!rK.test(newSubjKey)) {
  35. info(1, "Условный номер имеет неверный формат.");
  36. return;
  37. }
  38. if (!newSubjName) {
  39. info(1, "Не указано наименование предмета.");
  40. return;
  41. }
  42. let rN = /^[A-Za-z0-9А-Яа-яЁё(). \-]{2,30}$/;
  43. if (!rN.test(newSubjName)) {
  44. info(1, "Наименование предмета может содержать от 2 до 30 букв русского "
  45. + "и латинского алфавитов, дефисов, цифр, скобок, точек и пробелов.");
  46. return;
  47. }
  48. if (Object.keys(subjList).includes(newSubjKey) ||
  49. Object.keys(subjList).includes(newSubjKey.replace('d', 's'))) {
  50. info(1, "Предмет с таким условным номером уже существует.");
  51. return;
  52. }
  53. let apiResp = await apireq("subjAdd", [newSubjKey, newSubjName]);
  54. if (apiResp == "none") info(1, "Запрашиваемая операция отклонена.");
  55. else {
  56. subjList[newSubjKey] = newSubjName;
  57. sbListPubl(subjList);
  58. }
  59. };
  60. // Удаление дополнительного предмета
  61. const subjDel = async (sbDelKey) => {
  62. if (!confirm("Вы уверены?")) return;
  63. let apiResp = await apireq("subjDel", sbDelKey);
  64. if (apiResp == "none") info(1, "Запрашиваемая операция отклонена.");
  65. else {
  66. delete subjList[sbDelKey];
  67. sbListPubl(subjList);
  68. }
  69. }
  70. // Редактирование названия предмета
  71. const subjEdit = {
  72. getInp: (sbKey, oldName) => {
  73. dqs(`#sb-${sbKey}`).innerHTML =
  74. `<input class="sbEd" type="text" value="${oldName}"
  75. onKeyDown="if (event.keyCode == 13)
  76. subjEdit.subm('${sbKey}', this.value)">`;
  77. },
  78. subm: (sbKey, newName) => {
  79. newName = newName.trim();
  80. let rN = /^[A-Za-z0-9А-Яа-яЁё(). \-]{2,30}$/;
  81. if (!rN.test(newName)) {
  82. info(1, "Наименование предмета может содержать от 2 до 30 букв "
  83. + "русского и латинского алфавитов, дефисов, цифр, скобок, точек "
  84. + "и пробелов.");
  85. return;
  86. }
  87. // Отправляем запрос к API на редактирование,
  88. // в случае успеха публикуем обновленные данные
  89. (async () => {
  90. let apiResp = await apireq("subjEdit", [sbKey, newName]);
  91. if (apiResp == "none") {
  92. info(1, "Запрашиваемая операция отклонена.");
  93. sbListPubl(subjList);
  94. }
  95. else {
  96. subjList[sbKey] = newName;
  97. sbListPubl(subjList);
  98. }
  99. })();
  100. }
  101. }
  102. // Формирование контента странички
  103. createSection("subjects", `
  104. <h3>Список предметов</h3>
  105. <div id="sbList"></div><br>
  106. <input type="text" id="sbNewKod" placeholder="Условный номер"
  107. onKeyDown="if (event.keyCode == 13) subjAdd()">
  108. <input type="text" id="sbNewName" placeholder="Наименование"
  109. onKeyDown="if (event.keyCode == 13) subjAdd()">
  110. <button type="button" onclick="subjAdd()">Добавить</button>
  111. `);
  112. // Динамически подгружаем список предметов в объект subjList (сливаем объект
  113. // названий предметов по умолчанию subjDef и то, что получено с помощью API)
  114. // и публикуем его на страничке (имя метода = имени пункта меню!)
  115. getContent.subjects = async () => {
  116. let apiResp = await apireq("subjList");
  117. let subjListDop = JSON.parse(apiResp);
  118. // Оставляем собственно предметы, убираем межклассные группы
  119. for (let kod of Object.keys(subjListDop))
  120. if (kod[0] != 's' && kod[0] != 'd') delete subjListDop[kod];
  121. subjList = {...subjDef, ...subjListDop};
  122. sbListPubl(subjList);
  123. }