@@ -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 [ ] ;
@@ -324,12 +398,15 @@ async function main() {
324398 const data = cell . getRow ( ) . getData ( ) ;
325399 e . preventDefault ( ) ;
326400 e . stopPropagation ( ) ;
327- table . alert ( `${ data . name } (U+${ data . code } ) copied to clipboard` ) ;
401+ table . alert (
402+ `${ data . name } (U+${ data . code } ) copied to clipboard`
403+ ) ;
328404 setTimeout ( ( ) => table . clearAlert ( ) , 1000 ) ;
329405 navigator . clipboard . writeText ( data . example ) ;
330406 } ,
331407 field : "" ,
332- formatter : ( ) => `<img src="/images/icons/clipboard.svg" alt="Copy to clipboard" height="16">` ,
408+ formatter : ( ) =>
409+ `<img src="/images/icons/clipboard.svg" alt="Copy to clipboard" height="16">` ,
333410 headerSort : false ,
334411 title : "" ,
335412 } ,
@@ -374,6 +451,7 @@ async function main() {
374451 hozAlign : "center" ,
375452 responsive : 20 ,
376453 title : "Block" ,
454+ visible : false ,
377455 width : 175 ,
378456 } ,
379457 {
@@ -385,6 +463,7 @@ async function main() {
385463 hozAlign : "center" ,
386464 responsive : 40 ,
387465 title : "Category" ,
466+ visible : false ,
388467 width : 200 ,
389468 } ,
390469 {
@@ -395,6 +474,7 @@ async function main() {
395474 hozAlign : "center" ,
396475 responsive : 50 ,
397476 title : "Script" ,
477+ visible : false ,
398478 width : 100 ,
399479 } ,
400480 {
@@ -405,6 +485,7 @@ async function main() {
405485 hozAlign : "center" ,
406486 responsive : 30 ,
407487 title : "Version" ,
488+ visible : false ,
408489 width : 110 ,
409490 } ,
410491 {
@@ -432,6 +513,11 @@ async function main() {
432513 title : "Tags" ,
433514 field : "tags" ,
434515 formatter : fmtTags ,
516+ headerFilter : "input" ,
517+ headerFilterFunc : filterTags ,
518+ headerPopup : `Separate multiple tags with space or comma.<br/>Pr efix a tag with <code>!</code> to exclude it.` ,
519+ headerPopupIcon :
520+ '<span class="badge rounded-pill text-bg-primary">?</span>' ,
435521 headerSort : false ,
436522 responsive : 15 ,
437523 width : 375 ,
@@ -444,10 +530,11 @@ async function main() {
444530 placeholder : "No matches" ,
445531 responsiveLayout : "hide" ,
446532 footerElement : `<span class="w-100 mx-2 my-1">
447- <img src="/favicon.svg" class="pe-2" style="height:1.2em;" alt="UnicodeSearch logo"/>UnicodeSearch
448- <span id="rowcount" class="px-3">Rows: ${ data . length . toLocaleString ( ) } </span>
449- <a class="d-none d-lg-block float-end" href="https://github.com/FileFormatInfo/unicodesearch">Source</a>
450- </span>` ,
533+ <img src="/favicon.svg" class="pe-2" style="height:1.2em;" alt="UnicodeSearch logo"/>UnicodeSearch
534+ <span id="rowcount" class="px-3">Rows: ${ data . length . toLocaleString ( ) } </span>
535+ <input id="showhidecolumns" type="checkbox" class="mx-2" title="Toggle columns: Version, Block, Category, Script"/> Show/Hide Detail Columns
536+ <a class="d-none d-lg-block float-end" href="https://github.com/FileFormatInfo/unicodesearch">Source</a>
537+ </span>` ,
451538 } ) ;
452539
453540 table . on ( "dataFiltered" , function ( filters , rows ) {
@@ -475,6 +562,11 @@ async function main() {
475562 window . history . replaceState ( null , "" , "?" + qs ) ;
476563 } ) ;
477564
565+ table . on ( "tableBuilt" , function ( ) {
566+ document . getElementById ( "showhidecolumns" ) ! . onclick = ( ) =>
567+ toggleColumns ( table , [ "age" , "block" , "category" , "script" ] ) ;
568+ } ) ;
569+
478570 document . getElementById ( "loading" ) ! . style . display = "none" ;
479571 document . getElementById ( "achtable" ) ! . style . display = "block" ;
480572}
0 commit comments