Skip to content

Commit d4051bc

Browse files
committed
Merge branch 'FieldPickerListData' of https://github.com/joaojmendes/sp-dev-fx-controls-react into joaojmendes-FieldPickerListData
2 parents 8c229e9 + 7be70aa commit d4051bc

File tree

8 files changed

+205
-3
lines changed

8 files changed

+205
-3
lines changed

src/FieldPickerListData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './controls/fields/fieldPickerListData/index';
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import * as React from "react";
2+
import { IFieldPickerListDataProps } from "./IFieldPickerListDataProps";
3+
import { IFieldPickerListDataState } from "./IFieldPickerListDataState";
4+
import { escape } from "@microsoft/sp-lodash-subset";
5+
import { TagPicker } from "office-ui-fabric-react/lib/components/pickers/TagPicker/TagPicker";
6+
import SPservice from "../../../services/SPService";
7+
import { Label } from "office-ui-fabric-react/lib/Label";
8+
9+
10+
export class FieldPickerListData extends React.Component<
11+
IFieldPickerListDataProps,
12+
IFieldPickerListDataState
13+
> {
14+
private _value: Array<any>;
15+
private _spservice: SPservice;
16+
constructor(props: IFieldPickerListDataProps) {
17+
super(props);
18+
// States
19+
this.state = {
20+
noresultsFoundText:
21+
typeof this.props.noresultsFoundText === undefined
22+
? "No Items Found"
23+
: this.props.noresultsFoundText,
24+
showError: false,
25+
errorMessage: "",
26+
suggestionsHeaderText:
27+
typeof this.props.sugestedHeaderText === undefined
28+
? "Select Value"
29+
: this.props.sugestedHeaderText
30+
};
31+
32+
// Get SPService Factory
33+
this._spservice = new SPservice(this.props.context);
34+
35+
// handlers
36+
this.onFilterChanged = this.onFilterChanged.bind(this);
37+
this.getTextFromItem = this.getTextFromItem.bind(this);
38+
this.onItemChanged = this.onItemChanged.bind(this);
39+
40+
// Teste Parameters
41+
this._value = this.props.value !== undefined ? this.props.value : [];
42+
}
43+
// Render Field
44+
public render(): React.ReactElement<IFieldPickerListDataProps> {
45+
const { className, disabled, itemLimit } = this.props;
46+
return (
47+
<div>
48+
<TagPicker
49+
onResolveSuggestions={this.onFilterChanged}
50+
// getTextFromItem={(item: any) => { return item.name; }}
51+
getTextFromItem={this.getTextFromItem}
52+
pickerSuggestionsProps={{
53+
suggestionsHeaderText: this.state.suggestionsHeaderText,
54+
noResultsFoundText: this.state.noresultsFoundText
55+
}}
56+
defaultSelectedItems={this._value}
57+
onChange={this.onItemChanged}
58+
className={className}
59+
itemLimit={itemLimit}
60+
disabled={disabled}
61+
/>
62+
<Label style={{color:'#FF0000'}}> {this.state.errorMessage} </Label>
63+
</div>
64+
);
65+
}
66+
// Get text from Item
67+
private getTextFromItem(item: any): string {
68+
return item.name;
69+
}
70+
/*
71+
On Selected Item
72+
*/
73+
private onItemChanged(selectedItems: { key: string; name: string }[]): void {
74+
let item: { key: string; name: string } = selectedItems[0];
75+
console.log(`selected items nr: ${selectedItems.length}`);
76+
this.props.onSelectedItem(selectedItems);
77+
}
78+
// Filter Change
79+
private onFilterChanged(
80+
filterText: string,
81+
tagList: { key: string; name: string }[]
82+
) {
83+
return new Promise<{ key: string; name: string }[]>((resolve, reject) => {
84+
this.loadListItems(filterText)
85+
.then((resolvedSugestions: { key: string; name: string }[]) => {
86+
this.setState({
87+
errorMessage: "",
88+
showError: false
89+
});
90+
resolve(resolvedSugestions);
91+
})
92+
.catch((reason: any) => {
93+
console.log(`Error get Items ${reason}`);
94+
this.setState({
95+
showError: true,
96+
errorMessage: reason.message,
97+
noresultsFoundText: reason.message
98+
});
99+
resolve([]);
100+
});
101+
});
102+
}
103+
/*
104+
Function to load List Items
105+
*/
106+
private async loadListItems(
107+
filterText: string
108+
): Promise<{ key: string; name: string }[]> {
109+
let { listId, columnInternalName, webUrl } = this.props;
110+
let arrayItems: { key: string; name: string }[] = [];
111+
try {
112+
let listItems = await this._spservice.getListItems(
113+
filterText,
114+
listId,
115+
columnInternalName,
116+
webUrl
117+
);
118+
// has Items ?
119+
if (listItems.length > 0) {
120+
listItems.map((item, i) => {
121+
arrayItems.push({ key: item.Id, name: item[columnInternalName] });
122+
});
123+
}
124+
return Promise.resolve(arrayItems);
125+
} catch (error) {
126+
return Promise.reject(error);
127+
}
128+
}
129+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { WebPartContext } from "@microsoft/sp-webpart-base";
2+
import { ApplicationCustomizerContext } from "@microsoft/sp-application-base";
3+
export interface IFieldPickerListDataProps {
4+
listId: string;
5+
columnInternalName:string;
6+
onSelectedItem: (item:any) => void;
7+
className?: string;
8+
webUrl?:string;
9+
value?:Array<string>;
10+
disabled?: boolean;
11+
itemLimit: number;
12+
context: WebPartContext | ApplicationCustomizerContext;
13+
sugestedHeaderText?:string;
14+
noresultsFoundText?:string;
15+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface IFieldPickerListDataState {
2+
noresultsFoundText: string;
3+
showError: boolean;
4+
errorMessage: string;
5+
suggestionsHeaderText:string;
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// A file is required to be in the root of the /src directory by the TypeScript compiler
2+
export * from './IFieldPickerListDataProps';
3+
export * from './IFieldPickerListDataState';
4+
export * from '../../../services/SPService';
5+
export * from './FieldPickerListData';

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ export * from './FieldTextRenderer';
2222
export * from './FieldTitleRenderer';
2323
export * from './FieldUrlRenderer';
2424
export * from './FieldUserRenderer';
25+
export * from './FieldPickerListData';

src/services/ISPService.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ export interface ISPService {
1818
* @param options Options used to order and filter during the API query
1919
*/
2020
getLibs(options?: ILibsOptions): Promise<ISPLists>;
21-
}
21+
getListItems?(
22+
filterText: string,
23+
listId: string,
24+
internalColumnName: string,
25+
webUrl?: string
26+
) : Promise<any[]>;
27+
}

src/services/SPService.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import { ISPService, ILibsOptions, LibsOrderBy } from "./ISPService";
22
import { ISPLists } from "../common/SPEntities";
33
import { WebPartContext } from "@microsoft/sp-webpart-base";
4-
import { ApplicationCustomizerContext } from '@microsoft/sp-application-base';
4+
import { ApplicationCustomizerContext } from "@microsoft/sp-application-base";
55
import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http";
6+
import { sp, Web } from "@pnp/sp";
67

78
export default class SPService implements ISPService {
89

9-
constructor(private _context: WebPartContext | ApplicationCustomizerContext) {}
10+
constructor(private _context: WebPartContext | ApplicationCustomizerContext) {
11+
sp.setup({
12+
spfxContext: this._context
13+
});
14+
}
15+
1016

1117
/**
1218
* Get lists or libraries
@@ -33,4 +39,37 @@ export default class SPService implements ISPService {
3339
return this._context.spHttpClient.get(queryUrl, SPHttpClient.configurations.v1)
3440
.then(response => response.json()) as Promise<ISPLists>;
3541
}
42+
43+
/**
44+
* Get List Items
45+
*
46+
*/
47+
public async getListItems(
48+
filterText: string,
49+
listId: string,
50+
internalColumnName: string,
51+
webUrl?: string
52+
): Promise<any[]> {
53+
let filter = `startswith(${internalColumnName},'${filterText}')`;
54+
let returnItems: any[];
55+
console.log(
56+
`Page context url ${this._context.pageContext.web.absoluteUrl}`
57+
);
58+
let spWeb: Web;
59+
if (typeof webUrl === undefined) {
60+
spWeb = new Web(webUrl);
61+
} else {
62+
spWeb = new Web(this._context.pageContext.web.absoluteUrl);
63+
}
64+
try {
65+
returnItems = await spWeb.lists
66+
.getById(listId)
67+
.items.select("Id", internalColumnName)
68+
.filter(filter)
69+
.get();
70+
return Promise.resolve(returnItems);
71+
} catch (error) {
72+
return Promise.reject(error);
73+
}
74+
}
3675
}

0 commit comments

Comments
 (0)