Customisation: 'Day' filter as drop-down list

Home Forums Calendar Products Community Events Customisation: 'Day' filter as drop-down list

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #1020851
    Timothy Lindsay
    Participant

    We’d like to create our own filter based on the built-in Day filter, but instead of giving the user a list of checkboxes, we want them to select from a drop-down list.

    We’ve begun by taking a copy of the code in src > Tribe > Filters > Day_Of_Week.php and placing it in our functions.php. The only thing we’ve changed is the name of the class (to Tribe__Events__Filterbar__Filters__Day_Of_Week_Dropdown) and $type, which we’ve set to ‘select’.

    We’ve also added an action hook to register the new filter.

    Here’s the actual code:

    
    class Tribe__Events__Filterbar__Filters__Day_Of_Week_Dropdown extends Tribe__Events__Filterbar__Filter {
    
        public $type = 'select';
    
        protected function get_values() {
            $day_of_week_array = array(
                __( 'Sunday', 'tribe-events-filter-view' ),
                __( 'Monday', 'tribe-events-filter-view' ),
                __( 'Tuesday', 'tribe-events-filter-view' ),
                __( 'Wednesday', 'tribe-events-filter-view' ),
                __( 'Thursday', 'tribe-events-filter-view' ),
                __( 'Friday', 'tribe-events-filter-view' ),
                __( 'Saturday', 'tribe-events-filter-view' )
            );
    
            // Get WordPress system value for the start of the week, keep in mind that on WordPress it
            // starts on 0 instead of 1 like we did above.
            $sys_week_start = absint( get_option( 'start_of_week', 0 ) );
    
            $sorted = range( 0, 6 );
    
            // Push the items of the array until the start_of_week to the end
            for ( $i = 0; $i < $sys_week_start; $i ++ ) {
                array_push( $sorted, array_shift( $sorted ) );
            }
    
            $day_of_week_values = array();
            foreach ( $sorted as $n ) {
                $day_of_week_values[] = array(
                    'name'  => $day_of_week_array[ $n ],
                    'value' => $n + 1,
                );
            }
    
            return $day_of_week_values;
        }
    
        /**
         * Add modifications to the query
         *
         * @return void
         */
        protected function setup_query_filters() {
            global $wp_query;
            // band-aid for month view
            if ( $wp_query->is_main_query() && $wp_query->get( 'eventDisplay' ) == 'month' ) {
                $wp_query->set(
                    'meta_query', array(
                        array(
                            'key'  => '_EventStartDate',
                            'type' => 'DATETIME',
                        ),
                    )
                );
            }
            parent::setup_query_filters();
        }
    
        protected function setup_join_clause() {
            add_filter( 'posts_join', array( 'Tribe__Events__Query', 'posts_join' ), 10, 2 );
        }
    
        protected function setup_where_clause() {
    
            /** @var wpdb $wpdb */
            global $wpdb;
            $clauses = array();
            $values = array_map( 'intval', $this->currentValue );
            $values = implode( ',', $values );
    
            $eod_cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
            if ( $eod_cutoff != '00:00' ) {
                $eod_time_difference = Tribe__Events__Date_Utils::timeBetween( '1/1/2014 00:00:00', "1/1/2014 {$eod_cutoff}:00" );
                $start_date = "DATE_SUB({$wpdb->postmeta}.meta_value, INTERVAL {$eod_time_difference} SECOND)";
                $end_date = "DATE_SUB(tribe_event_end_date.meta_value, INTERVAL {$eod_time_difference} SECOND)";
            } else {
                $start_date = "{$wpdb->postmeta}.meta_value";
                $end_date = "tribe_event_end_date.meta_value";
            }
    
            $clauses[] = "(DAYOFWEEK($start_date) IN ($values))";
    
            // is it on at least 7 days (first day is 0)
            $clauses[] = "(DATEDIFF($end_date, $start_date) >=6)";
    
            // determine if the start of the nearest matching day is between the start and end dates
            $distance_to_day = array();
            foreach ( $this->currentValue as $day_of_week_index ) {
                $day_of_week_index = (int)$day_of_week_index;
                $distance_to_day[] = "MOD( 7 + $day_of_week_index - DAYOFWEEK($start_date), 7 )";
            }
            if ( count($distance_to_day) > 1 ) {
                $distance_to_next_matching_day = "LEAST(".implode(',', $distance_to_day).")";
            } else {
                $distance_to_next_matching_day = reset($distance_to_day);
            }
            $clauses[] = "(DATE(DATE_ADD($start_date, INTERVAL $distance_to_next_matching_day DAY)) < $end_date)";
    
            $this->whereClause = ' AND ('.implode(' OR ', $clauses).')';
        }
    }
    
    function add_custom_fields_to_tribe_filter_bar(){
        new Tribe__Events__Filterbar__Filters__Day_Of_Week_Dropdown('Day Dropdown', 'dayofweekdropdown');
    }
    add_action('tribe_events_filters_create_filters', 'add_custom_fields_to_tribe_filter_bar');
    

    Doing these small changes gets surprisingly far – the new filter shows up in Settings, and also displays on our events page. However, as soon as we try to use the filter in the front end, we get an endless loading spinner icon. Presumably something has gone wrong – the back end is expecting an array of values from multiple checkboxes, whereas we are now supplying it with just one value.

    We’re going to continue tweaking, and see if we can find a solution, but in the meantime, if you had any pointers they would be much appreciated – thanks!

    P.S. – the custom filter is currently on our dev site only, and not the live site where the plugin is registered.

    • This topic was modified 8 years, 6 months ago by Timothy Lindsay. Reason: additional note
    #1021070
    Brook
    Participant

    Howdy nucreative,

    Great work getting to where you are. That’s exactly what I would have done.

    I can’t say for sure without seeing your PHP error log and playing around wtih it. But you are probably on the right track. I see a couple implodes in there that will probably halt things and throw an error when passed a string. You might try removing them, or casting your string as an array with only one value.

    I hope that helps! We’re happy to provide pointers where we can, but due to the nature of customizations can’t always provide great insight.

    Cheers!

    – Brook

    #1075340
    Support Droid
    Keymaster

    This topic has not been active for quite some time and will now be closed.

    If you still need assistance please simply open a new topic (linking to this one if necessary)
    and one of the team will be only too happy to help.

Viewing 3 posts - 1 through 3 (of 3 total)
  • The topic ‘Customisation: 'Day' filter as drop-down list’ is closed to new replies.