Replace uitablefilter usage with jQuery

We were using uitablefilter.js to provide live filtering of table rows
based upon a search field value, but it turns out this module really
isn't necessary - we can accomplish the same thing using simple jQuery
code. While we're at it, enable the search field on the layers list page
to work in conjunction with with the drop-down layer type selection, fix
pasting into the search field and refreshing with a search specified.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2018-11-16 12:18:17 +13:00
parent b940e7c431
commit aa10299356
7 changed files with 91 additions and 254 deletions

2
README
View File

@ -359,8 +359,6 @@ the MIT license.
Bundled jQuery is redistributed under the MIT license.
Bundled uitablefilter.js is redistributed under the MIT license.
Bundled Chart.js is redistributed under the MIT license.
All other content is copyright (C) 2013-2018 Intel Corporation and

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2008 Greg Weber greg at gregweber.info
* Dual licensed under the MIT and GPLv2 licenses just as jQuery is:
* http://jquery.org/license
*
* documentation at http://gregweber.info/projects/uitablefilter
*
* allows table rows to be filtered (made invisible)
* <code>
* t = $('table')
* $.uiTableFilter( t, phrase )
* </code>
* arguments:
* jQuery object containing table rows
* phrase to search for
* optional arguments:
* column to limit search too (the column title in the table header)
* ifHidden - callback to execute if one or more elements was hidden
*/
(function($) {
$.uiTableFilter = function(jq, phrase, column, ifHidden){
var new_hidden = false;
if( this.last_phrase === phrase ) return false;
var phrase_length = phrase.length;
var words = phrase.toLowerCase().split(" ");
// these function pointers may change
var matches = function(elem) { elem.show() }
var noMatch = function(elem) { elem.hide(); new_hidden = true }
var getText = function(elem) { return elem.text() }
if( column ) {
var index = null;
jq.find("thead > tr:last > th").each( function(i){
if( $.trim($(this).text()) == column ){
index = i; return false;
}
});
if( index == null ) throw("given column: " + column + " not found")
getText = function(elem){ return $(elem.find(
("td:eq(" + index + ")") )).text()
}
}
// if added one letter to last time,
// just check newest word and only need to hide
if( (words.size > 1) && (phrase.substr(0, phrase_length - 1) ===
this.last_phrase) ) {
if( phrase[-1] === " " )
{ this.last_phrase = phrase; return false; }
var words = words[-1]; // just search for the newest word
// only hide visible rows
matches = function(elem) {;}
var elems = jq.find("tbody:first > tr:visible")
}
else {
new_hidden = true;
var elems = jq.find("tbody:first > tr")
}
elems.each(function(){
var elem = $(this);
$.uiTableFilter.has_words( getText(elem), words, false ) ?
matches(elem) : noMatch(elem);
});
last_phrase = phrase;
if( ifHidden && new_hidden ) ifHidden();
return jq;
};
// caching for speedup
$.uiTableFilter.last_phrase = ""
// not jQuery dependent
// "" [""] -> Boolean
// "" [""] Boolean -> Boolean
$.uiTableFilter.has_words = function( str, words, caseSensitive )
{
var text = caseSensitive ? str : str.toLowerCase();
for (var i=0; i < words.length; i++) {
if (text.indexOf(words[i]) === -1) return false;
}
return true;
}
}) (jQuery);

View File

