Added sorting
This commit is contained in:
parent
39ea25afc2
commit
7a06e35851
|
@ -46,6 +46,7 @@ Version|Date|Comments
|
||||||
2.0|January 19, 2020|Upgrade to SPFx 1.10
|
2.0|January 19, 2020|Upgrade to SPFx 1.10
|
||||||
2.1|June 22, 2020|Added pagination (Abhishek Garg)
|
2.1|June 22, 2020|Added pagination (Abhishek Garg)
|
||||||
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
|
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
|
||||||
|
2.3|September 30, 2021 | Added sorting (@fthorild)
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "react-accordion-client-side-solution",
|
"name": "react-accordion-client-side-solution",
|
||||||
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
|
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
|
||||||
"version": "2.2.0.0",
|
"version": "2.3.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"isDomainIsolated": false
|
"isDomainIsolated": false
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "react-accordion",
|
"name": "react-accordion",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -29,10 +29,13 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
|
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
|
||||||
"listName": "FAQ",
|
"listName": "FAQ",
|
||||||
"totalItems":20,
|
"totalItems": 20,
|
||||||
"maxItemsPerPage": 5,
|
"maxItemsPerPage": 5,
|
||||||
"allowPaging":true
|
"allowPaging": true,
|
||||||
|
"customSortField": "",
|
||||||
|
"sortById": false,
|
||||||
|
"sortByModified": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { Version, DisplayMode } from '@microsoft/sp-core-library';
|
import { Version, DisplayMode } from '@microsoft/sp-core-library';
|
||||||
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
import { IPropertyPaneConfiguration, PropertyPaneSlider, PropertyPaneTextField,PropertyPaneToggle } from "@microsoft/sp-property-pane";
|
import { IPropertyPaneConfiguration, PropertyPaneSlider, PropertyPaneTextField, PropertyPaneToggle } from "@microsoft/sp-property-pane";
|
||||||
|
|
||||||
import * as strings from 'ReactAccordionWebPartStrings';
|
import * as strings from 'ReactAccordionWebPartStrings';
|
||||||
import ReactAccordion from './components/ReactAccordion';
|
import ReactAccordion from './components/ReactAccordion';
|
||||||
|
@ -13,16 +13,19 @@ export interface IReactAccordionWebPartProps {
|
||||||
choice: string;
|
choice: string;
|
||||||
title: string;
|
title: string;
|
||||||
displayMode: DisplayMode;
|
displayMode: DisplayMode;
|
||||||
totalItems:number;
|
totalItems: number;
|
||||||
maxItemsPerPage: number;
|
maxItemsPerPage: number;
|
||||||
enablePaging:boolean;
|
enablePaging: boolean;
|
||||||
|
customSortField: string;
|
||||||
|
sortById: boolean;
|
||||||
|
sortByModified: boolean;
|
||||||
updateProperty: (value: string) => void;
|
updateProperty: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
|
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
|
||||||
const element: React.ReactElement<IReactAccordionProps> = React.createElement(
|
const element: React.ReactElement<IReactAccordionProps> = React.createElement(
|
||||||
ReactAccordion,
|
ReactAccordion,
|
||||||
{
|
{
|
||||||
|
@ -31,9 +34,12 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
siteUrl: this.context.pageContext.web.absoluteUrl,
|
siteUrl: this.context.pageContext.web.absoluteUrl,
|
||||||
title: this.properties.title,
|
title: this.properties.title,
|
||||||
displayMode: this.displayMode,
|
displayMode: this.displayMode,
|
||||||
totalItems:this.properties.totalItems,
|
totalItems: this.properties.totalItems,
|
||||||
maxItemsPerPage: this.properties.maxItemsPerPage,
|
maxItemsPerPage: this.properties.maxItemsPerPage,
|
||||||
enablePaging:this.properties.enablePaging,
|
enablePaging: this.properties.enablePaging,
|
||||||
|
customSortField: this.properties.customSortField,
|
||||||
|
sortById: this.properties.sortById,
|
||||||
|
sortByModified: this.properties.sortByModified,
|
||||||
updateProperty: (value: string) => {
|
updateProperty: (value: string) => {
|
||||||
this.properties.title = value;
|
this.properties.title = value;
|
||||||
}
|
}
|
||||||
|
@ -53,10 +59,10 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
|
|
||||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
//set maxitems to top
|
//set maxitems to top
|
||||||
if(!this.properties.enablePaging){
|
if (!this.properties.enablePaging) {
|
||||||
this.properties.maxItemsPerPage = this.properties.totalItems;
|
this.properties.maxItemsPerPage = this.properties.totalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
|
@ -83,7 +89,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
label: strings.EnablePagingLabel
|
label: strings.EnablePagingLabel
|
||||||
}),
|
}),
|
||||||
PropertyPaneSlider('maxItemsPerPage', {
|
PropertyPaneSlider('maxItemsPerPage', {
|
||||||
disabled:!this.properties.enablePaging,
|
disabled: !this.properties.enablePaging,
|
||||||
label: strings.MaxItemsPerPageLabel,
|
label: strings.MaxItemsPerPageLabel,
|
||||||
ariaLabel: strings.MaxItemsPerPageLabel,
|
ariaLabel: strings.MaxItemsPerPageLabel,
|
||||||
min: 3,
|
min: 3,
|
||||||
|
@ -91,6 +97,14 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
||||||
value: 5,
|
value: 5,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
step: 1
|
step: 1
|
||||||
|
}),
|
||||||
|
PropertyPaneTextField('customSortField', {
|
||||||
|
label: strings.CustomSortOrder
|
||||||
|
}),
|
||||||
|
PropertyPaneToggle('sortById', {
|
||||||
|
label: strings.SortById
|
||||||
|
}),PropertyPaneToggle('sortByModified', {
|
||||||
|
label: strings.SortByModified
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,8 @@ export interface IReactAccordionProps {
|
||||||
maxItemsPerPage: number;
|
maxItemsPerPage: number;
|
||||||
enablePaging:boolean;
|
enablePaging:boolean;
|
||||||
totalItems:number;
|
totalItems:number;
|
||||||
|
customSortField:string;
|
||||||
|
sortById:boolean;
|
||||||
|
sortByModified:boolean;
|
||||||
updateProperty: (value: string) => void;
|
updateProperty: (value: string) => void;
|
||||||
}
|
}
|
|
@ -7,4 +7,5 @@ export interface IReactAccordionState {
|
||||||
listItems: IAccordionListItem[];
|
listItems: IAccordionListItem[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
loaderMessage: string;
|
loaderMessage: string;
|
||||||
}
|
error: string;
|
||||||
|
}
|
|
@ -30,7 +30,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
items: [],
|
items: [],
|
||||||
listItems: [],
|
listItems: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ''
|
loaderMessage: '',
|
||||||
|
error: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.listNotConfigured(this.props)) {
|
if (!this.listNotConfigured(this.props)) {
|
||||||
|
@ -73,8 +74,24 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
}
|
}
|
||||||
|
|
||||||
private readItems(): void {
|
private readItems(): void {
|
||||||
|
|
||||||
let restAPI = this.props.siteUrl + `/_api/web/Lists/GetByTitle('${this.props.listName}')/items?$select=Title,Description&$top=${this.props.totalItems}`;
|
const orders = [];
|
||||||
|
if (this.props.customSortField) {
|
||||||
|
orders.push(this.props.customSortField);
|
||||||
|
}
|
||||||
|
if (this.props.sortById) {
|
||||||
|
orders.push('ID');
|
||||||
|
}
|
||||||
|
if (this.props.sortByModified) {
|
||||||
|
orders.push('Modified');
|
||||||
|
}
|
||||||
|
|
||||||
|
const selects = `select=Title,Description${this.props.customSortField ? `,${this.props.customSortField}` : ''}`;
|
||||||
|
|
||||||
|
const restAPI = this.props.siteUrl + `/_api/web/Lists/GetByTitle('${this.props.listName}')/items?` +
|
||||||
|
`$${selects}` +
|
||||||
|
`${orders.length > 0 ? '&$orderby=' + orders.join(',') : ''}` +
|
||||||
|
`&$top=${this.props.totalItems}`;
|
||||||
|
|
||||||
this.props.spHttpClient.get(restAPI, SPHttpClient.configurations.v1, {
|
this.props.spHttpClient.get(restAPI, SPHttpClient.configurations.v1, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -86,6 +103,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((response: { value: IAccordionListItem[] }): void => {
|
.then((response: { value: IAccordionListItem[] }): void => {
|
||||||
|
if (!response.value) {
|
||||||
|
this.setState({
|
||||||
|
error: `No items were found, check the list Title and/or custom sort order field internal name`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let listItemsCollection = [...response.value];
|
let listItemsCollection = [...response.value];
|
||||||
|
|
||||||
|
@ -95,14 +117,16 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
items: response.value,
|
items: response.value,
|
||||||
listItems: response.value,
|
listItems: response.value,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ""
|
loaderMessage: '',
|
||||||
|
error: ''
|
||||||
});
|
});
|
||||||
}, (error: any): void => {
|
}, (error: any): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
status: 'Loading all items failed with error: ' + error,
|
status: 'Loading all items failed with error: ' + error,
|
||||||
pagedItems: [],
|
pagedItems: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loaderMessage: ""
|
loaderMessage: "",
|
||||||
|
error: `Loading failed. Validate that you have entered a valid List Title and/or internal field name for the custom sort order ${error}`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,6 +134,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
|
|
||||||
public render(): React.ReactElement<IReactAccordionProps> {
|
public render(): React.ReactElement<IReactAccordionProps> {
|
||||||
let displayLoader;
|
let displayLoader;
|
||||||
|
let errorMessage;
|
||||||
let faqTitle;
|
let faqTitle;
|
||||||
let { items } = this.state;
|
let { items } = this.state;
|
||||||
let pageCountDivisor: number = this.props.maxItemsPerPage;
|
let pageCountDivisor: number = this.props.maxItemsPerPage;
|
||||||
|
@ -149,7 +174,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
displayLoader = (null);
|
displayLoader = (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.props.enablePaging){
|
if (this.props.enablePaging) {
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
pageCount = Math.ceil(items.length / pageCountDivisor);
|
pageCount = Math.ceil(items.length / pageCountDivisor);
|
||||||
}
|
}
|
||||||
|
@ -157,6 +182,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
pageButtons.push(<PrimaryButton onClick={() => { _pagedButtonClick(i + 1, items); }}> {i + 1} </PrimaryButton>);
|
pageButtons.push(<PrimaryButton onClick={() => { _pagedButtonClick(i + 1, items); }}> {i + 1} </PrimaryButton>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.state.error) {
|
||||||
|
errorMessage = <div>{this.state.error}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.reactAccordion}>
|
<div className={styles.reactAccordion}>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
@ -175,7 +205,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
<div className={`ms-Grid-row`}>
|
<div className={`ms-Grid-row`}>
|
||||||
<div className='ms-Grid-col ms-u-lg12'>
|
<div className='ms-Grid-col ms-u-lg12'>
|
||||||
{this.state.status}
|
{this.state.status}
|
||||||
<Accordion accordion={false}>
|
<Accordion>
|
||||||
{pagedItems}
|
{pagedItems}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,7 +216,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{errorMessage}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,9 @@ define([], function () {
|
||||||
"ListNameLabel": "List Name",
|
"ListNameLabel": "List Name",
|
||||||
"MaxItemsPerPageLabel": "Max number of items per page",
|
"MaxItemsPerPageLabel": "Max number of items per page",
|
||||||
"EnablePagingLabel":"Enable Paging",
|
"EnablePagingLabel":"Enable Paging",
|
||||||
"TotalItemsLabel":"Maximum items to retrieve"
|
"TotalItemsLabel":"Maximum items to retrieve",
|
||||||
|
"CustomSortOrder":"Custom sort order",
|
||||||
|
"SortById":"Sort by ID",
|
||||||
|
"SortByModified":"Sort by modified date"
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -5,6 +5,9 @@ declare interface IReactAccordionWebPartStrings {
|
||||||
MaxItemsPerPageLabel: string;
|
MaxItemsPerPageLabel: string;
|
||||||
EnablePagingLabel: string;
|
EnablePagingLabel: string;
|
||||||
TotalItemsLabel:string;
|
TotalItemsLabel:string;
|
||||||
|
CustomSortOrder:string;
|
||||||
|
SortById:string;
|
||||||
|
SortByModified:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'ReactAccordionWebPartStrings' {
|
declare module 'ReactAccordionWebPartStrings' {
|
||||||
|
|
Loading…
Reference in New Issue