Skip to content

Commit f004a95

Browse files
authored
Merge pull request #50 from AJIXuMuK/field-lookup-optimization
Lookup Field Renderer Optimization
2 parents 3cfa7ae + 55e88b6 commit f004a95

File tree

3 files changed

+92
-35
lines changed

3 files changed

+92
-35
lines changed

docs/documentation/docs/controls/fields/FieldLookupRenderer.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { FieldLookupRenderer } from "@pnp/spfx-controls-react/lib/FieldLookupRen
2222
- Use the `FieldLookupRenderer` control in your code as follows:
2323

2424
```TypeScript
25-
<FieldLookupRenderer lookups={event.fieldValue} dispFormUrl={'https://contoso.sharepoint.com/_layouts/15/listform.aspx?PageType=4&ListId={list_id}'} className={'some-class'} cssProps={{ background: '#f00' }} />
25+
<FieldLookupRenderer lookups={event.fieldValue} fieldId={'<field-guid>'} context={this.context} className={'some-class'} cssProps={{ background: '#f00' }} />
2626
```
2727

2828
## Implementation
@@ -36,6 +36,8 @@ The FieldLookupRenderer component can be configured with the following propertie
3636
| lookups | ISPFieldLookupValue[] | yes | Lookup field values. |
3737
| dispFormUrl | boolean | no | Url of Display form for the list that is referenced by the lookup. |
3838
| onClick | (args: ILookupClickEventArgs) => {} | no | Custom event handler of lookup item click. If not set the dialog with Display Form will be shown. |
39+
| fieldId | string | Field's id |
40+
| context | IContext | Customizer context. Must be providede if fieldId is set |
3941

4042
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/fields/FieldLookupRenderer)
4143

