autogostpreview.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var markupArea = $('#markuparea');
  2. var previewArea = $('#preview');
  3. var btnPreview = $("#switchPreview");
  4. var btnMarkup = $("#switchMarkup");
  5. var btnPrint = $('#printReport');
  6. var btnSave = $('#saveMarkupButton');
  7. var btnFilename = $('#getFilename');
  8. var reportId = $("#idInput").val();
  9. var filename = $("#filename").val().replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, "");
  10. var isDirty = false;
  11. var state = 0; // 0 - редактирование, 1 - превью
  12. $(document).ready(function() {
  13. textAreaAdjust(document.getElementById("markuparea"));
  14. markupArea.keyup(function() {
  15. isDirty = true;
  16. });
  17. // Сохранение по кнопке
  18. btnSave.click(function(e) {
  19. saveMarkup();
  20. });
  21. // Сохранение на Ctrl+S
  22. document.addEventListener("keydown", function(e) {
  23. if (e.keyCode === 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
  24. e.preventDefault();
  25. saveMarkup();
  26. }
  27. }, false);
  28. // Вставка картинок на Ctrl+V
  29. // https://stackoverflow.com/a/6338207
  30. markupArea.on('paste', function (e) {
  31. let items = (e.clipboardData || e.originalEvent.clipboardData).items;
  32. for (let index in items) {
  33. let item = items[index];
  34. if (item.kind === 'file') {
  35. // Загрузка файла через jQuery AJAX
  36. // https://stackoverflow.com/a/13333478
  37. var fd = new FormData();
  38. fd.append('file', item.getAsFile());
  39. $.ajax({
  40. url: "/autogost/upload-image",
  41. type: "post",
  42. data: fd,
  43. processData: false,
  44. contentType: false,
  45. success: function (response) {
  46. response = JSON.parse(response);
  47. if (response.ok) {
  48. const line = "\n@img:"+response.filename+":Изображение";
  49. insertAtCursor(document.getElementById("markuparea"), line);
  50. }
  51. }
  52. });
  53. }
  54. }
  55. });
  56. btnPreview.click(function() {
  57. state = 1;
  58. $("#switchMarkup").removeClass('selected');
  59. $("#switchPreview").addClass('selected');
  60. previewArea.html('<div class="loader"></div>');
  61. markupArea.hide();
  62. previewArea.show();
  63. saveMarkup();
  64. updatePreview();
  65. });
  66. btnMarkup.click(function() {
  67. state = 0;
  68. $("#switchMarkup").addClass('selected');
  69. $("#switchPreview").removeClass('selected');
  70. textAreaAdjust(markupArea);
  71. markupArea.show();
  72. previewArea.hide();
  73. saveMarkup();
  74. });
  75. // Скопировать текст в буфер обмена
  76. btnFilename.click(async function() {
  77. await navigator.clipboard.writeText(filename);
  78. btnFilename.text("Название скопировано");
  79. btnFilename.blur();
  80. });
  81. btnFilename.mouseleave(function () {
  82. btnFilename.text("Получить название файла");
  83. });
  84. btnPrint.click(function() {
  85. saveMarkup();
  86. updatePreview(true);
  87. });
  88. });
  89. // Заставляет textarea расширяться так, чтобы был текст в ней был полностью
  90. // виден
  91. function textAreaAdjust(element) {
  92. if (element.scrollHeight > element.clientHeight) {
  93. // Содержимое полностью не вмещается
  94. element.style.height = "calc(1lh + " + element.scrollHeight +"px)";
  95. }
  96. }
  97. // Обновляет #preview на странице, отсылая запрос на получение HTML
  98. function updatePreview(thenPrint=false) {
  99. $.ajax({
  100. url: "/autogost/gethtml",
  101. type: "post",
  102. data: {
  103. report_id: reportId
  104. },
  105. success: function (data, textStatus, xhr) {
  106. previewArea.html(data);
  107. if (thenPrint) {
  108. if (state == 0) {
  109. previewArea.show();
  110. }
  111. window.print();
  112. if (state == 0) {
  113. previewArea.hide();
  114. }
  115. }
  116. }
  117. });
  118. }
  119. // Сохраняет разметку для данного отчёта
  120. function saveMarkup() {
  121. $.ajax({
  122. url: "/reports/update",
  123. type: "post",
  124. data: {
  125. id: reportId,
  126. markup: markupArea.val()
  127. },
  128. success: function() {
  129. isDirty = false;
  130. btnSave.blur();
  131. }
  132. });
  133. }
  134. // Вставка текста на текущую позицию курсора
  135. // https://stackoverflow.com/a/11077016
  136. function insertAtCursor(myField, myValue) {
  137. //IE support
  138. if (document.selection) {
  139. myField.focus();
  140. sel = document.selection.createRange();
  141. sel.text = myValue;
  142. }
  143. //MOZILLA and others
  144. else if (myField.selectionStart || myField.selectionStart == '0') {
  145. var startPos = myField.selectionStart;
  146. var endPos = myField.selectionEnd;
  147. myField.value = myField.value.substring(0, startPos)
  148. + myValue
  149. + myField.value.substring(endPos, myField.value.length);
  150. } else {
  151. myField.value += myValue;
  152. }
  153. textAreaAdjust(myField);
  154. isDirty = true;
  155. }
  156. // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
  157. const beforeUnloadHandler = (event) => {
  158. if (isDirty == false) {
  159. return true;
  160. }
  161. // Recommended
  162. event.preventDefault();
  163. // Included for legacy support, e.g. Chrome/Edge < 119
  164. event.returnValue = true;
  165. };
  166. window.addEventListener("beforeunload", beforeUnloadHandler);