Merged Mike Zimmerman's changes

This commit is contained in:
Hugo Bernier 2020-09-03 00:50:03 -04:00 committed by Ryan Schouten
parent 48cd995985
commit 30f3c2ca80
7 changed files with 103 additions and 41 deletions

View File

@ -17,7 +17,6 @@
* The value in the Content column for each item will appear in the collapsible content section of the Accordion
* When creating the columns, select "Multiple lines of text". Rich text is now supported within the Content column.
![Create list for use with the Accordion](./assets/ListForAccordion.png)
**2) Add the Accordion Section web part to your page & select your list:**
@ -35,17 +34,17 @@
* [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
* [Office 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
> Update accordingly as needed.
## Prerequisites
> Any special pre-requisites?
Please create the list as described above
## Solution
Solution|Author(s)
--------|---------
SPFx Collapsible Accordion Section|[Erik Benke](https://github.com/ejbenke) ([@erikjbenke](https://twitter.com/erikjbenke))
SPFx Collapsible Accordion Section|[Mike Zimmerman](https://github.com/mikezimm)
## Version history
@ -57,6 +56,8 @@ Version|Date|Comments
1.3|July 10, 2020|Adding Rich Text support for Content panels
1.4|July 10, 2020|Upgraded to SPFx 1.10.
1.5|September 1, 2020|Adds ability to click on expanded section headers to collapse accordions
1.6|September 2, 2020|Added Web Part Title, and ability to expand multiple sections
## Disclaimer

View File

@ -3,11 +3,11 @@
"solution": {
"name": "Accordion Section FAQ Builder",
"id": "bf6fa974-fd40-45a3-80e9-e826abe025b9",
"version": "1.5.0.0",
"version": "1.6.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true
},
"paths": {
"zippedPackage": "solution/FAQ-Accordion.sppkg"
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "react-accordion",
"main": "lib/index.js",
"version": "1.5.0",
"version": "1.6.0",
"private": true,
"engines": {
"node": ">=0.10.0"
@ -47,4 +47,4 @@
"ajv": "~5.2.2",
"gulp": "~3.9.1"
}
}
}

View File

@ -23,7 +23,8 @@
"officeFabricIconFontName": "MusicInCollectionFill",
"properties": {
"description": "React Accordion",
"listId": ""
"listId": "",
"allowZeroExpanded": true
}
}]
}

View File

@ -5,6 +5,7 @@ import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneToggle,
PropertyPaneDropdown,
IPropertyPaneDropdownOption
} from '@microsoft/sp-property-pane';
@ -22,6 +23,8 @@ import { string } from 'prop-types';
export interface IReactAccordionWebPartProps {
listId: string;
accordionTitle: string;
allowZeroExpanded: boolean;
allowMultipleExpanded: boolean;
}
export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactAccordionWebPartProps> {
@ -40,6 +43,12 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
{
listId: this.properties.listId,
accordionTitle: this.properties.accordionTitle,
allowZeroExpanded: this.properties.allowZeroExpanded,
allowMultipleExpanded: this.properties.allowMultipleExpanded,
displayMode: this.displayMode,
updateProperty: (value: string) => {
this.properties.accordionTitle = value;
},
onConfigure: () => {
this.context.propertyPane.open();
}
@ -68,9 +77,6 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('accordionTitle', {
label: 'Accordion Title (optional)'
}),
PropertyFieldListPicker('listId', {
label: 'Select a list',
selectedList: this.properties.listId,
@ -83,7 +89,17 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
onGetErrorMessage: null,
deferredValidationTime: 0,
key: 'listPickerFieldId'
})
}),
PropertyPaneToggle('allowZeroExpanded', {
label: 'Allow zero expanded',
checked: this.properties.allowZeroExpanded,
key: 'allowZeroExpanded',
}),
PropertyPaneToggle('allowMultipleExpanded', {
label: 'Allow multiple expand',
checked: this.properties.allowMultipleExpanded,
key: 'allowMultipleExpanded',
}),
]
}
]
@ -91,4 +107,25 @@ export default class ReactAccordionWebPart extends BaseClientSideWebPart<IReactA
]
};
}
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
/**
* This section is used to determine when to refresh the pane options
*/
let updateOnThese = [
'allowZeroExpanded','allowMultipleExpanded','listId',
];
//alert('props updated');
console.log('onPropertyPaneFieldChanged:', propertyPath, oldValue, newValue);
if (updateOnThese.indexOf(propertyPath) > -1 ) {
this.properties[propertyPath] = newValue;
this.context.propertyPane.refresh();
} else { //This can be removed if it works
}
this.render();
}
}

