Skip to main content.
Find on this site:

Me as a baby.Mark A. Taff
Location: Home Code Viewer
  1.  /*********************************************************************************
  2.  filter.js
  3.  
  4.   Copyright (c) 2006-2007 Mark A. Taff <marktaff@comcast.net>
  5.  
  6.   Licensed under the GNU GPL, version 2
  7.  
  8.   PURPOSE: Filter my music collection ala Amarok's Google-esque syntax
  9.  **********************************************************************************/
  10.  
  11.  
  12.  // Globals
  13.  var albums; // Holds a collection of albums
  14.  var count = 0; // Holds number of albums
  15.  var visibleCount = 0; // Number of albums visible
  16.  var filterStatus; // "(filtered)" | null
  17.  var keystrokeDelay = 250; // delay between keystoke events in ms
  18.  var previousFilter; // value of previous filter
  19.  
  20.  
  21.  
  22.  function hideBlock(ID)
  23.  {
  24.   //if no block found, it errors
  25.   if (!document.getElementById(ID))
  26.   {
  27.   alert("No element found with an id attribute of: " + ID);
  28.   return;
  29.   }
  30.   // If displayed, hide it
  31.   if ( document.getElementById(ID).style.display = "block" )
  32.   {
  33.   document.getElementById(ID).style.display = "none";
  34.   }
  35.  } // End function hideBlock
  36.  
  37.  
  38.  
  39.  
  40.  function showBlock(ID)
  41.  {
  42.   //if no block found, it errors
  43.   if (!document.getElementById(ID))
  44.   {
  45.   alert("No element found with an id attribute of: " + ID);
  46.   return;
  47.   }
  48.   // If hidden, display it
  49.   if ( document.getElementById(ID).style.display = "none" )
  50.   {
  51.   document.getElementById(ID).style.display = "block";
  52.   }
  53.   visibleCount++;
  54.  
  55.  } // End fucntion showBlock
  56.  
  57.  
  58.  
  59.  
  60.  function getAllElementsByName ( name )
  61.  {
  62.   /* IE (and maybe some others?) ignores div and span tags when looking for elements by name
  63.   * in javascript's getElementsByName(), so we implement our own version here so that it
  64.   * will find all tags, including div and span.
  65.   */
  66.  
  67.   var counter = 0; // counter
  68.   var xhtmlTags; // holds all xhtml tags from the document
  69.  
  70.   /* Either document.all or document.getElementsByTagName() should work for all browsers */
  71.   xhtmlTags = document.all ? document.all : document.getElementsByTagName( "*" );
  72.  
  73.   for ( i = 0; i < xhtmlTags.length; i++ )
  74.   {
  75.   if ( xhtmlTags[i].name == name )
  76.   {
  77.   counter++;
  78.   albums[counter] = xhtmlTags[i]; // store in global albums collection
  79.   }
  80.   }
  81.   count = counter; // global count
  82.  } // End function getAllElementsByName
  83.  
  84.  
  85.  
  86.  
  87.  function init()
  88.  {
  89.   // We need to ensure this script included in xhtml file *after* all albums have been created
  90.   document.onkeyup = keyUp;
  91.  
  92.   albums = document.getElementsByName( "albumData" ); // array of albums
  93.   if ( ! ( albums ) ) { alert ( "No album collection" ); }
  94.   count = albums.length;
  95.  
  96.   visibleCount = count;
  97.   filterStatus = "";
  98.   setFilterMessage();
  99.  
  100.   // FF 2.0 keeps value upon refresh. Don't let it so that behaviour is the same everywhere
  101.   document.getElementById( 'filter' ).value = "";
  102.  } // End function init
  103.  
  104.  
  105.  
  106.  
  107.  function setFilterMessage()
  108.  {
  109.   if ( count != visibleCount )
  110.   {
  111.   filterStatus = " (filtered)";
  112.   }
  113.   else
  114.   {
  115.   filterStatus = "";
  116.   }
  117.   message = "Displaying " + visibleCount + " of " + count + filterStatus;
  118.   document.getElementById("filterStatus").innerHTML = message;
  119.  } // End function setFilterMessage
  120.  
  121.  
  122.  
  123.  
  124.  /*
  125.   * Show/Hide albums as per filter. Filter is case-insensitive, match anywhere in string
  126.   */
  127.  function simpleFilter ( query, searchSpace, blockID )
  128.  {
  129.   regex = new RegExp ( query, "i" );
  130.   matches = regex.exec ( searchSpace );
  131.   if ( regex.exec ( searchSpace ) )
  132.   {
  133.   showBlock( blockID );
  134.   }
  135.   else
  136.   {
  137.   hideBlock( blockID );
  138.   }
  139.  } // End function simpleFilter
  140.  
  141.  
  142.  
  143.  
  144.  /*
  145.   * Inverse of simpleFilter
  146.   */
  147.  function notSimpleFilter ( query, searchSpace, blockID )
  148.  {
  149.   regex = new RegExp ( query, "i" );
  150.   matches = regex.exec ( searchSpace );
  151.   if ( regex.exec ( searchSpace ) )
  152.   {
  153.   hideBlock( blockID );
  154.   }
  155.   else
  156.   {
  157.   showBlock( blockID );
  158.   }
  159.  } // End function notSimpleFilter
  160.  
  161.  
  162.  
  163.  /*
  164.   * Parse album, artist, md5 from name; then filter the albums
  165.   */
  166.  function parseFilter( query )
  167.  {
  168.   var albumIdAttribute; // holds contents of id attribute from div tag where name attribute is "album"
  169.   var albumProperties; // an array album properties
  170.  
  171.   if ( query.charAt(0) == "-" )
  172.   {
  173.   query = query.substr(1);
  174.   filter = "notSimpleFilter";
  175.   if ( ! ( query ) ) { filter = "simpleFilter"; } // An inverse with a null query == an empty regular query
  176.   }
  177.   else
  178.   {
  179.   filter = "simpleFilter";
  180.   }
  181.  
  182.   // Split albumIdAttribute's by "\:" to permit colons in album names or artists
  183.   regExp = /\\:/;
  184.  
  185.   for ( var i = 0; i < albums.length; i++ )
  186.   {
  187.   if ( albums[i].innerHTML )
  188.   {
  189.   albumIdAttribute = albums[i].innerHTML;
  190.  
  191.   albumProperties = albumIdAttribute.split (regExp);
  192.   artist = albumProperties[0];
  193.   artist = artist.replace ( /_/i, " " );
  194.   albumName = albumProperties[1];
  195.   md5 = albumProperties[2];
  196.  
  197.   searchSpace = artist + " " + albumName;
  198.  
  199.   if ( filter == "notSimpleFilter" )
  200.   {
  201.   notSimpleFilter ( query, searchSpace, 'Album' + md5 );
  202.   }
  203.  
  204.   if ( filter == "simpleFilter" )
  205.   {
  206.   simpleFilter ( query, searchSpace, 'Album' + md5 );
  207.   }
  208.   }
  209.   }
  210.  
  211.  } // End fucntion parseFilter
  212.  
  213.  
  214.  
  215.  /*
  216.   * Reset filter, unfiltering the results
  217.   */
  218.  function clearFilter()
  219.  {
  220.   document.getElementById( 'filter' ).value = "";
  221.   applyFilter();
  222.  } // End function clearFilter
  223.  
  224.  
  225.  
  226.  
  227.  /*
  228.   * Apply filter
  229.   */
  230.  function applyFilter()
  231.  {
  232.   var filterInput = document.getElementById( 'filter' );
  233.   var query = filterInput.value;
  234.  
  235.   // Never reapply the same filter
  236.   if ( query == previousFilter ) { return; }
  237.   previousFilter = query;
  238.  
  239.   visibleCount = 0; // Reset visible before applying filter
  240.   parseFilter ( query );
  241.   setFilterMessage();
  242.  } // End function applyFilter
  243.  
  244.  
  245.  
  246.  
  247.  /*
  248.   * Refresh filter on each keyup event
  249.   */
  250.  function keyUp( event )
  251.  {
  252.   setTimeout ( "applyFilter()", keystrokeDelay );
  253.  } // End function keyUp
  254.  
  255.  
  256.  
  257.  /*
  258.   * Implement sleep for wannabe language
  259.   * INPUT: ms - length of delay in milliseconds
  260.   */
  261.  function sleep( ms )
  262.  {
  263.   var then = new Date( new Date().getTime() + ms );
  264.   while ( new Date() < then ) {}
  265.  
  266.  } // End function sleep
  267.  
  268.  
  269.  
  270.  /*
  271.   * Initialize the script
  272.   */
  273.  init();
CC-GNU GPL
Photos & software licensed under the CC-GNU GPL
unless otherwise noted in the JPEG comments field or source code.