@ -1,117 +0,0 @@
/*
* Copyright (c) 2008 Greg Weber greg at gregweber.info
* Dual licensed under the MIT and GPLv2 licenses just as jQuery is:
* http://jquery.org/license
*
* Multi-columns fork by natinusala
*
* documentation at http://gregweber.info/projects/uitablefilter
* https://github.com/natinusala/jquery-uitablefilter
*
* allows table rows to be filtered (made invisible)
* <code>
* t = $('table')
* $.uiTableFilter( t, phrase )
* </code>
* arguments:
* jQuery object containing table rows
* phrase to search for
* optional arguments:
* array of columns to limit search too (the column title in the table header)
* ifHidden - callback to execute if one or more elements was hidden
* tdElem - specific element within <td> to be considered for searching or to limit search to,
* default:whole <td>. useful if <td> has more than one elements inside but want to
* limit search within only some of elements or only visible elements. eg tdElem can be "td span"
*/
(function($) {
$.uiTableFilter = function(jq, phrase, column, ifHidden, tdElem){
if(!tdElem) tdElem = "td";
var new_hidden = false;
if( this.last_phrase === phrase ) return false;
var phrase_length = phrase.length;
var words = phrase.toLowerCase().split(" ");
// these function pointers may change
var matches = function(elem) { elem.show() }
var noMatch = function(elem) { elem.hide(); new_hidden = true }
var getText = function(elem) { return elem.text() }
if( column )
{
if (!$.isArray(column))
{
column = new Array(column);
}
var index = new Array();
jq.find("thead > tr:last > th").each(function(i)
{
for (var j = 0; j < column.length; j++)
{
if ($.trim($(this).text()) == column[j])
{
index[j] = i;
break;
}
}
});
getText = function(elem) {
var selector = "";
for (var i = 0; i < index.length; i++)
{
if (i != 0) {selector += ",";}
selector += tdElem + ":eq(" + index[i] + ")";
}
return $(elem.find((selector))).text();
}
}
// if added one letter to last time,
// just check newest word and only need to hide
if( (words.size > 1) && (phrase.substr(0, phrase_length - 1) ===
this.last_phrase) ) {
if( phrase[-1] === " " )
{ this.last_phrase = phrase; return false; }
var words = words[-1]; // just search for the newest word
// only hide visible rows
matches = function(elem) {;}
var elems = jq.find("tbody:first > tr:visible")
}
else {
new_hidden = true;
var elems = jq.find("tbody:first > tr")
}
elems.each(function(){
var elem = $(this);
$.uiTableFilter.has_words( getText(elem), words, false ) ?
matches(elem) : noMatch(elem);
});
last_phrase = phrase;
if( ifHidden && new_hidden ) ifHidden();
return jq;
};
// caching for speedup
$.uiTableFilter.last_phrase = ""
// not jQuery dependent
// "" [""] -> Boolean
// "" [""] Boolean -> Boolean
$.uiTableFilter.has_words = function( str, words, caseSensitive )
{
var text = caseSensitive ? str : str.toLowerCase();
for (var i=0; i < words.length; i++) {
if (text.indexOf(words[i]) === -1) return false;
}
return true;
}
}) (jQuery);

View File

