将组合框绑定到共享点列表
Bind combobox to sharepoint list
此代码展示了如何使用 React 在 Sharepoint 在线 Web 部件中使用组合框。示例数据是硬编码的。如何将组合框绑定到 Sharepoint 列表?
```
import * as React from 'react';
import { ComboBox, Fabric, IComboBoxOption, mergeStyles,
SelectableOptionMenuItemType, Toggle } from 'office-ui-fabric-
react/lib/index';
const INITIAL_OPTIONS: IComboBoxOption[] = [
{ key: 'Header1', text: 'First heading', itemType:
SelectableOptionMenuItemType.Header },
{ key: 'A', text: 'Option A' },
{ key: 'B', text: 'Option B' },
{ key: 'C', text: 'Option C' },
{ key: 'D', text: 'Option D' },
{ key: 'divider', text: '-',
itemType: SelectableOptionMenuItemType.Divider },
{ key: 'Header2', text: 'Second heading', itemType:
SelectableOptionMenuItemType.Header },
{ key: 'E', text: 'Option E' },
{ key: 'F', text: 'Option F', disabled: true },
{ key: 'G', text: 'Option G' },
{ key: 'H', text: 'Option H' },
{ key: 'I', text: 'Option I' },
{ key: 'J', text: 'Option J' }
];
const wrapperClassName = mergeStyles({
display: 'flex',
selectors: {
'& > *': { marginRight: '20px' },
'& .ms-ComboBox': { maxWidth: '300px' }
}
});
export interface IComboBoxTogglesExampleState {
autoComplete: boolean;
allowFreeform: boolean;
}
// tslint:disable:jsx-no-lambda
export class ComboBoxTogglesExample extends React.Component<{},
IComboBoxTogglesExampleState> {
public state: IComboBoxTogglesExampleState = {
autoComplete: false,
allowFreeform: true
};
public render(): JSX.Element {
const state = this.state;
return (
<Fabric className={wrapperClassName}>
<ComboBox
label="ComboBox with toggleable freeform/auto-complete"
key={'' + state.autoComplete + state.allowFreeform /*key causes re-
render when toggles change*/}
allowFreeform={state.allowFreeform}
autoComplete={state.autoComplete ? 'on' : 'off'}
options={INITIAL_OPTIONS}
/>
<Toggle
label="Allow freeform"
checked={state.allowFreeform}
onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) =>
{
this.setState({ allowFreeform: !!checked });
}}
/>
<Toggle
label="Auto-complete"
checked={state.autoComplete}
onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) =>
{
this.setState({ autoComplete: !!checked });
}}
/>
</Fabric>
);
}
}
```
这是使用 React Framework 的 Sharepoint Online webpart。
我有一个包含 60 个成本中心的列表,我希望它们显示在一个组合框中并打开自动完成功能。
示例演示(很多测试场景,只检查您需要的逻辑):
export interface IListItem{
Id: number;
Title: string;
Body : {
Body_p1: string;
Body_p2: string;
};
}
export interface IReactExState{
controlName:string,
ControlValue:string,
windowsID:number,
showPanel:boolean,
items: IListItem[],
Options:IComboBoxOption[],
selectionDetails: {},
showModal: boolean,
autoComplete: boolean,
allowFreeform: boolean
}
export default class OfficeFabric extends React.Component<IOfficeFabricProps, IReactExState> {
private _selection: Selection;
private _allItems: IListItem[];
private _columns: IColumn[];
public constructor(props: IOfficeFabricProps,state: IReactExState){
super(props);
this._selection = new Selection({
onSelectionChanged: () => this.setState({ selectionDetails: this._getSelectionDetails() })
});
this._allItems = [
{
Id : 0,
Title : "test0",
Body : {
Body_p1: "test0_p1",
Body_p2: "test0_p2"
},
},
{
Id : 1,
Title : "test1",
Body : {
Body_p1: "test1_p1",
Body_p2: "test1_p2"
}
}
];
this._columns = [
{ key: 'Id', name: 'Id', fieldName: 'Id', minWidth: 100, maxWidth: 200, isResizable: true },
{ key: 'Title', name: 'Title', fieldName: 'Title', minWidth: 200, maxWidth: 400, isResizable: true },
{ key: 'Body', name: 'Body', minWidth: 200, maxWidth: 400, isResizable: true,onRender: (item) => (
<div>
{item.Body.Body_p1}
</div>) },
];
this.state = {
controlName:"",
ControlValue:"",
windowsID:123.4,
showPanel:false,
items:this._allItems,
Options:[],
selectionDetails: this._getSelectionDetails() ,
showModal:false,
autoComplete: false,
allowFreeform: true
};
}
private _showModal = (): void => {
this.setState({ showModal: true });
};
private _closeModal = (): void => {
this.setState({ showModal: false });
};
private _getSelectionDetails(): string {
const selectionCount = this._selection.getSelectedCount();
switch (selectionCount) {
case 0:
return 'No items selected';
case 1:
return '1 item selected: ' + (this._selection.getSelection()[0] as IListItem).Title;
default:
return `${selectionCount} items selected`;
}
}
private _onItemInvoked = (item: IListItem): void => {
alert(`Item invoked: ${item.Title}`);
};
private _showPanel = () => {
this.setState({ showPanel: true });
};
private _hidePanel = () => {
this.setState({ showPanel: false });
};
private _Save = () => {
//to do save logic
this.setState({ showPanel: false });
alert('save clicked');
};
private _onRenderFooterContent = () => {
return (
<div>
<PrimaryButton onClick={this._hidePanel} style={{ marginRight: '8px' }}>
Save
</PrimaryButton>
<DefaultButton onClick={this._showPanel}>Cancel</DefaultButton>
</div>
);
};
public componentDidMount(){
var reactHandler = this;
this.props.context.spHttpClient.get(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestList')/items?select=ID,Title`,
SPHttpClient.configurations.v1) .then((response: SPHttpClientResponse) => {
response.json().then((responseJSON: any) => {
let tempOptions:IComboBoxOption[]=[];
responseJSON.value.forEach(element => {
tempOptions.push({key:element.ID,text:element.Title})
});
reactHandler.setState({
Options: tempOptions
});
});
});
}
// private _onJobTitReportToChange = (ev: React.FormEvent<HTMLInputElement>, newValue?: string) => {
// this.props.onJobTitleReportToChange(newValue);
// }
public handleObjectWithMultipleFields = (ev, newText: string): void => {
const target = ev.target;
const value = newText;
var _ControlName=target.name;
this.setState({
controlName: _ControlName,
ControlValue:value
})
}
public render(): React.ReactElement<IOfficeFabricProps> {
return (
<div className={ styles.officeFabric }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint!</span>
<p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
<p className={ styles.description }>{escape(this.props.description)}</p>
<ComboBox
label="ComboBox with toggleable freeform/auto-complete"
key={'' + this.state.autoComplete + this.state.allowFreeform /*key causes re-
render when toggles change*/}
allowFreeform={this.state.allowFreeform}
autoComplete={this.state.autoComplete ? 'on' : 'off'}
options={this.state.Options}
/>
<TextField name="txtA" value={this.state.windowsID.toString()}
onChange={this.handleObjectWithMultipleFields}/>
<TextField name="txtB"
onChange={this.handleObjectWithMultipleFields}/>
<div>
<DefaultButton secondaryText="Opens the Sample Panel" onClick={this._showPanel} text="Open Panel" />
<Panel
isOpen={this.state.showPanel}
type={PanelType.smallFixedFar}
onDismiss={this._hidePanel}
headerText="Panel - Small, right-aligned, fixed, with footer"
closeButtonAriaLabel="Close"
onRenderFooterContent={this._onRenderFooterContent}
>
<DefaultButton className={styles.tablink} text="Button" />
<ChoiceGroup
options={[
{
key: 'A',
text: 'Option A'
},
{
key: 'B',
text: 'Option B',
checked: true
},
{
key: 'C',
text: 'Option C',
disabled: true
},
{
key: 'D',
text: 'Option D',
checked: true,
disabled: true
}
]}
label="Pick one"
required={true}
/>
</Panel>
<DefaultButton secondaryText="Opens the Sample Modal" onClick={this._showModal} text="Open Modal" />
</div>
<MarqueeSelection selection={this._selection}>
<DetailsList
items={this.state.items}
columns={this._columns}
setKey="set"
layoutMode={DetailsListLayoutMode.justified}
selection={this._selection}
selectionPreservedOnEmptyClick={true}
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
checkButtonAriaLabel="Row checkbox"
onItemInvoked={this._onItemInvoked}
/>
</MarqueeSelection>
<a href="https://aka.ms/spfx" className={ styles.button }>
<span className={ styles.label }>Learn more</span>
</a>
<Icon iconName='Mail' />
<br/>
<Icon iconName='CirclePlus' />
<br/>
<Icon iconName='LocationDot' />
</div>
</div>
</div>
</div>
);
}
}
我最终使用了这个。
sp.web.lists.getByTitle("ChartOfAccounts").items.getAll().then((result: any)=>{
for(let i: number = 0; i< result.length; i++) {
const b: SPData = result[i];
const c: IComboBoxOption={key:b.Column1, text: b.CostCentreInfo};
INITIAL_OPTIONS.push(c);
}
此代码展示了如何使用 React 在 Sharepoint 在线 Web 部件中使用组合框。示例数据是硬编码的。如何将组合框绑定到 Sharepoint 列表?
```
import * as React from 'react';
import { ComboBox, Fabric, IComboBoxOption, mergeStyles,
SelectableOptionMenuItemType, Toggle } from 'office-ui-fabric-
react/lib/index';
const INITIAL_OPTIONS: IComboBoxOption[] = [
{ key: 'Header1', text: 'First heading', itemType:
SelectableOptionMenuItemType.Header },
{ key: 'A', text: 'Option A' },
{ key: 'B', text: 'Option B' },
{ key: 'C', text: 'Option C' },
{ key: 'D', text: 'Option D' },
{ key: 'divider', text: '-',
itemType: SelectableOptionMenuItemType.Divider },
{ key: 'Header2', text: 'Second heading', itemType:
SelectableOptionMenuItemType.Header },
{ key: 'E', text: 'Option E' },
{ key: 'F', text: 'Option F', disabled: true },
{ key: 'G', text: 'Option G' },
{ key: 'H', text: 'Option H' },
{ key: 'I', text: 'Option I' },
{ key: 'J', text: 'Option J' }
];
const wrapperClassName = mergeStyles({
display: 'flex',
selectors: {
'& > *': { marginRight: '20px' },
'& .ms-ComboBox': { maxWidth: '300px' }
}
});
export interface IComboBoxTogglesExampleState {
autoComplete: boolean;
allowFreeform: boolean;
}
// tslint:disable:jsx-no-lambda
export class ComboBoxTogglesExample extends React.Component<{},
IComboBoxTogglesExampleState> {
public state: IComboBoxTogglesExampleState = {
autoComplete: false,
allowFreeform: true
};
public render(): JSX.Element {
const state = this.state;
return (
<Fabric className={wrapperClassName}>
<ComboBox
label="ComboBox with toggleable freeform/auto-complete"
key={'' + state.autoComplete + state.allowFreeform /*key causes re-
render when toggles change*/}
allowFreeform={state.allowFreeform}
autoComplete={state.autoComplete ? 'on' : 'off'}
options={INITIAL_OPTIONS}
/>
<Toggle
label="Allow freeform"
checked={state.allowFreeform}
onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) =>
{
this.setState({ allowFreeform: !!checked });
}}
/>
<Toggle
label="Auto-complete"
checked={state.autoComplete}
onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) =>
{
this.setState({ autoComplete: !!checked });
}}
/>
</Fabric>
);
}
}
```
这是使用 React Framework 的 Sharepoint Online webpart。
我有一个包含 60 个成本中心的列表,我希望它们显示在一个组合框中并打开自动完成功能。
示例演示(很多测试场景,只检查您需要的逻辑):
export interface IListItem{
Id: number;
Title: string;
Body : {
Body_p1: string;
Body_p2: string;
};
}
export interface IReactExState{
controlName:string,
ControlValue:string,
windowsID:number,
showPanel:boolean,
items: IListItem[],
Options:IComboBoxOption[],
selectionDetails: {},
showModal: boolean,
autoComplete: boolean,
allowFreeform: boolean
}
export default class OfficeFabric extends React.Component<IOfficeFabricProps, IReactExState> {
private _selection: Selection;
private _allItems: IListItem[];
private _columns: IColumn[];
public constructor(props: IOfficeFabricProps,state: IReactExState){
super(props);
this._selection = new Selection({
onSelectionChanged: () => this.setState({ selectionDetails: this._getSelectionDetails() })
});
this._allItems = [
{
Id : 0,
Title : "test0",
Body : {
Body_p1: "test0_p1",
Body_p2: "test0_p2"
},
},
{
Id : 1,
Title : "test1",
Body : {
Body_p1: "test1_p1",
Body_p2: "test1_p2"
}
}
];
this._columns = [
{ key: 'Id', name: 'Id', fieldName: 'Id', minWidth: 100, maxWidth: 200, isResizable: true },
{ key: 'Title', name: 'Title', fieldName: 'Title', minWidth: 200, maxWidth: 400, isResizable: true },
{ key: 'Body', name: 'Body', minWidth: 200, maxWidth: 400, isResizable: true,onRender: (item) => (
<div>
{item.Body.Body_p1}
</div>) },
];
this.state = {
controlName:"",
ControlValue:"",
windowsID:123.4,
showPanel:false,
items:this._allItems,
Options:[],
selectionDetails: this._getSelectionDetails() ,
showModal:false,
autoComplete: false,
allowFreeform: true
};
}
private _showModal = (): void => {
this.setState({ showModal: true });
};
private _closeModal = (): void => {
this.setState({ showModal: false });
};
private _getSelectionDetails(): string {
const selectionCount = this._selection.getSelectedCount();
switch (selectionCount) {
case 0:
return 'No items selected';
case 1:
return '1 item selected: ' + (this._selection.getSelection()[0] as IListItem).Title;
default:
return `${selectionCount} items selected`;
}
}
private _onItemInvoked = (item: IListItem): void => {
alert(`Item invoked: ${item.Title}`);
};
private _showPanel = () => {
this.setState({ showPanel: true });
};
private _hidePanel = () => {
this.setState({ showPanel: false });
};
private _Save = () => {
//to do save logic
this.setState({ showPanel: false });
alert('save clicked');
};
private _onRenderFooterContent = () => {
return (
<div>
<PrimaryButton onClick={this._hidePanel} style={{ marginRight: '8px' }}>
Save
</PrimaryButton>
<DefaultButton onClick={this._showPanel}>Cancel</DefaultButton>
</div>
);
};
public componentDidMount(){
var reactHandler = this;
this.props.context.spHttpClient.get(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestList')/items?select=ID,Title`,
SPHttpClient.configurations.v1) .then((response: SPHttpClientResponse) => {
response.json().then((responseJSON: any) => {
let tempOptions:IComboBoxOption[]=[];
responseJSON.value.forEach(element => {
tempOptions.push({key:element.ID,text:element.Title})
});
reactHandler.setState({
Options: tempOptions
});
});
});
}
// private _onJobTitReportToChange = (ev: React.FormEvent<HTMLInputElement>, newValue?: string) => {
// this.props.onJobTitleReportToChange(newValue);
// }
public handleObjectWithMultipleFields = (ev, newText: string): void => {
const target = ev.target;
const value = newText;
var _ControlName=target.name;
this.setState({
controlName: _ControlName,
ControlValue:value
})
}
public render(): React.ReactElement<IOfficeFabricProps> {
return (
<div className={ styles.officeFabric }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint!</span>
<p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
<p className={ styles.description }>{escape(this.props.description)}</p>
<ComboBox
label="ComboBox with toggleable freeform/auto-complete"
key={'' + this.state.autoComplete + this.state.allowFreeform /*key causes re-
render when toggles change*/}
allowFreeform={this.state.allowFreeform}
autoComplete={this.state.autoComplete ? 'on' : 'off'}
options={this.state.Options}
/>
<TextField name="txtA" value={this.state.windowsID.toString()}
onChange={this.handleObjectWithMultipleFields}/>
<TextField name="txtB"
onChange={this.handleObjectWithMultipleFields}/>
<div>
<DefaultButton secondaryText="Opens the Sample Panel" onClick={this._showPanel} text="Open Panel" />
<Panel
isOpen={this.state.showPanel}
type={PanelType.smallFixedFar}
onDismiss={this._hidePanel}
headerText="Panel - Small, right-aligned, fixed, with footer"
closeButtonAriaLabel="Close"
onRenderFooterContent={this._onRenderFooterContent}
>
<DefaultButton className={styles.tablink} text="Button" />
<ChoiceGroup
options={[
{
key: 'A',
text: 'Option A'
},
{
key: 'B',
text: 'Option B',
checked: true
},
{
key: 'C',
text: 'Option C',
disabled: true
},
{
key: 'D',
text: 'Option D',
checked: true,
disabled: true
}
]}
label="Pick one"
required={true}
/>
</Panel>
<DefaultButton secondaryText="Opens the Sample Modal" onClick={this._showModal} text="Open Modal" />
</div>
<MarqueeSelection selection={this._selection}>
<DetailsList
items={this.state.items}
columns={this._columns}
setKey="set"
layoutMode={DetailsListLayoutMode.justified}
selection={this._selection}
selectionPreservedOnEmptyClick={true}
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
checkButtonAriaLabel="Row checkbox"
onItemInvoked={this._onItemInvoked}
/>
</MarqueeSelection>
<a href="https://aka.ms/spfx" className={ styles.button }>
<span className={ styles.label }>Learn more</span>
</a>
<Icon iconName='Mail' />
<br/>
<Icon iconName='CirclePlus' />
<br/>
<Icon iconName='LocationDot' />
</div>
</div>
</div>
</div>
);
}
}
我最终使用了这个。
sp.web.lists.getByTitle("ChartOfAccounts").items.getAll().then((result: any)=>{
for(let i: number = 0; i< result.length; i++) {
const b: SPData = result[i];
const c: IComboBoxOption={key:b.Column1, text: b.CostCentreInfo};
INITIAL_OPTIONS.push(c);
}