BaseDialog 'isBlocking' IDialogConfiguration Override is not Working.

Issue

Recently, we were developing an SPFx webpart in which we needed to open a dialog. For that, we decide to use Office Fabric UI Dialog control. For that, we used this link as a reference. The Microsoft blog explains the code well. We were able to open the dialog as expected. We needed one more functionality: if the user clicks outside the dialog, it should not be closed.

For that, we found we can set the “IsBlocking” flag to true. We applied the code as mentioned below.

export default class ColorPickerDialog extends BaseDialog {
  public message: string;
  public colorCode: IColor;

  public render(): void {
    ReactDOM.render(
      <ColorPickerDialogContent
        close={this.close}
        message={this.message}
        defaultColor={this.colorCode}
        submit={this._submit}
      />,
      this.domElement
    );
  }

  public getConfig(): IDialogConfiguration {
    return { isBlocking: false };
  }

  protected onAfterClose(): void {
    super.onAfterClose();

    // Clean up the element for the next dialog
    ReactDOM.unmountComponentAtNode(this.domElement);
  }

  private _submit = (color: IColor) => {
    this.colorCode = color;
    this.close();
  }
}

But still, that does not work.

Analysis

The blog was written in 2017. So, we thought there might be a change in the code with the updates in the SPFx version. We tried to find online if we could get any updated code for the same. But we are not able to find it anywhere. So, we decide to put a query in GitHub for a solution. We found an old issue there, which provided us with a resolution.

Resolution

The issue was reported in Dec 2017 and was given a resolution in Jan 2018. The code documented was missing the actual implementations for the “IsBlocking” flag. It needs to be passed when you call the dialog component as below.

const dialog: ColorPickerDialog = new ColorPickerDialog({ 
  isBlocking: true 
});

So, the full code for the button click will look something like the one below.

@override
public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
  switch (event.itemId) {
    case 'COMMAND_1':
      Dialog.alert(`${this.properties.sampleTextOne}`);
      
      // actual code provided in the code
      // const dialog: ColorPickerDialog = new ColorPickerDialog();

      // Code that needs to be updated.
      const dialog: ColorPickerDialog = new ColorPickerDialog({ isBlocking: true });
      dialog.message = 'Pick a color:';

      // Use 'FFFFFF' as the default color for first usage
      let defaultColor: IColor = {
        hex: 'FFFFFF',
        str: '',
        r: null,
        g: null,
        b: null,
        h: null,
        s: null,
        v: null
      };

      dialog.colorCode = this._colorCode || defaultColor;

      dialog.show().then(() => {
        this._colorCode = dialog.colorCode;
        Dialog.alert(`Picked color: ${dialog.colorCode.hex}`);
      });
      break;

    default:
      throw new Error('Unknown command');
  }
}

You can remove the getConfig() method from the ColorPickerDialog class as it is of no use.

It has been 6 years since the posting of the issue, and still, the blog is not updated. There isn’t any other resource that mentions this. So, I am writing this again to help anyone who is stuck in the issue.

References

  1. https://learn.microsoft.com/en-us/sharepoint/dev/spfx/extensions/guidance/using-custom-dialogs-with-spfx
  2. https://github.com/SharePoint/sp-dev-docs/issues/1121