methnen / m-chart

Manage data sets and display them as charts in WordPress.
Other
43 stars 22 forks source link

[Request] Allow table data be sorted / filtered by column headings #191

Open RIPcounties opened 1 month ago

RIPcounties commented 1 month ago

An option to allow site visitors to sort (filter?) table data by clicking on a column heading would be helpful for our project.

(Providing this feature for visitors is the only reason we are currently using Ninja Tables alongside M Chart).

https://ripcounties.ie/the-national-picture/

methnen commented 1 month ago

That's definitely out of the intended scope of the plugin.

However, I've purposely put many hooks into the existing code to allow for just these kinds of things.

I don't think I've documented this one in the wiki yet, but there's a hook right where the table template is called:

require apply_filters( 'm_chart_table_template', $template, $library, $post->ID );

You could use that hook to return the path of a different table template inside of your theme and then do whatever you want in there.

The default table template looks like this:

<table class="<?php echo esc_attr( $classes ); ?>">
    <?php
    $set_name = '';

    if ( $multiple ) {
        $set_name = ': ' . $post_meta['set_names'][ $set ];
    }

    if ( isset( m_chart()->parse()->value_labels['first_row'] ) ) {
        $first_row = m_chart()->parse()->value_labels['first_row'];
        $labels    = m_chart()->parse()->value_labels['first_column'];

        $row_column = false;

        if ( count( $first_row ) == count( m_chart()->parse()->set_data[0] ) ) {
            $row_column = true;
        }
        ?>
        <tr><th colspan="<?php echo count( $first_row ) + 1; ?>"><?php echo get_the_title( $post_id ) . $set_name; ?></th></tr>
        <tr>
            <th></th>
            <?php
            foreach ( $first_row as $label ) {
                ?>
                <th><?php echo esc_html( $label ); ?></th>
                <?php
            }
            ?>
        </tr>
        <?php
        foreach ( $labels as $row => $label ) {
            ?>
            <tr>
                <th><?php echo esc_html( $label ); ?></th>
                <?php
                foreach ( $first_row as $column => $label ) {
                    if ( $row_column ) {
                        $value = m_chart()->parse()->set_data[ $row ][ $column ];
                    } else {
                        $value = m_chart()->parse()->set_data[ $column ][ $row ];
                    }

                    if ( is_numeric( $value ) ) {
                        $value = number_format_i18n( $value, strlen( substr( strrchr( $value, '.'), 1 ) ) );
                        $value = '' != $value ? m_chart()->parse()->data_prefix . $value . m_chart()->parse()->data_suffix : '';
                    }
                    ?>
                    <td><?php echo esc_html( $value ); ?></td>
                    <?php
                }
                ?>
            </tr>
            <?php
        }
    } else {
        $first_row = m_chart()->parse()->value_labels;
        ?>
        <tr><th colspan="<?php echo count( $first_row ); ?>"><?php echo get_the_title( $post_id ) . $set_name; ?></th></tr>
        <tr>
            <?php
            foreach ( $first_row as $label ) {
                ?>
                <th><?php echo esc_html( $label ); ?></th>
                <?php
            }
            ?>
        </tr>
        <tr>
            <?php
            $row_count = 1;
            $total_rows = count( m_chart()->parse()->set_data ) / count( $first_row );

            foreach ( m_chart()->parse()->set_data as $key => $value ) {
                if ( is_numeric( $value ) ) {
                    $value = number_format_i18n( $value, strlen( substr( strrchr( $value, '.'), 1 ) ) );
                    $value = '' != $value ? m_chart()->parse()->data_prefix . $value . m_chart()->parse()->data_suffix : '';
                }
                ?>
                <td><?php echo esc_html( $value ); ?></td>
                <?php

                if ( ( $key + 1 ) / ( count( $first_row ) * $row_count ) == 1 ) {
                    $row_count++;

                    if ( $row_count <= $total_rows ) {
                        ?>
                        </tr><tr>
                        <?php
                    }
                }
            }
            ?>
        </tr>
    <?php
    }
    ?>
</table>

You could use that as a starting point to build alternate versions of table output that include whatever features you like. And there are many javascript libraries out there for adding sorting features to HTML tables.

RIPcounties commented 1 month ago

Thanks. A bit beyond my basic skills. But I know a developer who might help out.

methnen commented 1 month ago

Happy to help them along/point them in the right direction when the time comes.