Since I started to distribute my application, I got to know that more is not always better when it comes to functionality. Just yesterday my buddy Kim called and asked me if there is any way for him to get rid of the loyalty cards functionality I added recently. He has no plans of using it and doesn’t want it cluttering the interface. Sure thing, buddy, was my answer. So, I created a new constant, added this pretty simple piece of code to the OnOpen event handler, along with this even simpler &AtServer function, and here we go.
I have my new constant switched off, so when I open a Sales document, there is no Loyalty Card field anymore. Except there is still Loyalty cards turnovers link over here, Loyalty cards catalog link over here, and god knows how many more loyalty-cards-related commands all over the place.
What is worse is that at some point I might want to add other places like this. And how I’m supposed to remember by then that their visibility depends on this constant over here? Wouldn’t it be so much more convenient if there was some Platform feature that keeps in mind that these metadata objects visibility depend on this constant? This is exactly what functional options do. They control the visibility of the commands relating to selected metadata objects depending on the value of a constant.
So, let’s add a new Functional option called UseLoyaltyCards and see what’s where. The first thing we need to do is to tell the functional option which value it depends on. So I’m selecting our constant right here. Now I need to tell the functional option what metadata objects it controls. So, I’m going to the Content page and selecting the LoyaltyCards catalog, the LoyaltyCardsTurnovers register and this LoyaltyCard attribute of the Sales document. OK, let’s see what we’ve got.
So, here is my LoyaltyCards constant and now it’s turned off. Therefore, there are no signs of LoayltyCards anywhere in the interface including the Sales document form. Now, I’m turning it on andтАжHmmm. Still nothing. OK. How about I close the document form and then reopen it? OK, now we’re talking. Here is my Loyalty card field in the form. But still no signs of the loyalty-cards-related commands in the global interface. OK, let me guess. They will be here as soon as I reload the Main Window. And here they are indeed.
OK, I feel like this phenomenon deserves an explanation, so here is the deal. Every form, including the Main Window, gets created on the server side and then goes to the client where a user starts working with it. Every now and then a user clicks something that triggers a new form to be created, which also occurs on the server side. Then this new form makes it to the client and the work goes on.
The functional option is, basically, a police officer checking every form before letting it pass from the server to the client side. Taking over a watch he gets a list of Metadata Objects he needs to keep an eye on. So, when a form arrives at the checkpoint, the officer checks it against his list before letting it in. If he sees anyone from his checklist, he requests his boss (the constant he depends on) whether he can let them in or not. If he doesn’t get the permission (because the constant in turned off), he drops these unwanted objects off and lets the rest of the form go. The point here is that when the form is open, the checkpoint is already passed. After that, no constant changes can affect the attributes visibility. So the form needs to be reopened in order for the changes to take effect. But there is a better solution. Let me show you.
First, I need my constants on the explicit form. So, I’m going to the common forms and adding a constant form like this. Now I’m going to the form’s events and here is the AfterWrite event that occurs on the client side right after the constant’s values are saved to the database. Now let’s check the Syntax Assistant. Here are the Functional options methods of the Global Context and here is what we need - the RefreshInterface procedure. What it does is reload all opened forms from the server so that the functional options can filter out the unwanted objects. So, I’m calling it here, adding the constants form to the Other subsystemand here we go. The constant is now on, so here are the links to the loyalty-cards-related commands in the Global interface, and here is the Loyalty card field in the Sales document form. As soon as I turn the constant off, all of them are gone. And now they are back again. And now they are gone. Sorry, I can do this all day.
OK. One more thing we need to fix before we go. I’m talking this piece of code posting the Sales document data to the LoyaltyCardsTurnovers register. There is no way for the Platform to just disable a piece of source code, so this part still needs to be done manually. Let’s check if we can read the functional option value from the code. And we sure can. What this function does is just return the value of the constant the functional option depends on. So let’s do it. And this is it.