diff --git a/src/_h5ai/client/css/inc/ext/filter.less b/src/_h5ai/client/css/inc/ext/filter.less index fb507439..8ebf5c54 100644 --- a/src/_h5ai/client/css/inc/ext/filter.less +++ b/src/_h5ai/client/css/inc/ext/filter.less @@ -20,4 +20,10 @@ display: inline-block; } } + + &.pending { + input { + color: @col-text-disabled-black; + } + } } diff --git a/src/_h5ai/client/css/inc/view/view.less b/src/_h5ai/client/css/inc/view/view.less index add07dee..79479d69 100644 --- a/src/_h5ai/client/css/inc/view/view.less +++ b/src/_h5ai/client/css/inc/view/view.less @@ -73,8 +73,8 @@ width: 80px; } - .empty { - display: none; + #view-hint { + display: block; margin-top: 36px; text-align: center; color: @col-border; diff --git a/src/_h5ai/client/js/inc/ext/filter.js b/src/_h5ai/client/js/inc/ext/filter.js index 94055104..71804755 100644 --- a/src/_h5ai/client/js/inc/ext/filter.js +++ b/src/_h5ai/client/js/inc/ext/filter.js @@ -1,48 +1,48 @@ -modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/resource', 'core/settings'], function (_, $, event, resource, allsettings) { +modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/settings', 'view/view'], function (_, $, event, location, resource, allsettings, view) { var settings = _.extend({ - enabled: false + enabled: false, + debounceTime: 100 }, allsettings.filter); var template = '
' + 'filter' + - '' + + '' + '
'; - var noMatchTemplate = '
'; var inputIsVisible = false; + var prevPattern = ''; var $filter; var $input; - var $noMatch; - function filter(re) { + function filter(pattern) { - var match = []; - var noMatch = []; - var duration = 200; + pattern = pattern || ''; + if (pattern === prevPattern) { + return; + } + prevPattern = pattern; - if (re) { - $('#items .item').not('.folder-parent').each(function () { - - var label = $(this).find('.label').text(); - - if (label.match(re)) { - match.push(this); - } else { - noMatch.push(this); - } - }); - } else { - match = $('#items .item').not('.folder-parent'); + if (!pattern) { + view.setLocation(); + return; } - if (match.length) { - $noMatch.hide(); - } else if (noMatch.length) { - setTimeout(function () { $noMatch.show(); }, duration); - } - $(match).fadeIn(duration); - $(noMatch).fadeOut(duration); + $filter.addClass('pending'); + + var re = new RegExp(pattern); + var matchedItems = []; + + _.each(location.getItem().content, function (item) { + + if (re.test(item.label)) { + matchedItems.push(item); + } + }); + + $filter.removeClass('pending'); + view.setHint('noMatch'); + view.setItems('filter', matchedItems); } function escapeRegExp(sequence) { @@ -50,30 +50,31 @@ modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/resource', 'core/se return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); } - function parseFilterSequence(sequence) { + function parseInput(sequence) { if (sequence.substr(0, 3) === 're:') { - return new RegExp(sequence.substr(3)); + return sequence.substr(3); } - sequence = $.map($.trim(sequence).split(/\s+/), function (part) { + return escapeRegExp(sequence); - return _.map(part.split(''), function (character) { + // sequence = $.map($.trim(sequence).split(/\s+/), function (part) { - return escapeRegExp(character); - }).join('.*?'); - }).join('|'); + // return _.map(part.split(''), function (character) { - return new RegExp(sequence, 'i'); + // return escapeRegExp(character); + // }).join('.*?'); + // }).join('|'); + + // return sequence; } function update() { if (inputIsVisible) { - var val = $input.val(); - filter(parseFilterSequence(val)); $filter.addClass('active'); $input.focus(); + filter(parseInput($input.val())); } else { filter(); $filter.removeClass('active'); @@ -88,6 +89,7 @@ modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/resource', 'core/se function reset() { + inputIsVisible = false; $input.val(''); update(); } @@ -100,10 +102,9 @@ modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/resource', 'core/se $filter = $(template).appendTo('#toolbar'); $input = $filter.find('input'); - $noMatch = $(noMatchTemplate).appendTo('#view'); $filter.on('click', 'img', toggle); - $input.on('keyup', update); + $input.on('keyup', _.debounce(update, settings.debounceTime, {trailing: true})); event.sub('location.changed', reset); } diff --git a/src/_h5ai/client/js/inc/ext/search.js b/src/_h5ai/client/js/inc/ext/search.js index 7f54c1fa..fbc1332d 100644 --- a/src/_h5ai/client/js/inc/ext/search.js +++ b/src/_h5ai/client/js/inc/ext/search.js @@ -7,7 +7,7 @@ modulejs.define('ext/search', ['_', '$', 'core/event', 'core/location', 'core/re var template = ''; var inputIsVisible = false; var prevPattern = ''; @@ -39,6 +39,7 @@ modulejs.define('ext/search', ['_', '$', 'core/event', 'core/location', 'core/re }, function (response) { $search.removeClass('pending'); + view.setHint('noMatch'); view.setItems('search', _.map(response.search, function (item) { return Item.get(item); diff --git a/src/_h5ai/client/js/inc/view/view.js b/src/_h5ai/client/js/inc/view/view.js index 409db2d5..1052c752 100644 --- a/src/_h5ai/client/js/inc/view/view.js +++ b/src/_h5ai/client/js/inc/view/view.js @@ -16,7 +16,7 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat '' + '' + '' + - '
' + + '
' + '
'; var itemTemplate = '
  • ' + @@ -30,7 +30,7 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat '
  • '; var $view = $(template); var $items = $view.find('#items'); - var $empty = $view.find('.empty'); + var $hint = $view.find('#view-hint'); function createHtml(item) { @@ -98,8 +98,8 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat $items.append(createHtml(e)); }); - $empty.hide(); content.$el.scrollLeft(0).scrollTop(0); + checkHint(); event.pub('view.changed', items, removed); } @@ -117,10 +117,27 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat }); }); - $empty.hide(); + checkHint(); event.pub('view.changed', add, remove); } + function checkHint() { + + var hasNoItems = $items.find('.item').not('.folder-parent').length === 0; + + if (hasNoItems) { + $hint.show(); + } else { + $hint.hide(); + } + } + + function setHint(l10nKey) { + + $hint.removeClass().addClass('l10n-' + l10nKey); + checkHint(); + } + function onLocationChanged(item) { if (!item) { @@ -140,6 +157,7 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat } }); + setHint('empty'); setItems('location.changed', items); } @@ -154,13 +172,14 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat } }); + setHint('empty'); changeItems('location.refreshed', add, removed); } function init() { $view.appendTo(content.$el); - $empty.hide(); + $hint.hide(); format.setDefaultMetric(settings.binaryPrefix); @@ -180,6 +199,7 @@ modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/locat $items: $items, setItems: setItems, changeItems: changeItems, - setLocation: onLocationChanged + setLocation: onLocationChanged, + setHint: setHint }; }); diff --git a/src/_h5ai/conf/options.json b/src/_h5ai/conf/options.json index 0fd43631..277c5561 100644 --- a/src/_h5ai/conf/options.json +++ b/src/_h5ai/conf/options.json @@ -109,9 +109,12 @@ Options Filters will be treated as JavaScript regular expressions if you prefix them with "re:". + + - debounceTime: number, debounce wait time in milliseconds */ "filter": { - "enabled": true + "enabled": true, + "debounceTime": 100 }, /*