Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1721 #1722

Merged
merged 8 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 23 additions & 21 deletions docs/documentation/docs/controls/ListItemPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Here is an example of the control:
```TypeScript
import { ListItemPicker } from '@pnp/spfx-controls-react/lib/ListItemPicker';
```

- Use the `ListItemPicker` control in your code as follows:

```TypeScript
Expand All @@ -41,30 +42,31 @@ private onSelectedItem(data: { key: string; name: string }[]) {
}
}
```

## Implementation

The `ListItemPicker` control can be configured with the following properties:


| Property | Type | Required | Description |
| ---- | ---- | ---- | ---- |
| columnInternalName | string | yes | InternalName of column to search and get values. |
| keyColumnInternalName | string | no | InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id |
| context | BaseComponentContext | yes | SPFx web part or extention context |
| listId | string | yes | Guid or title of the list. |
| itemLimit | number | yes | Number of items which can be selected |
| onSelectedItem | (items: any[]) => void | yes | Callback function which returns the selected items. |
| className | string | no | ClassName for the picker. |
| webUrl | string | no | URL of the site. By default it uses the current site URL. |
| defaultSelectedItems | any[] | no | Initial items that have already been selected and should appear in the people picker. |
| suggestionsHeaderText | string | no | The text that should appear at the top of the suggestion box. |
| noResultsFoundText | string | no | The text that should appear when no results are returned. |
| disabled | boolean | no | Specifies if the control is disabled or not. |
| filter | string | no | condition to filter list Item, same as $filter ODATA parameter|
| orderBy | string | no | condition to order by list Item, same as $orderby ODATA parameter|
| placeholder | string | no | Short text hint to display in empty picker |
| substringSearch | boolean | no | Specifies if substring search should be used |
| label | string | no | Specifies the text describing the ListItemPicker. |
| enableDefaultSuggestions | boolean | no | Enable default suggestions. All options are displayed by default when clicking on the control. |
| Property | Type | Required | Description |
| ------------------------ | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| columnInternalName | string | yes | InternalName of column to search and get values. |
| keyColumnInternalName | string | no | InternalName of column to use as the key for the selection. Must be a column with unique values. Default: Id |
| context | BaseComponentContext | yes | SPFx web part or extention context |
| listId | string | yes | Guid or title of the list. |
| itemLimit | number | yes | Number of items which can be selected |
| onSelectedItem | (items: any[]) => void | yes | Callback function which returns the selected items. |
| className | string | no | ClassName for the picker. |
| webUrl | string | no | URL of the site. By default it uses the current site URL. |
| defaultSelectedItems | any[] | no | Initial items that have already been selected and should appear in the people picker. |
| suggestionsHeaderText | string | no | The text that should appear at the top of the suggestion box. |
| noResultsFoundText | string | no | The text that should appear when no results are returned. |
| disabled | boolean | no | Specifies if the control is disabled or not. |
| filter | string | no | condition to filter list Item, same as $filter ODATA parameter |
| orderBy | string | no | condition to order by list Item, same as $orderby ODATA parameter |
| placeholder | string | no | Short text hint to display in empty picker |
| substringSearch | boolean | no | Specifies if substring search should be used |
| label | string | no | Specifies the text describing the ListItemPicker. |
| enableDefaultSuggestions | boolean | no | Enable default suggestions. All options are displayed by default when clicking on the control. |
| itemsQueryCountLimit | number | no | Number of items to display in a lookup field |

