Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

175 líneas
6.3 KiB

  1. import $ from 'jquery';
  2. import FilesField from './file';
  3. import { config, translations } from 'grav-form';
  4. import Sortable from 'sortablejs';
  5. const template = `
  6. <div class="dz-preview dz-file-preview">
  7. <div class="dz-details">
  8. <div class="dz-filename"><span data-dz-name></span></div>
  9. <div class="dz-size" data-dz-size></div>
  10. <img data-dz-thumbnail />
  11. </div>
  12. <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
  13. <div class="dz-success-mark"><span>✔</span></div>
  14. <div class="dz-error-mark"><span>✘</span></div>
  15. <div class="dz-error-message"><span data-dz-errormessage></span></div>
  16. <a class="dz-remove" title="${translations.PLUGIN_FORM.DELETE}" href="javascript:undefined;" data-dz-remove>${translations.PLUGIN_FORM.DELETE}</a>
  17. </div>`.trim();
  18. export default class PageMedia extends FilesField {
  19. constructor({ container = '#grav-dropzone', options = {} } = {}) {
  20. const previewTemplate = $('#dropzone-media-template').html() || template;
  21. options = Object.assign(options, { previewTemplate });
  22. super({ container, options });
  23. if (!this.container.length) { return; }
  24. this.urls = {
  25. fetch: `${this.container.data('media-url')}/task${config.param_sep}listmedia`,
  26. add: `${this.container.data('media-url')}/task${config.param_sep}addmedia`,
  27. delete: `${this.container.data('media-url')}/task${config.param_sep}delmedia`
  28. };
  29. this.dropzone.options.url = this.urls.add;
  30. if (typeof this.options.fetchMedia === 'undefined' || this.options.fetchMedia) {
  31. this.fetchMedia();
  32. }
  33. const field = $(`[name="${this.container.data('dropzone-field')}"]`);
  34. if (field.length) {
  35. this.sortable = new Sortable(this.container.get(0), {
  36. animation: 150,
  37. // forceFallback: true,
  38. setData: (dataTransfer, target) => {
  39. target = $(target);
  40. this.dropzone.disable();
  41. target.addClass('hide-backface');
  42. dataTransfer.effectAllowed = 'copy';
  43. },
  44. onSort: () => {
  45. let names = [];
  46. this.container.find('[data-dz-name]').each((index, file) => {
  47. file = $(file);
  48. const name = file.text().trim();
  49. names.push(name);
  50. });
  51. field.val(names.join(','));
  52. }
  53. });
  54. }
  55. }
  56. onDropzoneRemovedFile(file, ...extra) {
  57. if (!file.accepted || file.rejected) { return; }
  58. const form = this.container.closest('form');
  59. const unique_id = form.find('[name="__unique_form_id__"]');
  60. let url = file.removeUrl || this.urls.delete || `${location.href}.json`;
  61. let path = (url || '').match(/path:(.*)\//);
  62. let data = new FormData();
  63. data.append('filename', file.name);
  64. data.append('__form-name__', form.find('[name="__form-name__"]').val());
  65. if (unique_id.length) {
  66. data.append('__unique_form_id__', unique_id.val());
  67. }
  68. data.append('name', this.options.dotNotation);
  69. data.append('form-nonce', config.form_nonce);
  70. if (file.sessionParams) {
  71. data.append('__form-file-remover__', '1');
  72. data.append('session', file.sessionParams);
  73. }
  74. $.ajax({
  75. url,
  76. data,
  77. method: 'POST',
  78. contentType: false,
  79. processData: false,
  80. success: () => {
  81. if (!path) { return; }
  82. path = global.atob(path[1]);
  83. let input = this.container.find('[name][type="hidden"]');
  84. let data = JSON.parse(input.val() || '{}');
  85. delete data[path];
  86. input.val(JSON.stringify(data));
  87. }
  88. });
  89. }
  90. fetchMedia() {
  91. const order = this.container.closest('.form-field').find('[name="data[header][media_order]"]').val();
  92. const data = { order };
  93. let url = this.urls.fetch;
  94. $.ajax({
  95. url,
  96. method: 'POST',
  97. data,
  98. success: (response) => {
  99. if (typeof response === 'string' || response instanceof String) {
  100. return false;
  101. }
  102. response = response.results;
  103. Object.keys(response).forEach((name) => {
  104. let data = response[name];
  105. let mock = { name, size: data.size, accepted: true, extras: data };
  106. this.dropzone.files.push(mock);
  107. this.dropzone.options.addedfile.call(this.dropzone, mock);
  108. this.dropzone.options.thumbnail.call(this.dropzone, mock, data.url);
  109. });
  110. this.container.find('.dz-preview').prop('draggable', 'true');
  111. }
  112. });
  113. /*
  114. request(url, { method: 'post', body }, (response) => {
  115. let results = response.results;
  116. Object.keys(results).forEach((name) => {
  117. let data = results[name];
  118. let mock = { name, size: data.size, accepted: true, extras: data };
  119. this.dropzone.files.push(mock);
  120. this.dropzone.options.addedfile.call(this.dropzone, mock);
  121. this.dropzone.options.thumbnail.call(this.dropzone, mock, data.url);
  122. });
  123. this.container.find('.dz-preview').prop('draggable', 'true');
  124. });*/
  125. }
  126. onDropzoneSending(file, xhr, formData) {
  127. /*
  128. // Cannot call super because Safari and IE API don't implement `delete`
  129. super.onDropzoneSending(file, xhr, formData);
  130. formData.delete('task');
  131. */
  132. formData.append('name', this.options.dotNotation);
  133. formData.append('admin-nonce', config.admin_nonce);
  134. }
  135. onDropzoneComplete(file) {
  136. super.onDropzoneComplete(file);
  137. this.sortable.options.onSort();
  138. // accepted
  139. $('.dz-preview').prop('draggable', 'true');
  140. }
  141. // onDropzoneRemovedFile(file, ...extra) {
  142. // super.onDropzoneRemovedFile(file, ...extra);
  143. // this.sortable.options.onSort();
  144. // }
  145. }
  146. export let Instance = new PageMedia();