Reputation: 409
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
Upvotes: 5
Views: 3735
Reputation: 469
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.
Upvotes: 2
Reputation: 2803
You can filter and sort in render() before return.
this.props.results.filter(item => item.keep).sort((item1, item2) => item1.value - item2.value);
Upvotes: 0