-
Notifications
You must be signed in to change notification settings - Fork 409
Description
Category
[ ] Enhancement
[x ] Bug
[ ] Question
Version
3.22 (latest at time of this posting)
Expected / Desired Behavior
After saving a form, I expect to be have the values persisted when editing the form afterwards. I want to switch through the fields with the Tab key and NOT lose the value of those fields when pressing the Tab key.
Observed Behavior
When using the Edit form (PageType=6) and Tab-ing through the fields, the field values are being cleared (I do not press any other key or move the mouse). Using the Tab key to navigate through a form is a common task and should not lead to deleting values from the form.
Steps to Reproduce
- Create a custom list ( I used the fields Title, abcTotalAmount as number with 0 trailing digits and mandatory field, abcTaxAmount as number with 0 trailing digits and abcComments as multiple lines of text)
- Create a spfx project (I used version 1.21) - form application extension.
- In the component use the following code:
import { DynamicForm } from "@pnp/spfx-controls-react/lib/DynamicForm";
export interface IMyFormsProps {
context: any;
displayMode: FormDisplayMode;
targetListId: string;
targetItemId: number;
onSave: () => void;
onClose: () => void;
}
//...component boilerplate omitted for brevity
public render(): React.ReactElement<{}> {
return( <DynamicForm
context={this.props.context}
listId={this.props.targetListId}
listItemId={ this.props.targetItemId != null ? this.props.targetItemId : 0 }
contentTypeId={"0x01006CAD569..."} //this is the list item content type for the custom list above
onCancelled={() => { console.log('Cancelled') }}
onBeforeSubmit={async (listItem) => { return false; }}
onSubmitError={(listItem, error) => { alert(error.message); }}
onSubmitted={async (listItemData) => { console.log(listItemData); this.props.onSave(); }}
>
</DynamicForm>);
Also in MyFormCustomizer.ts:
React.createElement(MyForms, {
context: this.context,
displayMode: this.displayMode,
targetItemId: this.context.itemId,
targetListId: this.context.list.guid.toString(),
targetContentTypeId: targetContentTypeId,
onSave: this._onSave,
onClose: this._onClose
} as MyFormsProps)
- Activate the extension for the custom list
- Create a new item using the New Form
- Edit the newly created item
- Position the cursor in the Title field then attempt to press Tab to get to the end of the form. You will notice that values are being deleted
My Analysis of probable cause
After starting the test Webpart and debugging a bit I discovered that all changes (including key presses) are being channeled to the onChange method in DynamicForm.tsx
I included the runtime values as comments below:
/**
* Triggered when the user makes any field value change in the form
*/
private onChange = async (
internalName: string, //internalName = "Title"
// eslint-disable-next-line @typescript-eslint/no-explicit-any
newValue: any, //newValue = ""
validate: boolean, //validate = true
additionalData?: FieldChangeAdditionalData,
): Promise<void> => {
So it is no surprise that pressing Tab triggers onChange -> onChange does not differentiate events so it just assumes it should replace the newValue with "". As I understand it, newValue should not be the empty string when we are simply tabbing.
Two possible solutions:
- Refine onchange so that we can see if a key was pressed and which one
- Add a separate onKeyUp event (not onKeyDown, had bad experiences with that) to handle this case, but find a way to adjust onChange so that it is skipped in this case