Skip to content

Tab key in DynamicForm deletes field values #2061

@CodingSinceThe80s

Description

@CodingSinceThe80s

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

  1. 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)
  2. Create a spfx project (I used version 1.21) - form application extension.
  3. 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)
  1. Activate the extension for the custom list
  2. Create a new item using the New Form
  3. Edit the newly created item
  4. 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:

  1. Refine onchange so that we can see if a key was pressed and which one
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions