Merge pull request #2060 from fthorild/fthorild/issue2056
Added sorting fixing #2056
This commit is contained in:
commit
4cae8f5e6b
|
@ -22,9 +22,14 @@ This is a sample web Part that illustrates the use of React Accessible Accordion
|
|||
|
||||
![Sample Web Part built using SPFx with React Framework showing list data in accordion format](./assets/AccordionPreview.png)
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
|
||||
![1.10.0](https://img.shields.io/badge/drop-1.10.0-green.svg)
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.10](https://img.shields.io/badge/SPFx-1.10.0-green.svg)
|
||||
![Node.js LTS 10.x | LTS 8.x](https://img.shields.io/badge/Node.js-LTS%2010.x%7C%20LTS%208.x-green.svg) ![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||
![Teams N/A: Untested with Microsoft Teams](https://img.shields.io/badge/Teams-N%2FA-lightgrey.svg "Untested with Microsoft Teams")
|
||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
||||
|
||||
|
||||
## Applies to
|
||||
|
||||
|
@ -46,11 +51,7 @@ Version|Date|Comments
|
|||
2.0|January 19, 2020|Upgrade to SPFx 1.10
|
||||
2.1|June 22, 2020|Added pagination (Abhishek Garg)
|
||||
2.2|October 1, 2020 | Added new Pagination Configuration (@beau__cameron)
|
||||
|
||||
## 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.**
|
||||
|
||||
---
|
||||
2.3|September 30, 2021 | Added sorting (@fthorild)
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
|
@ -94,4 +95,19 @@ This sample illustrates the following concepts on top of the SharePoint Framewor
|
|||
- searching in the fetched data by making use of Search Box from Office Fabric UI
|
||||
|
||||
|
||||
## 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.**
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||
|
||||
If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||
|
||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||
|
||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=REACT-ACCORDION&authors=@AbhishekGarg%20@gautamdsheth&title=REACT-ACCORDION%20-%20).
|
||||
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-accordion" />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"This is a sample web Part that illustrates the use of React Accessible Accordion plugin for building SharePoint Framework client-side web parts to show SharePoint list data in Accordion format."
|
||||
],
|
||||
"creationDateTime": "2020-06-22",
|
||||
"updateDateTime": "2020-06-22",
|
||||
"updateDateTime": "2021-09-30",
|
||||
"products": [
|
||||
"SharePoint",
|
||||
"Office"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"solution": {
|
||||
"name": "react-accordion-client-side-solution",
|
||||
"id": "6d6cf05b-cfe5-4d12-af19-19ec3aedcaf9",
|
||||
"version": "2.2.0.0",
|
||||
"version": "2.3.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "react-accordion",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "react-accordion",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"engines": {
|
||||
|
|
|
@ -29,10 +29,13 @@
|
|||
"properties": {
|
||||
"description": "SPFx webpart which shows SharePoint list data in Accordion format",
|
||||
"listName": "FAQ",
|
||||
"totalItems":20,
|
||||
"totalItems": 20,
|
||||
"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 { Version, DisplayMode } from '@microsoft/sp-core-library';
|
||||
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 ReactAccordion from './components/ReactAccordion';
|
||||
|
@ -13,16 +13,19 @@ export interface IReactAccordionWebPartProps {
|
|||
choice: string;
|
||||
title: string;
|
||||
displayMode: DisplayMode;
|
||||
totalItems:number;
|
||||
totalItems: number;
|
||||
maxItemsPerPage: number;
|
||||
enablePaging:boolean;
|
||||
enablePaging: boolean;
|
||||
customSortField: string;
|
||||
sortById: boolean;
|
||||
sortByModified: boolean;
|
||||
updateProperty: (value: string) => void;
|
||||
}
|
||||
|
||||
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
|
||||
|
||||
const element: React.ReactElement<IReactAccordionProps> = React.createElement(
|
||||
ReactAccordion,
|
||||
{
|
||||
|
@ -31,9 +34,12 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
|||
siteUrl: this.context.pageContext.web.absoluteUrl,
|
||||
title: this.properties.title,
|
||||
displayMode: this.displayMode,
|
||||
totalItems:this.properties.totalItems,
|
||||
totalItems: this.properties.totalItems,
|
||||
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) => {
|
||||
this.properties.title = value;
|
||||
}
|
||||
|
@ -53,10 +59,10 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
|||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
//set maxitems to top
|
||||
if(!this.properties.enablePaging){
|
||||
if (!this.properties.enablePaging) {
|
||||
this.properties.maxItemsPerPage = this.properties.totalItems;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
|
@ -83,7 +89,7 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
|||
label: strings.EnablePagingLabel
|
||||
}),
|
||||
PropertyPaneSlider('maxItemsPerPage', {
|
||||
disabled:!this.properties.enablePaging,
|
||||
disabled: !this.properties.enablePaging,
|
||||
label: strings.MaxItemsPerPageLabel,
|
||||
ariaLabel: strings.MaxItemsPerPageLabel,
|
||||
min: 3,
|
||||
|
@ -91,6 +97,14 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
|
|||
value: 5,
|
||||
showValue: true,
|
||||
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;
|
||||
enablePaging:boolean;
|
||||
totalItems:number;
|
||||
customSortField:string;
|
||||
sortById:boolean;
|
||||
sortByModified:boolean;
|
||||
updateProperty: (value: string) => void;
|
||||
}
|
||||
}
|
|
@ -7,4 +7,5 @@ export interface IReactAccordionState {
|
|||
listItems: IAccordionListItem[];
|
||||
isLoading: boolean;
|
||||
loaderMessage: string;
|
||||
}
|
||||
error: string;
|
||||
}
|
|
@ -30,7 +30,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
items: [],
|
||||
listItems: [],
|
||||
isLoading: false,
|
||||
loaderMessage: ''
|
||||
loaderMessage: '',
|
||||
error: ''
|
||||
};
|
||||
|
||||
if (!this.listNotConfigured(this.props)) {
|
||||
|
@ -73,8 +74,24 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
}
|
||||
|
||||
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, {
|
||||
headers: {
|
||||
|
@ -86,6 +103,11 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
return response.json();
|
||||
})
|
||||
.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];
|
||||
|
||||
|
@ -95,14 +117,16 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
items: response.value,
|
||||
listItems: response.value,
|
||||
isLoading: false,
|
||||
loaderMessage: ""
|
||||
loaderMessage: '',
|
||||
error: ''
|
||||
});
|
||||
}, (error: any): void => {
|
||||
this.setState({
|
||||
status: 'Loading all items failed with error: ' + error,
|
||||
pagedItems: [],
|
||||
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> {
|
||||
let displayLoader;
|
||||
let errorMessage;
|
||||
let faqTitle;
|
||||
let { items } = this.state;
|
||||
let pageCountDivisor: number = this.props.maxItemsPerPage;
|
||||
|
@ -149,7 +174,7 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
displayLoader = (null);
|
||||
}
|
||||
|
||||
if(this.props.enablePaging){
|
||||
if (this.props.enablePaging) {
|
||||
if (items.length > 0) {
|
||||
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>);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.error) {
|
||||
errorMessage = <div>{this.state.error}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.reactAccordion}>
|
||||
<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-col ms-u-lg12'>
|
||||
{this.state.status}
|
||||
<Accordion accordion={false}>
|
||||
<Accordion>
|
||||
{pagedItems}
|
||||
</Accordion>
|
||||
</div>
|
||||
|
@ -186,7 +216,8 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{errorMessage}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@ define([], function () {
|
|||
"ListNameLabel": "List Name",
|
||||
"MaxItemsPerPageLabel": "Max number of items per page",
|
||||
"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;
|
||||
EnablePagingLabel: string;
|
||||
TotalItemsLabel:string;
|
||||
CustomSortOrder:string;
|
||||
SortById:string;
|
||||
SortByModified:string;
|
||||
}
|
||||
|
||||
declare module 'ReactAccordionWebPartStrings' {
|
||||
|
|
Loading…
Reference in New Issue