@@ -134,6 +134,31 @@ function filterName(
134134 return rowValue . toLowerCase ( ) . includes ( search ) ;
135135}
136136
137+ function filterTags (
138+ headerValue : string ,
139+ rowValue : string [ ] ,
140+ rowData : any ,
141+ filterParams : any
142+ ) {
143+ if ( ! headerValue || headerValue . length == 0 ) return true ;
144+
145+ const headerVals = headerValue . split ( / [ , ] + / ) ;
146+ const rowVals :string [ ] = rowValue || [ ] ;
147+
148+ for ( const filterVal of headerVals ) {
149+ if ( filterVal . startsWith ( "!" ) ) {
150+ if ( rowVals . indexOf ( filterVal . slice ( 1 ) ) != - 1 ) {
151+ return false ;
152+ }
153+ } else {
154+ if ( rowVals . indexOf ( filterVal ) == - 1 ) {
155+ return false ;
156+ }
157+ }
158+ }
159+ return true ;
160+ }
161+
137162function fmtCategory ( cell : CellComponent ) {
138163 const val = cell . getValue ( ) as string ;
139164 if ( ! val ) {
@@ -165,6 +190,12 @@ function fmtTags(cell: CellComponent) {
165190 el . className =
166191 "badge border border-primary text-primary me-1 mb-1 text-decoration-none" ;
167192 el . textContent = key ;
193+ el . style . cursor = "pointer" ;
194+ el . onclick = ( e ) => {
195+ e . preventDefault ( ) ;
196+ e . stopPropagation ( ) ;
197+ toggleTagFilter ( cell , key ) ;
198+ }
168199 container . appendChild ( el ) ;
169200 }
170201
@@ -238,21 +269,64 @@ function tickLinkFilter(
238269 return true ; // null case
239270}
240271
241- function makeTagMap ( row : any , socialmedia : SocialMedia [ ] ) : Map < string , string > {
242- const tagMap = new Map < string , string > ( ) ;
243-
244- tagMap . set ( "website" , row . website ) ;
272+ function toggleColumns ( tbl : Tabulator , columns : string [ ] ) : void {
273+ for ( const col of columns ) {
274+ const column = tbl . getColumn ( col ) ;
275+ if ( column ) {
276+ if ( column . isVisible ( ) ) {
277+ column . hide ( ) ;
278+ } else {
279+ column . show ( ) ;
280+ }
281+ }
282+ }
283+ }
245284
246- for ( const sm of socialmedia ) {
247- if ( row [ sm . id ] ) {
248- tagMap . set ( sm . id , row [ sm . id ] ) ;
285+ function toggleTagFilter ( cell : CellComponent , tag : string ) : void {
286+ const tbl = cell . getTable ( ) ;
287+ var headerFilter = "" ;
288+ const headerFilters = tbl . getHeaderFilters ( ) ;
289+ var existingFilter : Filter | null = null ;
290+ for ( const hf of headerFilters ) {
291+ if ( hf . field == "tags" ) {
292+ headerFilter = hf . value ;
293+ existingFilter = hf ;
294+ break ;
249295 }
250296 }
251297
252- return tagMap ;
298+ if ( existingFilter == null ) {
299+ console . log ( `adding to blank` ) ;
300+ tbl . setHeaderFilterValue ( cell . getColumn ( ) , tag ) ;
301+ } else {
302+ tbl . setHeaderFilterValue (
303+ cell . getColumn ( ) ,
304+ ( existingFilter . value = toggleTagArray (
305+ headerFilter . split ( / [ , ] + / ) ,
306+ tag
307+ ) . join ( " " ) )
308+ ) ;
309+ }
310+ tbl . refreshFilter ( ) ;
253311}
254312
313+ function toggleTagArray ( tags : string [ ] , tag : string ) : string [ ] {
314+ var idx = tags . indexOf ( tag ) ;
315+ if ( idx != - 1 ) {
316+ tags . splice ( idx ) ;
317+ tags . push ( `!${ tag } ` ) ;
318+ return tags ;
319+ }
320+
321+ idx = tags . indexOf ( `!${ tag } ` ) ;
322+ if ( idx != - 1 ) {
323+ tags . splice ( idx ) ;
324+ return tags ;
325+ }
255326
327+ tags . push ( tag ) ;
328+ return tags ;
329+ }
256330
257331async function main ( ) {
258332 let data : SearchEntry [ ] ;
@@ -432,6 +506,11 @@ async function main() {
432506 title : "Tags" ,
433507 field : "tags" ,
434508 formatter : fmtTags ,
509+ headerFilter : "input" ,
510+ headerFilterFunc : filterTags ,
511+ headerPopup : `Separate multiple tags with space or comma.<br/>Pr efix a tag with <code>!</code> to exclude it.` ,
512+ headerPopupIcon :
513+ '<span class="badge rounded-pill text-bg-primary">?</span>' ,
435514 headerSort : false ,
436515 responsive : 15 ,
437516 width : 375 ,
@@ -446,6 +525,7 @@ async function main() {
446525 footerElement : `<span class="w-100 mx-2 my-1">
447526 <img src="/favicon.svg" class="pe-2" style="height:1.2em;" alt="UnicodeSearch logo"/>UnicodeSearch
448527 <span id="rowcount" class="px-3">Rows: ${ data . length . toLocaleString ( ) } </span>
528+ <input id="showhidecolumns" type="checkbox" class="mx-2" title="Toggle columns: Version, Block, Category, Script"/> Show/Hide Detail Columns
449529 <a class="d-none d-lg-block float-end" href="https://github.com/FileFormatInfo/unicodesearch">Source</a>
450530 </span>` ,
451531 } ) ;
@@ -475,6 +555,11 @@ async function main() {
475555 window . history . replaceState ( null , "" , "?" + qs ) ;
476556 } ) ;
477557
558+ table . on ( "tableBuilt" , function ( ) {
559+ document . getElementById ( "showhidecolumns" ) ! . onclick = ( ) =>
560+ toggleColumns ( table , [ "age" , "block" , "category" , "script" ] ) ;
561+ } ) ;
562+
478563 document . getElementById ( "loading" ) ! . style . display = "none" ;
479564 document . getElementById ( "achtable" ) ! . style . display = "block" ;
480565}
0 commit comments