I guess to define a field as mandatory should be a very common requirement in the world of CRM Web UI. In short, there are two options:

Via configuration, define the field properties, and turn on or off the Mandatory flag

Via coding, add logic into the P getter of the interested field

Let’s try a bit advanced requirement: to enable a dynamic mandatory field, the mandatory or not will depend on the value of another field in the same view. Let’s have a fake requirement, when create an Individual Account, if “Academic Title” has value 0002 (which is Professor in my testing system), we would like to have “First Name” field as mandatory. “First Name” field was not mandatory on the initial creation screen.

If we consider the 2 options above, if we would like to use option 1, which is via configuration, we might have to make changes to the configuration xml in the runtime. In theory, this is possible, but compared to the simple fake requirement we are having, it is not worthy to use such complex solution. Alternatively, we’d like to use option 2, that is via coding in P Getter. We only make different coding in step 5 for the above option 2, as following:

I thought it’s done. But when test the result, it turns out to be with the following confused behavior:

Feeling so sad? Let’s try to analyze how such confusion is caused.

After press “Enter” (a roundtrip), for an empty mandatory field, there will be 3 system behaviors

Compared to the previous video, we can see the above 3 system behaviors are inconsistent. After select value 0002 for field “Academic Title”, press Enter. The system behavior 1 and 2a will appear and disappear, which is what we want. But for system behavior 2b and 3, I have to press Enter for the second time to have it correctly shown. The system behavior 3, which is the key logic to forbidden saving when a mandatory field was empty. Given the inconsistent system behavior, the mandatory control cannot be realized correctly. This is Not what we wanted.

KBA 2013392 has described the same issue. And it explains that within the current CRM Web UI frame, only add logic in P getter can’t avoid the above inconsistent system behavior. KBA 2013392 has to comment such behavior as standard limitation. Then are we no way out? No. Let’s start from the comment in KBA 2013392 and analyze the mechanism of mandatory control and see how we can bypass this standard limitation. Here is the comment from KBA 2013392

The “Issue Error” corresponds to the system behavior 3. And “Set Error status” system behavior 2. The following screen shot shows how the “Set Error status” was translated into html presentation. In CL_THTMLB_INPUTFIELD, it takes over the error status passed from method DO_FINISH_INPUT, th-onerror class was added into html. And in CSS definition, the background-color and border-color explains the system behavior 2a and 2b.

When analyzing the Error status, I happen to find the coding which deals with required field status. The following screen shot shows, in CL_THTMLB_INPUTFIELD, system checks the “required” attribute, and set th-ip-sp-md class id into html. This leads to the system behavior of 2a. Regarding the red star, it is processed in CL_THTMLB_LABEL. The “*” was added into the label and CSS forced it to be red.

Then where is this “required” attribute coming from? It is from the two options mentioned at the beginning of this blog. The coding detail as following

Visualize the flow of one roundtrip as following. The error message will be based on last roundtrip’s mandatory fields of the bsp application. Only after it, the P getter will be called. This leads to the inconsistent system behavior.

After analyzing, I feel the mechanism is clear to me. But the initial issue was not solved yet. 😛

I’ve discussed with our Web UI developer. Our developer has included this issue within the to do list. But it might take some time to be solved. Before we get a standard solution, let’s try to see if there is any chance to bypass the standard limitation.

There is a blog in 2013, talking about the same Dynamic Mandatory Field requirement. The author proposed a solution in customer bsp component. This blog will try in the scope of an enhanced bsp component.

Let’s review the visualized flow. Here CL_BSP_WD_VIEW_CONTROLLER method POST_MANDATORY_FIELD added one new mandatory field to the bsp application. This is a public method. If the current flow is to increase one mandatory field, we can call this method before GET_EMPTY_MANDATORY_FIELDS in DO_FINISH_INPUT. But how to decrease mandatory fields? Observe class CL_BSP_WD_VIEW_CONTROLLER attribute MANDATORY_FIELDS, it is a Private attribute. And no public method provided to delete one entry of the mandatory fields. Thus it seems to be a dead end.

Then how about redefine DO_FINISH_INPUT method completely? Or redefine method GET_EMPTY_MANDATORY_FIELDS?

With help from my colleague, we managed to come up with the following coding by redefine method GET_EMPTY_MANDATORY_FIELDS. And the initial issue was solved perfectly.

In the following coding, it is better to create a separate interface or method to capsulate the logic regarding judging the dynamic condition, should or should not undergo extra logic. This can lead to easy reading and extension for future. Here the coding to check a field is empty or not is copied from CL_BSP_WD_VIEW_CONTROLLER method GET_EMPTY_MANDATORY_FIELDS.

I’d like to mention that, this issue is already in our developer’s to do list. We should expect a standard solution to this issue in future. Just before the solution is released, you may try the above solution. And I didn’t test in more bsp components. Thus if there is anything I missed, welcome to add to this blog. Thank you!

Update on 2018 Jun 22nd

After more discussion at development team, if you like this function and need it in our standard, please raise suggestion in the upcoming Customer Connection project https://influence.sap.com/CRM2019 (from Oct 23 till Dec 3, 2018) and post an improvement suggestion there. Depending on the votes from other customers, development department will review the requests and decide if it can be implemented. Let’s vote it and make it true.