Dynamics Ninja Logo

Blog.

Is your PCF control read-only?

Cover Image for Is your PCF control read-only?
·
3 min read

Issue

I've noticed that most of the PCF controls out there that are available as open-source projects have the same problem. They don't handle states of the field.

The most basic one is the disabled state when the data is read-only. Maybe you thought that framework will handle that by default, but the answer is sadly a big NO. The good news is that you can fix that in no time.

Get the right info

The answer is quite simple and it can be found in the context object of type ComponentFramework.Context.

There is a property called mode that holds two important pieces of information. Those 2 are isControlDisabled & isVisible that hold information if the control is read-only and if the control should be visible on the form.

You can easily get those to values typing following commands.

var disabled = context.mode.isControlDisabled
var visible = context.mode.isVisible

Those properties obviously give us a boolean value that is self-explanatory.

Now we know how to get those values, but the question that pops up after that is where should I use it.

Choose the right tool

You can get the context inside two main methods that are part of every control out there: init & updateView. Both context objects will give you the data you need, but you must understand the behavior of each to be sure that that's the right place you want to use it.

The first one that comes to mind is init method that is called only once when the control is loading. This choice will cover most of the use cases out there for the fields regarding the disabled state because most of the time field is read-only or editable from the moment you opened the form till the moment you close it. Is it the best way to handle it?

The answer is again NO. The second choice would be a updateView method that is always called after the init method finishes with the initialization of the control which will result in the same output as calling it in the init method. The most important thing to know here is that updateView method will be called every time something in the context is changed. That way we can handle the events like business rules for example that will make the fields read-only as a result of some other actions on the form.

Solution

Now when we are familiar with all the concepts we can make it work as a complete solution. The first thing to we need to do is make out the HTML element assessable inside the scope of the control.

The next step is to add the component to the control container and expose it to the variable outside the init method.

Finally, we need to set the element state in the updateView method.

You can reproduce the steps with the code shown below.

export class DisabledDemo implements ComponentFramework.StandardControl<IInputs, IOutputs> {
  private _textbox: HTMLInputElement;

  public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement)
  {
    let textbox = document.createElement("input");
    this._textbox = textbox;
    container.appendChild(textbox);
  }

  public updateView(context: ComponentFramework.Context<IInputs>): void
  {
    this._textbox.disabled = context.mode.isControlDisabled;
  }
}

Conclusion

It's time to revisit all the controls you've created and implement the logic for handling the disabled state. Make your control a complete solution just by a few lines of code. You can also try to manage the visibility state just the same way we did it with the read-only state.

Since most of the updateView methods are empty these days it's a perfect time to give them some love with just a few lines of code.