Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering and sorting React

I am new in development React I have a project where I have to add the filter and sort functionality on my table and I really do not know where to start. The template below: How can proceed?

import * as React from 'react';
import { SPComponentLoader } from '@microsoft/sp-loader';

import styles from '../components/SearchSpfx.module.scss';
import { ISearchSpfxWebPartProps } from '../ISearchSpfxWebPartProps';

import * as moment from 'moment';

export interface ITableTemplate extends ISearchSpfxWebPartProps {
	results: any[];
}

export default class TableTemplate extends React.Component<ITableTemplate, {}> {
	private iconUrl: string = "https://spoprod-a.akamaihd.net/files/odsp-next-prod_ship-2016-08-15_20160815.002/odsp-media/images/filetypes/16/";
	private unknown: string[] = ['aspx', 'null'];

	private getAuthorDisplayName(author: string): string {
		if (author !== null) {
			const splits: string[] = author.split('|');
			return splits[1].trim();
		} else {
			return "";
		}
	}

	private getDateFromString(retrievedDate: string): string {
		if (retrievedDate !== null) {
			return moment(retrievedDate).format('DD/MM/YYYY');
		} else {
			return "";
		}
	}

	public render(): JSX.Element {
		// Load the Office UI Fabrics components css file via the module loader
    	SPComponentLoader.loadCss('https://appsforoffice.microsoft.com/fabric/2.6.1/fabric.components.min.css');

		return (
			<div className={styles.searchSpfx}>
				{
					(() => {
						// Check if you need to show a title
						if (this.props.title !== "") {
							return <h1 className='ms-font-xxl'>{this.props.title}</h1>;
						}
					})()
				}

				<table className={`ms-Table ${styles.templateTable}`}>
					<thead>
						<tr>
							<th>Type</th>
							<th>Name</th>
							<th>Modified</th>
							<th>Modified by</th>
						</tr>
					</thead>
					<tbody>
						{
							this.props.results.map((result, index) => {
								return (<tr key={index}>
											<td>
												<a href={result.Path}><img src={`${this.iconUrl}${result.Fileextension !== null && this.unknown.indexOf(result.Fileextension) === -1 ? result.Fileextension : 'code'}.png`} alt="File extension"/></a>
											</td>
											<td>
												<a href={result.Path}>{result.Filename !== null ? result.Filename.substring(0, result.Filename.lastIndexOf('.')) : ""}</a>
											</td>
											<td>{this.getDateFromString(result.ModifiedOWSDATE)}</td>
											<td>{this.getAuthorDisplayName(result.EditorOWSUSER)}</td>
										</tr>);
							})
						}
					</tbody>
				</table>
			</div>
		);
	}
}

Thank you guys

like image 401
Amine Zel Avatar asked Nov 09 '22 00:11

Amine Zel


1 Answers

Here's some working code of how you could implement a table that can be filtered and sorted. Here, the sorting happens whenever you click on the row header. this.props.data for this example is:

[
    {"Type":"foo", "Name": 0, "Modified": "3/20/2017", "ModifiedBy":"Me"},
    {"Type":"foo", "Name": 2, "Modified": "3/15/2017", "ModifiedBy":"You"},
    {"Type":"buzz", "Name": 1, "Modified": "3/20/2017", "ModifiedBy":"Me"}
];

And the react class is:

const SortableFilterableTable = React.createClass({
    getInitialState: function(){
        return({data:this.getSortedData('Type')});
    },
    render: function(){

        let rows = this.state.data.map((rowData) =>{
            return(
                <tr>
                    <td>{rowData.Type}</td>
                    <td>{rowData.Name}</td>
                    <td>{rowData.Modified}</td>
                    <td>{rowData.ModifiedBy}</td>
                </tr>
            );
        });
        return(
            <div>
                <input type="text" id="filter" onChange={this.filterTable}/>
                <table>
                    <thead>
                        <tr>
                            <th onClick={()=>this.setSortedData('Type')}>Type</th>
                            <th onClick={()=>this.setSortedData('Name')}>Name</th>
                            <th onClick={()=>this.setSortedData('Modified')}>Modified</th>
                            <th onClick={()=>this.setSortedData('Modified By')}>Modified By</th>
                        </tr>
                    </thead>
                    <tbody>
                        {rows}
                    </tbody>
                </table>
            </div>
        );
    },
    setSortedData: function(sortBy){
        this.setState({data:this.getSortedData(sortBy)});
    },
    getSortedData: function(sortBy){
        //data handed down from props
        let dataToSort = this.props.data;

        //you can implement your own sorting algorithm here. I think this one
        //will only work if the properties are integers.
        dataToSort.sort(function(a,b){
            if(sortBy === 'Type')
                return a.Type - b.Type;
            if(sortBy === 'Name')
                return a.Name - b.Name;
            if(sortBy === 'Modified')
                return a.Modified - b.Modified;
            if(sortBy === 'Modified By')
                return a.ModifiedBy - b.ModifiedBy;
        });
        return dataToSort;
    },
    filterTable: function(e){
        let text = e.target.value;
        let filterFunc = (value) => {
            console.log(value)
            if(value.Type.indexOf(text) >= 0 || value.Name.toString().indexOf(text) >= 0 || value.Modified.indexOf(text) >= 0 || value.ModifiedBy.indexOf(text) >= 0)
                return true;
            console.log('made it ')
            return false;
        };

        let dataForState = this.props.data.filter(filterFunc);
        this.setState({data:dataForState});
    }
});

You'll have to make your own sorting algorithm to work for strings and dates. With this code, the only column that will be correctly sorted when you click the table header is the Name column.

like image 62
Micaiah Reid Avatar answered Nov 14 '22 22:11

Micaiah Reid