$( function() { const CL_ALL = 'all', CL_UPCOMING = 'current', CL_PAST = 'past'; // classes matching the date values var $allRows = $(".filter-table tbody tr"); var $allDateHeaderRows = $allRows.filter( function() { return $( this ).find( 'td[colspan]' ).length; }); var $dateSelect = $( '#choice' ); var $stateSelect = $( '#choice2' ); var $errorRow = $allRows.filter( '.no-events' ); $allRows.not( $errorRow ).addClass( CL_ALL ); assignDateClasses(); assignStateClasses(); applyBothFilters(); // on init $dateSelect.add( $stateSelect ).on( 'change', applyBothFilters ); function assignDateClasses() { var now = new Date(); now.setHours(0, 0, 0, 0); // Add classes to the individual event rows based on today's date $allRows.not( $allDateHeaderRows ).each( function() { var date = getRowDate( $( this ) ); if( date ) { if( date[1] > now ) { $( this ).addClass( CL_UPCOMING ).removeClass( CL_PAST ); } else { $( this ).addClass( CL_PAST ).removeClass( CL_UPCOMING ); } } var state = getRowState( $( this ) ); } ); // Add classes to the "header" rows based on the "child" rows' classes $allDateHeaderRows.each( function ( i ) { var $nextDateHeaderRow = $allDateHeaderRows.eq( i + 1 ); var $childRows; if( $nextDateHeaderRow.length ) { $childRows = $( this ).nextUntil( $nextDateHeaderRow ).not( $errorRow ); } else { $childRows = $( this ).nextAll().not( $errorRow ); } if( $childRows.filter( '.' + CL_UPCOMING ).length ) { $( this ).addClass( CL_UPCOMING ); } if( $childRows.filter( '.' + CL_PAST ).length ) { $( this ).addClass( CL_PAST ); } } ); } function getRowDate( $row ) { // Pulls the first text node out of the first td (without a colspan) var dateText = $row.find( 'td:not([colspan]):first' ).contents().filter( function() { return this.nodeType == Node.TEXT_NODE; } ).text(); dateText = $.trim( dateText ); if( !dateText.length ) { return; } // no date here var isRange = ( dateText.indexOf( '-' ) > 0 ); var startDate, endDate; if( isRange ) { var splitDates = dateText.split( '-' ); // Pull out years var y1 = extractYear( splitDates[0] ); var startYear = y1[0]; splitDates[0] = y1[1]; var y2 = extractYear( splitDates[1] ); var endYear = y2[0]; splitDates[1] = y2[1]; // Pull out days var d1 = extractDay( splitDates[0] ); var startDay = d1[0]; splitDates[0] = d1[1]; var d2 = extractDay( splitDates[1] ); var endDay = d2[0]; splitDates[1] = d2[1]; // Pull out months var startMonth = $.trim( splitDates[0] ); var endMonth = $.trim( splitDates[1] ); startDate = new Date( startMonth + ' ' + startDay + ', ' + ( startYear ? startYear : endYear ) ); endDate = new Date( (endMonth ? endMonth : startMonth ) + ' ' + endDay + ', ' + endYear ); } else { startDate = new Date( dateText ); endDate = startDate; } var valid = true; if( !( startDate instanceof Date ) ) { console.error( 'Unable to parse start date from string', dateText, startDate ); valid = false; } if( !( endDate instanceof Date ) ) { console.error( 'Unable to parse end date from string', dateText, endDate ); valid = false; } if( !valid ) { return; } else { return [startDate, endDate]; } } function extractYear( str ) { const YEAR_REGEX = /\, \d\d\d\d/gi; var year = str.match( YEAR_REGEX ); if( year && year.length ) { year = str.replace( /.*\,\s/gi, '' ); } else { year = ''; } str = str.replace( YEAR_REGEX, '' ); return [year, str]; } function extractDay( str ) { const DAY_REGEX = /\d\d?/gi; var day = str.match( DAY_REGEX ); if( day && day.length ) { day = parseInt( day[0] ); } else { day = ''; } str = str.replace( DAY_REGEX, '' ); return [day, str]; } function assignStateClasses() { $allRows.not( $allDateHeaderRows ).each( function() { var state = getRowState( $( this ) ); $( this ).addClass( state ); getRowHeader( $( this ) ).addClass( state ); } ); } function getRowHeader( $row ) { var $header = $(); $row.prevAll().each( function () { if ( $( this ).is( $allDateHeaderRows ) ) { $header = $( this ); return false; } } ); return $header; } function getRowState( $row ) { var stateText = $.trim( $row.find( 'td:not([colspan]):first strong' ).text() ); if( !stateText.length || !stateText.indexOf( ', ' ) ) { return; } return stateText.split( ', ' )[1].toLowerCase(); } function applyBothFilters() { var selectedDate = $dateSelect.val().toLowerCase(); var selectedState = $stateSelect.val().toLowerCase(); var filterClass = (selectedDate && selectedDate.length ? ('.' + selectedDate ) : ( '.' + CL_ALL ) ); filterClass += ( selectedState && selectedState.length ? ('.' + selectedState ) : '' ); var $showRows = $allRows.filter( filterClass ); $allRows.not( $showRows ).hide(); $showRows.show(); if( !$showRows.length ) { $errorRow.show(); } } } );