Dramatically improved filepicker performance. Data is only ever loaded when the dropdown is on focus, as it was supposed to be. Image preview of a selected item won't be rendered unless the field gains focus to avoid wasting resources. (fixes #788)

This commit is contained in:
Djamil Legato
2016-10-01 00:09:01 -07:00
parent a011368e40
commit 74b756d6a8
4 changed files with 50 additions and 66 deletions

View File

@@ -16,6 +16,7 @@
* Fixed Submit buttons getting disabled in case of form invalidity disallowing to submit again ([#802](https://github.com/getgrav/grav-plugin-admin/issues/802)) * Fixed Submit buttons getting disabled in case of form invalidity disallowing to submit again ([#802](https://github.com/getgrav/grav-plugin-admin/issues/802))
* Fixed issue when reading the file size setting if set to `0` (in Pagemedia and File fields) * Fixed issue when reading the file size setting if set to `0` (in Pagemedia and File fields)
* Fixed issue with `file` field in collections that caused unexpected duplication of items ([#775](https://github.com/getgrav/grav-plugin-admin/issues/775)) * Fixed issue with `file` field in collections that caused unexpected duplication of items ([#775](https://github.com/getgrav/grav-plugin-admin/issues/775))
* Dramatically improved `filepicker` performance. Data is only ever loaded when the dropdown is on focus, as it was supposed to be. Image preview of a selected item won't be rendered unless the field gains focus to avoid wasting resources. ([#788](https://github.com/getgrav/grav-plugin-admin/issues/788))
# v1.2.2 # v1.2.2
## 09/08/2016 ## 09/08/2016

View File

@@ -33,56 +33,50 @@ export default class FilePickerField {
let field = (isInput ? element : element.find('input, select')); let field = (isInput ? element : element.find('input, select'));
var folder = ''; let folder = '';
if (!field.length || field.get(0).selectize) { return; } if (!field.length || field.get(0).selectize) { return; }
var getData = function getData(field, callback) { let getData = function getData(field, callback) {
let url = config.current_url + `.json/task${config.param_sep}getFilesInFolder`; let url = config.current_url + `.json/task${config.param_sep}getFilesInFolder`;
let parent = field.first().parents('[data-grav-filepicker]'); let parent = field.closest('[data-grav-filepicker]');
let name = parent.data('name'); let name = parent.data('name');
let value = parent.data('value'); let value = parent.data('value');
request(url, { request(url, {
method: 'post', method: 'post',
body: { body: { name }
name: name
}
}, (response) => { }, (response) => {
if (typeof response.files === 'undefined') { if (typeof response.files === 'undefined') {
return; return;
} }
var data = [];
for (var i = 0; i < response.files.length; i++) { let data = [];
for (let i = 0; i < response.files.length; i++) {
data.push({'name': response.files[i]}); data.push({'name': response.files[i]});
} }
folder = response.folder; folder = response.folder;
callback(data, value); callback(data, value);
}); });
}; };
var refreshingCurrentValue = false; let imagesPreview = field.closest('[data-preview-images]').length > 0;
var preview_images = false; let selectedIsRendered = false;
if (field.first().parents('[data-preview-images]').length > 0) {
preview_images = true;
}
var renderOption = function renderOption(item, escape) { let renderOption = function renderOption(item, escape) {
let image = ''; let image = '';
if (preview_images) { if (imagesPreview && folder && item.name.match(/\.(jpg|jpeg|png|gif)$/i)) {
if (item.name.match(/\.(jpg|jpeg|png|gif)$/)) { image = `
image = '<img class="filepicker-field-image" src="' + config.base_url_relative + '/../' + folder + '/' + item.name + '"/>'; <img class="filepicker-field-image"
} src="${config.base_url_relative}/../${folder}/${item.name}"/>`;
} }
return '<div>' + return `<div>
'<span class="title">' + <span class="title">
image + ${image} <span class="name filepicker-field-name">${escape(item.name)}</span>
'<span class="name filepicker-field-name">' + escape(item.name) + '</span>' + </span>
'</span>' + </div>`;
'</div>';
}; };
field.selectize({ field.selectize({
@@ -90,43 +84,28 @@ export default class FilePickerField {
labelField: 'name', labelField: 'name',
searchField: 'name', searchField: 'name',
create: false, create: false,
preload: true, preload: false, // 'focus',
render: { render: {
option: function(item, escape) { option: function(item, escape) {
return renderOption(item, escape); return renderOption(item, escape);
}, },
item: function(item, escape) { item: function(item, escape) {
return renderOption(item, escape); return renderOption(item, escape);
} }
}, },
load: function(query, callback) {
var that = this;
getData(field, function(data, value) { onLoad: function(/* data */) {
callback(data); if (!selectedIsRendered) {
that.setValue(value); let name = this.getValue();
}); this.updateOption(name, { name });
},
onFocus: function() { selectedIsRendered = true;
if (refreshingCurrentValue) {
return;
} }
var that = this; },
var currentValue = that.getValue();
this.clearOptions();
getData(field, function(data, value) { onFocus: function() {
data.forEach(function(item) { this.load((callback) => getData(field, (data) => callback(data)));
that.addOption(item);
that.refreshOptions();
});
refreshingCurrentValue = true;
that.setValue(currentValue);
setTimeout(function() {
refreshingCurrentValue = false;
}, 1000);
});
} }
}); });
} }

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,8 @@
{% embed "forms/fields/select/select.html.twig" %} {% embed "forms/fields/select/select.html.twig" %}
{% if not field.options and value %}
{% set field = field|merge({options: {(value): value}}) %}
{% endif %}
{% block global_attributes %} {% block global_attributes %}
data-grav-filepicker data-grav-filepicker
data-name="{{field.name}}" data-name="{{field.name}}"