View File

@ -1,5 +1,11 @@
import { DisplayMode } from '@microsoft/sp-core-library';
export interface IReactAccordionProps {
listId: string;
accordionTitle: string;
allowZeroExpanded: boolean;
allowMultipleExpanded: boolean;
displayMode: DisplayMode;
updateProperty: (value: string) => void;
onConfigure: () => void;
}
}

View File

@ -3,6 +3,7 @@ import styles from './ReactAccordion.module.scss';
import { IReactAccordionProps } from './IReactAccordionProps';
import { sp } from "@pnp/sp";
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
import './reactAccordion.css';
import {
@ -15,44 +16,57 @@ import {
export interface IReactAccordionState {
items: Array<any>;
allowMultipleExpanded: boolean;
allowZeroExpanded: boolean;
}
export default class ReactAccordion extends React.Component<IReactAccordionProps, IReactAccordionState> {
constructor(props: IReactAccordionProps) {
super(props);
this.state = {
items: new Array<any>()
items: new Array<any>(),
allowMultipleExpanded: this.props.allowMultipleExpanded,
allowZeroExpanded: this.props.allowZeroExpanded
};
this.getListItems();
}
private getListItems(): void {
if(typeof this.props.listId !== "undefined" && this.props.listId.length > 0) {
sp.web.lists.getById(this.props.listId).items.select("Title","Content").get()
if (typeof this.props.listId !== "undefined" && this.props.listId.length > 0) {
sp.web.lists.getById(this.props.listId).items.select("Title", "Content").get()
.then((results: Array<any>) => {
this.setState({
items: results
});
})
.catch((error:any) => {
.catch((error: any) => {
console.log("Failed to get list items!");
console.log(error);
});
}
}
public componentDidUpdate(prevProps:IReactAccordionProps): void {
if(prevProps.listId !== this.props.listId) {
public componentDidUpdate(prevProps: IReactAccordionProps): void {
if (prevProps.listId !== this.props.listId) {
this.getListItems();
}
if (prevProps.allowMultipleExpanded !== this.props.allowMultipleExpanded || prevProps.allowZeroExpanded !== this.props.allowZeroExpanded) {
this.setState({
allowMultipleExpanded: this.props.allowMultipleExpanded,
allowZeroExpanded: this.props.allowZeroExpanded
});
}
}
public render(): React.ReactElement<IReactAccordionProps> {
let listSelected:boolean = typeof this.props.listId !== "undefined" && this.props.listId.length > 0;
const listSelected: boolean = typeof this.props.listId !== "undefined" && this.props.listId.length > 0;
const { allowMultipleExpanded, allowZeroExpanded } = this.state;
return (
<div className={ styles.reactAccordion }>
<div className={styles.reactAccordion}>
{!listSelected &&
<Placeholder
iconName='MusicInCollectionFill'
@ -62,28 +76,31 @@ export default class ReactAccordion extends React.Component<IReactAccordionProps
onConfigure={this.props.onConfigure} />
}
{listSelected &&
<div>
<h2>{this.props.accordionTitle}</h2>
<Accordion allowZeroExpanded>
{this.state.items.map((item:any) => {
return (
<AccordionItem>
<AccordionItemHeading>
<AccordionItemButton>
{item.Title}
</AccordionItemButton>
</AccordionItemHeading>
<div>
<WebPartTitle displayMode={this.props.displayMode}
title={this.props.accordionTitle}
updateProperty={this.props.updateProperty}
/>
<Accordion allowZeroExpanded={allowZeroExpanded} allowMultipleExpanded={allowMultipleExpanded}>
{this.state.items.map((item: any) => {
return (
<AccordionItem>
<AccordionItemHeading>
<AccordionItemButton>
{item.Title}
</AccordionItemButton>
</AccordionItemHeading>
<AccordionItemPanel>
<p dangerouslySetInnerHTML={{__html: item.Content}} />
<p dangerouslySetInnerHTML={{ __html: item.Content }} />
</AccordionItemPanel>
</AccordionItem>
</AccordionItem>
);
})
}
</Accordion>
</div>
}
</Accordion>
</div>
}
</div>
);
);
}
}
}