@ -222,7 +222,10 @@
<a href="{% url 'layer_export_recipes_csv' layerbranch.branch.name layerbranch.layer.name %}" class="btn btn-default navbar-btn"><i class="glyphicon glyphicon-file" aria-hidden="true"></i> Export CSV</a>
<form action="" class="navbar-form pull-right" id="filter-form">
<input type="text" placeholder="Search recipes" class="form-control" id="filter">
<div class="form-group has-feedback has-clear">
<input type="text" placeholder="Search recipes" class="form-control" id="recipesearchtext">
<a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" id="recipesearchclear" style="pointer-events: auto; text-decoration: none;cursor: pointer;"></a>
</div>
</form>
</div>
</div>
@ -381,8 +384,6 @@
{% block scripts %}
<script src="{% static "js/uitablefilter.js" %}"></script>
<script>
// selectText plugin Borrowed from http://jsfiddle.net/edelman/KcX6A/1506/
jQuery.fn.selectText = function() {
@ -403,19 +404,25 @@
}
};
function clearRecipeSearch() {
$("#recipesearchtext").val('');
$(".recipestable > tbody > tr").show();
}
$(document).ready(function() {
$(function() {
var theTable = $('table.recipestable');
$("#recipesearchtext").on("input", function() {
var value = $(this).val().toLowerCase();
$(".recipestable > tbody > tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
$("#filter").keyup(function() {
$.uiTableFilter( theTable, this.value );
})
$('#filter-form').submit(function(){
theTable.find("tbody > tr:visible > td:eq(1)").mousedown();
return false;
}).focus(); //Give focus to input field
$("#recipesearchclear").click(function(){
clearRecipeSearch();
$("#recipesearchtext").focus();
});
$('.selectallicon').mouseup(function() {
$('#' + $(this).attr('for')).selectText();
@ -430,6 +437,8 @@
$('.glyphicon-hdd').tooltip({title:"Inherits image"});
$('.label-inverse').tooltip();
});
clearRecipeSearch();
});
</script>
{% endblock %}

View File

@ -33,8 +33,11 @@
{% if layerbranch_list %}
<div class="col-md-6 no-left-pad bottom-margin">
<form id="filter-form">
<input type="text" class="form-control" id="filter" placeholder="Search layers">
<form id="filter-form" action="">
<div class="form-group has-feedback has-clear">
<input type="text" class="form-control" id="layersearchtext" placeholder="Search layers">
<a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" id="layersearchclear" style="pointer-events: auto; text-decoration: none;cursor: pointer;"></a>
</div>
</form>
</div>
@ -48,7 +51,7 @@
{% for choice_id, choice_label in layer_type_choices %}
<li><a tabindex="-1" href="#">
<label class="checkbox">
<input type="checkbox" checked value="{{ choice_id }}">{{ choice_label }}
<input type="checkbox" class="filterlayertypecheckbox" checked value="{{ choice_id }}">{{ choice_label }}
</label>
</a></li>
{% endfor %}
@ -115,40 +118,74 @@
{% block scripts %}
<script src="{% static "js/uitablefilter.js" %}"></script>
<script>
var refreshTimer = 0;
function clearLayerSearch() {
$("#layersearchtext").val('');
$(".layerstable > tbody > tr").show();
}
function refreshLayerSearch() {
var classes = [];
$('.filterlayertypecheckbox:not(":checked")').each(function() {
classes.push('layertype_' + $(this).val());
});
var value = $("#layersearchtext").val().toLowerCase();
$(".layerstable > tbody > tr").each(function() {
var visible = true;
if($(this).text().toLowerCase().indexOf(value) == -1) {
visible = false;
}
else {
var row = $(this)
classes.forEach(function (className) {
if( row.hasClass(className) ) {
visible = false;
return false;
}
});
}
$(this).toggle(visible)
});
}
function refreshTimeout() {
// Search text: $("#layersearchtext").val()
// Number of matches: $(".layerstable > tbody > tr:visible").length
}
$(document).ready(function() {
$("input:checkbox").change();
$("input:checkbox").change()
$("input:checkbox").change(function(){
var selectedType = $(this).val();
if($(this).is(":checked")){
$(".layertype_"+selectedType).show();
}
else{
$(".layertype_"+selectedType).hide();
}
refreshLayerSearch();
});
$(function() {
var theTable = $('table.layerstable');
$("#filter").keyup(function() {
$.uiTableFilter( theTable, this.value );
})
$("#layersearchtext").on("input", function() {
refreshLayerSearch();
if(refreshTimer) {
window.clearTimeout(refreshTimer);
}
refreshTimer = window.setTimeout(refreshTimeout, 1000);
});
$("#layersearchclear").click(function(){
$("#layersearchtext").val('');
refreshLayerSearch();
$("#layersearchtext").focus();
});
$('.dropdown-menu input, .dropdown-menu label').click(function(e) {
e.stopPropagation();
})
$('#filter-form').submit(function(){
theTable.find("tbody > tr:visible > td:eq(1)").mousedown();
return false;
}).focus(); //Give focus to input field
});
refreshLayerSearch();
});
</script>
{% endblock %}

View File

@ -166,16 +166,13 @@ th.headerSortDown {
{% endblock %}
{% block scripts %}
<script src="{% static "js/uitablefilter.js" %}"></script>
<script src="{% static "js/jquery.tablesorter.js" %}"></script>
<script>
$(document).ready(function() {
statisticsTable = $('#statistics-table');
var totals = []
$("#statistics-table th").each(function(i){
totals.push(0);
});
function updateMaintainerCount() {
$('#statistics-table').show()
@ -200,17 +197,19 @@ $(document).ready(function() {
}
$("#form-search").submit(function( event ) {
search_text = $("#filter").val()
$.uiTableFilter(statisticsTable, search_text);
search_text = $("#filter").val().toLowerCase();
$("#statistics-table > tbody > tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(search_text) > -1)
});
updateMaintainerCount()
$("#clear-search-btn").show()
event.preventDefault();
});
function clearSearch() {
$.uiTableFilter(statisticsTable, '');
$("#filter").val('');
$("#statistics-table > tbody > tr").show();
$("#clear-search-btn").hide()
$("#filter").val('')
updateMaintainerCount()
}

View File

@ -142,7 +142,6 @@ th.headerSortDown {
{% endblock %}
{% block scripts %}
<script src="{% static "js/uitablefilter.js" %}"></script>
<script src="{% static "js/jquery.tablesorter.js" %}"></script>
<script>
(function($) {
@ -278,7 +277,10 @@ $(document).ready(function() {
queryString = ''
if (search != '') {
$.uiTableFilter(recipesTable, search);
var value = search.toLowerCase();
$("#recipestable > tbody > tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
queryString = '?search=' + search
} else {
if (upstreamStatus != 'All' && maintainer != 'All') {