![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/ListItemPicker)
3 changes: 3 additions & 0 deletions src/controls/dynamicForm/dynamicField/DynamicField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export class DynamicField extends React.Component<IDynamicFieldProps, IDynamicFi
description,
maximumValue,
minimumValue,
itemsQueryCountLimit,
customIcon,
orderBy
} = this.props;
Expand Down Expand Up @@ -245,6 +246,7 @@ export class DynamicField extends React.Component<IDynamicFieldProps, IDynamicFi
itemLimit={1}
onSelectedItem={(newValue) => { this.onChange(newValue, true); }}
context={context}
itemsQueryCountLimit={itemsQueryCountLimit}
orderBy={orderBy}
/>
{descriptionEl}
Expand All @@ -270,6 +272,7 @@ export class DynamicField extends React.Component<IDynamicFieldProps, IDynamicFi
itemLimit={100}
onSelectedItem={(newValue) => { this.onChange(newValue, true); }}
context={context}
itemsQueryCountLimit={itemsQueryCountLimit}
/>
{descriptionEl}
{errorTextEl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export interface IDynamicFieldProps {
maximumValue?: number;
minimumValue?: number;
showAsPercentage?: boolean;
itemsQueryCountLimit?: number;
customIcon?: string;
orderBy?: string;
}
2 changes: 1 addition & 1 deletion src/controls/listItemPicker/IListItemPickerProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ export interface IListItemPickerProps {
*/
enableDefaultSuggestions?: boolean;
styles? : IBasePickerStyles;

itemsQueryCountLimit?: number;
}
4 changes: 2 additions & 2 deletions src/controls/listItemPicker/ListItemPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,15 @@ export class ListItemPicker extends React.Component<IListItemPickerProps, IListI
* Function to load List Items
*/
private loadListItems = async (filterText: string): Promise<{ key: string; name: string }[]> => {
const { columnInternalName, keyColumnInternalName, webUrl, filter, orderBy, substringSearch } = this.props;
const { columnInternalName, keyColumnInternalName, webUrl, filter, orderBy, substringSearch, itemsQueryCountLimit } = this.props;
const {
field, safeListId
} = this.state;
const arrayItems: { key: string; name: string }[] = [];
const keyColumn: string = keyColumnInternalName || 'Id';

try {
const listItems = await this._spservice.getListItems(filterText, safeListId, columnInternalName, field, keyColumn, webUrl, filter, substringSearch, orderBy ? orderBy : ''); // JJ - 20200613 - find by substring as an option
const listItems = await this._spservice.getListItems(filterText, safeListId, columnInternalName, field, keyColumn, webUrl, filter, substringSearch, orderBy ? orderBy : '', itemsQueryCountLimit); // JJ - 20200613 - find by substring as an option
// Check if the list had items
if (listItems.length > 0) {
for (const item of listItems) {
Expand Down
21 changes: 16 additions & 5 deletions src/services/SPService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ export default class SPService implements ISPService {
filterString?: string,
substringSearch: boolean = false,
orderBy?: string,
top?: number,
cacheInterval: number = 1): Promise<any[]> { // eslint-disable-line @typescript-eslint/no-explicit-any
const webAbsoluteUrl = !webUrl ? this._webAbsoluteUrl : webUrl;
let apiUrl = '';
Expand Down Expand Up @@ -248,7 +249,7 @@ export default class SPService implements ISPService {
const filterStr = substringSearch ? // JJ - 20200613 - find by substring as an option
`${filterText ? `substringof('${encodeURIComponent(filterText.replace("'", "''"))}',${internalColumnName})` : ''}${filterString ? (filterText ? ' and ' : '') + filterString : ''}`
: `${filterText ? `startswith(${internalColumnName},'${encodeURIComponent(filterText.replace("'", "''"))}')` : ''}${filterString ? (filterText ? ' and ' : '') + filterString : ''}`; //string = filterList ? `and ${filterList}` : '';
apiUrl = `${webAbsoluteUrl}/_api/web/lists('${listId}')/items?$select=${keyInternalColumnName || 'Id'},${internalColumnName}&$filter=${filterStr}&$orderby=${orderBy}`;
apiUrl = `${webAbsoluteUrl}/_api/web/lists('${listId}')/items?$select=${keyInternalColumnName || 'Id'},${internalColumnName}&$filter=${filterStr}&$orderby=${orderBy}${top ? `&$top=${top}` : ''}`;
}
else { // we need to get FieldValuesAsText and cache them
const mapKey = `${webAbsoluteUrl}##${listId}##${internalColumnName}##${keyInternalColumnName || 'Id'}`;
Expand All @@ -259,7 +260,7 @@ export default class SPService implements ISPService {
return filteredItems;
}

apiUrl = `${webAbsoluteUrl}/_api/web/lists('${listId}')/items?$select=${keyInternalColumnName || 'Id'},${internalColumnName},FieldValuesAsText/${internalColumnName}&$expand=FieldValuesAsText&$orderby=${orderBy}${filterString ? '&$filter=' + filterString : ''}`;
apiUrl = `${webAbsoluteUrl}/_api/web/lists('${listId}')/items?$select=${keyInternalColumnName || 'Id'},${internalColumnName},FieldValuesAsText/${internalColumnName}&$expand=FieldValuesAsText&$orderby=${orderBy}${filterString ? '&$filter=' + filterString : ''}${top ? `&$top=${top}` : ''}`;
isPost = false;

//eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -559,14 +560,24 @@ export default class SPService implements ISPService {
const isArray = Array.isArray(result[fieldName]);
//multiselect lookups are arrays
if (isArray) {
result[fieldName].forEach(element => {
lookups.push({ key: element.ID, name: element[lookupFieldName || 'Title'] });
result[fieldName].forEach(element => {
let value = element[lookupFieldName || 'Title'];
const dateVal = Date.parse(value);
if (!Number.isNaN(dateVal)) {
value = new Date(value).toLocaleDateString();
}
lookups.push({ key: element.ID, name: value });
});
}
//single select lookups are objects
else {
const singleItem = result[fieldName];
lookups.push({ key: singleItem.ID, name: singleItem[lookupFieldName || 'Title'] });
let value = singleItem[lookupFieldName || 'Title'];
const dateVal = Date.parse(value);
if (!Number.isNaN(dateVal)) {
value = new Date(value).toLocaleDateString();
}
lookups.push({ key: singleItem.ID, name: value });
}
return lookups;
}
Expand Down