Feature - searchPanes: Class names can be defined

pull/355/head
Allan Jardine 7 years ago
parent e221ce9c3d
commit 797c3e6f90

@ -1,4 +1,4 @@
div.dt-searchPane { div.dt-searchPanes {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;
@ -8,18 +8,18 @@ div.dt-searchPane {
height: 100%; height: 100%;
margin: 1em 0; margin: 1em 0;
} }
div.dt-searchPane div.pane { div.dt-searchPanes div.pane {
position: relative; position: relative;
flex: 1; flex: 1;
margin: 0 0.5%; margin: 1em 0.5%;
border: 1px solid #ccc; border: 1px solid #ccc;
/*width: 15.5%; /*width: 15.5%;
margin: 0 0.583333333%;*/ margin: 0 0.583333333%;*/
} }
div.dt-searchPane div.pane button[type=button] { div.dt-searchPanes div.pane button[type=button] {
display: none; display: none;
} }
div.dt-searchPane div.pane.filtering button[type=button] { div.dt-searchPanes div.pane.filtering button[type=button] {
display: block; display: block;
position: absolute; position: absolute;
right: 6px; right: 6px;
@ -29,10 +29,10 @@ div.dt-searchPane div.pane.filtering button[type=button] {
border-radius: 3px; border-radius: 3px;
cursor: pointer; cursor: pointer;
} }
div.dt-searchPane div.pane.filtering button[type=button]:hover { div.dt-searchPanes div.pane.filtering button[type=button]:hover {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
} }
div.dt-searchPane div.pane div.title { div.dt-searchPanes div.pane div.title {
box-sizing: border-box; box-sizing: border-box;
height: 30px; height: 30px;
padding: 0.35em; padding: 0.35em;
@ -40,7 +40,7 @@ div.dt-searchPane div.pane div.title {
background-color: rgba(0, 0, 0, 0.075); background-color: rgba(0, 0, 0, 0.075);
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
} }
div.dt-searchPane div.pane div.scroller { div.dt-searchPanes div.pane div.scroller {
position: absolute; position: absolute;
top: 30px; top: 30px;
bottom: 0; bottom: 0;
@ -48,25 +48,25 @@ div.dt-searchPane div.pane div.scroller {
right: 0; right: 0;
overflow: auto; overflow: auto;
} }
div.dt-searchPane div.pane div.scroller ul { div.dt-searchPanes div.pane div.scroller ul {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
div.dt-searchPane div.pane div.scroller ul li { div.dt-searchPanes div.pane div.scroller ul li {
position: relative; position: relative;
margin: 0; margin: 0;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
} }
div.dt-searchPane div.pane div.scroller ul li:nth-child(odd) { div.dt-searchPanes div.pane div.scroller ul li:nth-child(odd) {
background: rgba(0, 0, 0, 0.03); background: rgba(0, 0, 0, 0.03);
} }
div.dt-searchPane div.pane div.scroller ul li.selected { div.dt-searchPanes div.pane div.scroller ul li.selected {
background: #3276b1; background: #3276b1;
color: white; color: white;
} }
div.dt-searchPane div.pane div.scroller ul li span.label { div.dt-searchPanes div.pane div.scroller ul li span.label {
display: inline-block; display: inline-block;
box-sizing: border-box; box-sizing: border-box;
white-space: nowrap; white-space: nowrap;
@ -76,7 +76,7 @@ div.dt-searchPane div.pane div.scroller ul li span.label {
vertical-align: middle; vertical-align: middle;
padding: 0.2em 0.3em; padding: 0.2em 0.3em;
} }
div.dt-searchPane div.pane div.scroller ul li span.count { div.dt-searchPanes div.pane div.scroller ul li span.count {
display: inline-block; display: inline-block;
width: 14%; width: 14%;
margin-right: 1%; margin-right: 1%;

@ -1,5 +1,4 @@
// TODO // TODO
// - Tidy up class names
// - Option to have vertical layout class // - Option to have vertical layout class
// - Number of horizontal panels class options // - Number of horizontal panels class options
// - Threshold option - require that there is duplicate information in a column before it is used // - Threshold option - require that there is duplicate information in a column before it is used
@ -43,16 +42,19 @@ var DataTable = $.fn.dataTable;
function SearchPanes ( settings, opts ) { function SearchPanes ( settings, opts ) {
var that = this; var that = this;
var table = new DataTable.Api( settings ); var table = new DataTable.Api( settings );
this.classes = $.extend( true, {}, SearchPanes.classes );
this.dom = {
container: $('<div/>')
.addClass( this.classes.container )
.appendTo( opts.container )
};
this.s = { this.s = {
dt: table dt: table
}; };
this.dom = {
container: $('<div class="dt-searchPane"/>')
.appendTo( opts.container )
}
table.columns(opts.columns).eq(0).each( function ( idx ) { table.columns(opts.columns).eq(0).each( function ( idx ) {
that._pane( idx ); that._pane( idx );
} ); } );
@ -61,37 +63,26 @@ function SearchPanes ( settings, opts ) {
.on( 'click', 'li', function () { .on( 'click', 'li', function () {
that._toggle( this ); that._toggle( this );
} ) } )
.on( 'click', 'button.close', function () { .on( 'click', 'button.'+this.classes.clear, function () {
that._clear( $(this).closest('div.pane') ); that._clear( $(this).closest('div.'+that.classes.pane.container) );
} ); } );
} }
$.extend( SearchPanes.prototype, { $.extend( SearchPanes.prototype, {
_binData: function ( data, tags ) { _binData: function ( data ) {
var out = {}; var out = {};
var add = function ( d ) {
if ( ! out[ d ] ) {
out[ d ] = 1;
}
else {
out[ d ]++;
}
};
data.each( function (d) { data.each( function (d) {
if ( ! d ) { if ( ! d ) {
return; return;
} }
if ( tags ) { if ( ! out[ d ] ) {
var a = d.split(','); out[ d ] = 1;
for ( var i=0, ien=a.length ; i<ien ; i++ ) {
add( a[i] );
}
} }
else { else {
add( d ); out[ d ]++;
} }
} ); } );
@ -99,8 +90,11 @@ $.extend( SearchPanes.prototype, {
}, },
_clear: function ( pane ) { _clear: function ( pane ) {
pane.find( 'li.selected' ).removeClass( 'selected' ); var classes = this.classes;
pane.removeClass('filtering'); var itemSelected = classes.item.selected;
pane.find( 'li.'+itemSelected ).removeClass( itemSelected );
pane.removeClass( classes.pane.active );
this.s.dt this.s.dt
.column( pane.data('column') ) .column( pane.data('column') )
@ -109,11 +103,13 @@ $.extend( SearchPanes.prototype, {
}, },
_pane: function ( idx ) { _pane: function ( idx ) {
var classes = this.classes;
var itemClasses = classes.item;
var paneClasses = classes.pane;
var table = this.s.dt; var table = this.s.dt;
var column = table.column( idx ); var column = table.column( idx );
var list = $('<ul/>'); var list = $('<ul/>');
var tags = $( column.header() ).hasClass('tags'); var bins = this._binData( column.data().flatten() );
var bins = this._binData( column.data().flatten(), tags );
// On initialisation, do we need to set a filtering value from a // On initialisation, do we need to set a filtering value from a
// saved state or init option? // saved state or init option?
@ -122,19 +118,17 @@ $.extend( SearchPanes.prototype, {
search[0].substr( 1, search[0].length-2 ).split('|') : search[0].substr( 1, search[0].length-2 ).split('|') :
[]; [];
var data = tags ? var data = column.data().unique().sort().toArray();
table.ajax.json().tags :
column.data().unique().sort().toArray();
for ( var i=0, ien=data.length ; i<ien ; i++ ) { for ( var i=0, ien=data.length ; i<ien ; i++ ) {
if ( data[i] ) { if ( data[i] ) {
var li = $('<li/>') var li = $('<li/>')
.html( '<span class="label">'+data[i]+'</span>' ) .html( '<span class="'+itemClasses.label+'">'+data[i]+'</span>' )
.data( 'filter', data[i] ) .data( 'filter', data[i] )
.append( $('<span class="count" />').html( bins[ data[i] ] ) ); .append( $('<span/>').addClass( itemClasses.count ).html( bins[ data[i] ] ) );
if ( $.inArray( data[i], search ) !== -1 ) { if ( $.inArray( data[i], search ) !== -1 ) {
li.addClass('selected'); li.addClass(itemClasses.selected);
} }
list.append( li ); list.append( li );
@ -142,33 +136,36 @@ $.extend( SearchPanes.prototype, {
} }
$(this.dom.container).append( $(this.dom.container).append(
$('<div class="pane"/>') $('<div/>')
.data( 'column', idx ) .data( 'column', idx )
.addClass( search.length ? 'filtering' : '' ) .addClass( paneClasses.container )
.append( '<button type="button" class="close">&times;</button>' ) .addClass( search.length ? paneClasses.active : '' )
.append( $('<div class="title"/>').html( $(column.header()).text() ) ) .append( $('<button type="button">&times;</button>').addClass(this.classes.clear) )
.append( $('<div class="scroller"/>').append( list ) ) .append( $('<div/>').addClass(paneClasses.title).html( $(column.header()).text() ) )
.append( $('<div/>').addClass(paneClasses.scroller).append( list ) )
); );
}, },
_toggle: function ( li ) { _toggle: function ( li ) {
var classes = this.classes;
var itemSelected = classes.item.selected;
var table = this.s.dt; var table = this.s.dt;
var li = $(li); var li = $(li);
var pane = li.closest('div.pane'); var pane = li.closest('div.'+classes.pane.container);
li.toggleClass( 'selected', ! li.hasClass( 'selected' ) ); li.toggleClass( itemSelected, ! li.hasClass( itemSelected ) );
var filters = pane.find( 'li.selected' ); var filters = pane.find( 'li.'+itemSelected );
if ( filters.length === 0 ) { if ( filters.length === 0 ) {
pane.removeClass('filtering'); pane.removeClass( classes.pane.active );
table table
.column( pane.data('column') ) .column( pane.data('column') )
.search('') .search('')
.draw(); .draw();
} }
else { else {
pane.addClass('filtering'); pane.addClass( classes.pane.active );
table table
.column( pane.data('column') ) .column( pane.data('column') )
.search( $.map( filters, function (filter) { .search( $.map( filters, function (filter) {
@ -179,6 +176,22 @@ $.extend( SearchPanes.prototype, {
} }
} ); } );
SearchPanes.classes = {
container: 'dt-searchPanes',
clear: 'clear',
pane: {
active: 'filtering',
container: 'pane',
title: 'title',
scroller: 'scroller'
},
item: {
selected: 'selected',
label: 'label',
count: 'count'
}
};
$(document).on( 'init.dt', function (e, settings, json) { $(document).on( 'init.dt', function (e, settings, json) {

@ -1,5 +1,5 @@
div.dt-searchPane { div.dt-searchPanes {
display:flex; display:flex;
flex-direction: row; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;

Loading…
Cancel
Save