src/common/utilities/FieldRendererHelper.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,18 @@ export class FieldRendererHelper {
132132
break;
133133
case "Lookup":
134134
case "LookupMulti":
135-
SPHelper.getLookupFieldListDispFormUrl(field.id.toString(), context).then(dispFormUrlValue => {
136-
const lookupValues = fieldValue as ISPFieldLookupValue[];
137-
const dispFormUrl: string = dispFormUrlValue.toString();
138-
resolve(React.createElement(FieldLookupRenderer, {
139-
lookups: lookupValues,
140-
dispFormUrl: dispFormUrl,
141-
...props
142-
}));
143-
});
144-
135+
//
136+
// we're providing fieldId and context. In that case Lookup values will be rendered right away
137+
// without additional lag of waiting of response to get dispUrl.
138+
// The request for DispUrl will be sent only if user click on the value
139+
//
140+
const lookupValues = fieldValue as ISPFieldLookupValue[];
141+
resolve(React.createElement(FieldLookupRenderer, {
142+
lookups: lookupValues,
143+
fieldId: field.id.toString(),
144+
context: context,
145+
...props
146+
}));
145147
break;
146148
case 'URL':
147149
SPHelper.getFieldProperty(field.id.toString(), 'Format', context, true).then(format => {

src/controls/fields/fieldLookupRenderer/FieldLookupRenderer.tsx

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import { override } from '@microsoft/decorators';
22
import * as React from 'react';
3-
import { css, DialogType, Link } from 'office-ui-fabric-react';
3+
import { css, Dialog, DialogType, Link, Spinner, SpinnerSize } from 'office-ui-fabric-react';
44

55
import { ISPFieldLookupValue } from "../../../common/SPEntities";
66
import { IFieldRendererProps } from '../fieldCommon/IFieldRendererProps';
77
import * as appInsights from '../../../common/appInsights';
88

99
import styles from './FieldLookupRenderer.module.scss';
1010
import IFrameDialog from '../../iFrameDialog/IFrameDialog';
11+
import { SPHelper } from '../../../Utilities';
12+
import { IContext } from '../../../Common';
1113

14+
/**
15+
* Field Lookup Renderer Props
16+
* There are 3 options to provide the props:
17+
* - [recommended, used in FieldRendererHelper] Provide fieldId and context. In that case request for DispUrl will be sent only if a user clicks on the value
18+
* - Provide dispFormUrl: if you know this URL a priori you can provide it into the renderer
19+
* - Provide onClick handler to handle value's click event outside the renderer
20+
*/
1221
export interface IFieldLookupRendererProps extends IFieldRendererProps {
1322
/**
1423
* lookup values
@@ -22,14 +31,23 @@ export interface IFieldLookupRendererProps extends IFieldRendererProps {
2231
* custom event handler of lookup item click. If not set the dialog with Display Form will be shown
2332
*/
2433
onClick?: (args: IFieldLookupClickEventArgs) => {};
34+
/**
35+
* Field's id.
36+
*/
37+
fieldId?: string;
38+
/**
39+
* Customizer context. Must be providede if fieldId is set
40+
*/
41+
context?: IContext;
2542
}
2643

2744
/**
28-
* For future
45+
* Field Lookup Renderer State
2946
*/
3047
export interface IFieldLookupRendererState {
3148
hideDialog?: boolean;
3249
lookupDispFormUrl?: string;
50+
dispFormUrl?: string;
3351
}
3452

3553
/**
@@ -51,7 +69,8 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
5169
appInsights.track('FieldLookupRenderer', {});
5270

5371
this.state = {
54-
hideDialog: true
72+
hideDialog: true,
73+
dispFormUrl: props.dispFormUrl
5574
};
5675
}
5776

@@ -61,23 +80,35 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
6180
return <Link onClick={this._onClick.bind(this, lookup)} className={styles.lookup} style={this.props.cssProps}>{lookup.lookupValue}</Link>;
6281
});
6382
return (
64-
<div style={this.props.cssProps} className={css(this.props.className)}>{lookupLinks}
65-
{!this.state.hideDialog && <IFrameDialog
66-
url={this.state.lookupDispFormUrl}
67-
iframeOnLoad={this._onIframeLoaded.bind(this)}
68-
hidden={this.state.hideDialog}
69-
onDismiss={this._onDialogDismiss.bind(this)}
70-
modalProps={{
71-
isBlocking: true,
72-
containerClassName: styles.dialogContainer
73-
}}
74-
dialogContentProps={{
75-
type: DialogType.close,
76-
showCloseButton: true
77-
}}
78-
width={'570px'}
79-
height={'315px'}/>}
80-
</div>);
83+
<div style={this.props.cssProps} className={css(this.props.className)}>{lookupLinks}
84+
{!this.state.hideDialog && this.state.dispFormUrl && <IFrameDialog
85+
url={this.state.lookupDispFormUrl}
86+
iframeOnLoad={this._onIframeLoaded.bind(this)}
87+
hidden={this.state.hideDialog}
88+
onDismiss={this._onDialogDismiss.bind(this)}
89+
modalProps={{
90+
isBlocking: true,
91+
containerClassName: styles.dialogContainer
92+
}}
93+
dialogContentProps={{
94+
type: DialogType.close,
95+
showCloseButton: true
96+
}}
97+
width={'570px'}
98+
height={'315px'} />}
99+
{!this.state.hideDialog && !this.state.dispFormUrl && <Dialog
100+
onDismiss={this._onDialogDismiss.bind(this)}
101+
modalProps={{
102+
isBlocking: true,
103+
containerClassName: styles.dialogContainer
104+
}}
105+
dialogContentProps={{
106+
type: DialogType.close,
107+
showCloseButton: true
108+
}}>
109+
<Spinner size={SpinnerSize.large} />
110+
</Dialog>}
111+
</div>);
81112
}
82113

83114
private _onClick(lookup: ISPFieldLookupValue): void {
@@ -92,10 +123,32 @@ export class FieldLookupRenderer extends React.Component<IFieldLookupRendererPro
92123
//
93124
// showing Display Form in the dialog
94125
//
95-
this.setState({
96-
lookupDispFormUrl: `${this.props.dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`,
97-
hideDialog: false
98-
});
126+
if (this.state.dispFormUrl) {
127+
this.setState({
128+
lookupDispFormUrl: `${this.state.dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`,
129+
hideDialog: false
130+
});
131+
}
132+
else if (this.props.fieldId) {
133+
134+
this.setState({
135+
hideDialog: false
136+
});
137+
138+
SPHelper.getLookupFieldListDispFormUrl(this.props.fieldId, this.props.context).then(dispFormUrlValue => {
139+
const dispFormUrl: string = dispFormUrlValue.toString();
140+
this.setState((prevState, props) => {
141+
if (prevState.hideDialog) {
142+
return;
143+
}
144+
145+
return {
146+
dispFormUrl: dispFormUrl,
147+
lookupDispFormUrl: `${dispFormUrl}&ID=${lookup.lookupId}&RootFolder=*&IsDlg=1`
148+
};
149+
});
150+
});
151+
}
99152
}
100153

101154
private _onIframeLoaded(iframe: any): void {

0 commit comments

Comments
 (0)