autogostpreview.js 4.9 KB

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