filepicker.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import $ from 'jquery';
  2. import { config, uri_params } from 'grav-config';
  3. import request from '../../utils/request';
  4. // const insertTextAt = (string, index, text) => [string.slice(0, index), text, string.slice(index)].join('');
  5. export default class FilePickerField {
  6. constructor(options) {
  7. this.items = $();
  8. this.options = Object.assign({}, this.defaults, options);
  9. $('[data-grav-filepicker]').each((index, element) => this.addItem(element));
  10. $('body').on('mutation._grav', this._onAddedNodes.bind(this));
  11. }
  12. _onAddedNodes(event, target/* , record, instance */) {
  13. let fields = $(target).find('[data-grav-filepicker]');
  14. if (!fields.length) { return; }
  15. fields.each((index, field) => {
  16. field = $(field);
  17. if (!~this.items.index(field)) {
  18. this.addItem(field);
  19. }
  20. });
  21. }
  22. addItem(element) {
  23. element = $(element);
  24. this.items = this.items.add(element);
  25. let tag = element.prop('tagName').toLowerCase();
  26. let isInput = tag === 'input' || tag === 'select';
  27. let field = (isInput ? element : element.find('input, select'));
  28. let folder = '';
  29. let thumbs = {};
  30. if (!field.length || field.get(0).selectize) { return; }
  31. let getData = function getData(field, callback, mode = 'all') {
  32. let url = config.current_url + `.json/task${config.param_sep}getFilesInFolder`;
  33. let parent = field.closest('[data-grav-filepicker]');
  34. let name = parent.data('name');
  35. let value = parent.data('value');
  36. let params = JSON.stringify(uri_params || '{}');
  37. request(url, {
  38. method: 'post',
  39. body: { name, params }
  40. }, (response) => {
  41. if (typeof response.files === 'undefined') {
  42. return;
  43. }
  44. let data = [];
  45. thumbs = response.thumbs || {};
  46. for (let i = 0; i < response.files.length; i++) {
  47. if (mode === 'selected' && response.files[i] !== value) { continue; }
  48. data.push({ 'name': response.files[i], 'status': 'available', thumb: thumbs[response.files[i]] || '' });
  49. }
  50. for (let i = 0; i < response.pending.length; i++) {
  51. if (mode === 'selected' && response.pending[i] !== value) { continue; }
  52. data.push({ 'name': response.pending[i], 'status': 'pending', thumb: thumbs[response.pending[i]] || '' });
  53. }
  54. folder = response.folder;
  55. callback(data, value);
  56. });
  57. };
  58. let imagesPreview = field.closest('[data-preview-images]').length > 0;
  59. let selectedIsRendered = false;
  60. let renderOption = function renderOption(item, escape) {
  61. let image = '';
  62. if (imagesPreview && folder && (!item.status || item.status === 'available') && item.name.match(/\.(jpg|jpeg|png|gif)$/i)) {
  63. // const fallback2x = insertTextAt(`${config.base_url_relative}/../${folder}/${item.name}`, -4, '@2x');
  64. // const fallback3x = insertTextAt(`${config.base_url_relative}/../${folder}/${item.name}`, -4, '@3x');
  65. const source = thumbs[item.name] || `${config.base_url_relative}/../${folder}/${item.name}`;
  66. // onerror="if(this.src==='${fallback2x}'){this.src='${fallback3x}';}else{this.src='${fallback2x}'}"
  67. image = `<img class="filepicker-field-image" src="${source}" />`;
  68. }
  69. return `<div>
  70. <span class="title">
  71. ${image} <span class="name filepicker-field-name">${escape(item.name)}</span>
  72. </span>
  73. </div>`;
  74. };
  75. field.selectize({
  76. plugins: ['required-fix'],
  77. valueField: 'name',
  78. labelField: 'name',
  79. searchField: 'name',
  80. optgroups: [
  81. {$order: 1, value: 'pending', label: 'Pending'},
  82. {$order: 2, value: 'available', label: 'Available'}
  83. ],
  84. optgroupField: 'status',
  85. // lockOptgroupOrder: true,
  86. create: false,
  87. preload: false, // 'focus',
  88. render: {
  89. option: function(item, escape) {
  90. return renderOption(item, escape);
  91. },
  92. item: function(item, escape) {
  93. return renderOption(item, escape);
  94. }
  95. },
  96. onInitialize: function() {
  97. this.load((callback) => getData(field, (data) => callback(data), 'selected'));
  98. },
  99. onLoad: function(/* data */) {
  100. if (!selectedIsRendered) {
  101. let name = this.getValue();
  102. this.updateOption(name, { name });
  103. selectedIsRendered = true;
  104. }
  105. },
  106. onFocus: function() {
  107. this.load((callback) => getData(field, (data) => callback(data)));
  108. }
  109. });
  110. }
  111. }
  112. export let Instance = new FilePickerField();