A view called Constraints has been created for this lesson’s demonstration. It uses the ‘Customer’ table to list data. There is a combo and a couple of forms at the top that can be used to filter the data, and an ‘Update’ button that updates the filter.
As an example, the list is filtered by “Number,” and is to be restrained to show customers 5 – 10. At first glance, all looks fine.
When the ‘Number’ header is selected to change the sorting resulting in all of the data being reloaded without the filtered constraints. This shows that the constraint is not rebuilt properly for each request. The constraint needs to be built properly, and not just handled in the request of the ‘Update’ button.
Looking at the source code in the Studio, the OnClick for the button calls a function called UpdateFilter. It WebGet’s the values of the combo and forms out of the view, and then builds a constraint based on this information. Then the list is refilled and triggered to refresh. This method causes a global constraint, but it should not. It should be specific for the Data Dictionary. It should be built inside the OnCall procedure, which is called when the Framework synchronizes itself because a rebuild constraint is done with each synchronization performed with each request.
A different UpdateFilter procedure is put in place that will call Rebuild_Constraints and trigger the list to refill.
A different OnConstrain is also applied, so that inside the Data Dictionary the OnConstraint procedure is going to WebGet values from the combo and forms and build the constraint. This code will be executed for each request.
Recompiling the app, reloading the page, resetting the parameters in the form and combo, updating and then sorting by ‘Number’ now works with the constraints still in place.
Even though it is now session-safe and process pooling it is not functioning properly. Since the values for the constraints are read directly from the user interface, the constraint can be changed on the client before the synchronization process happens. This causes issues with the synchronization process because it will not be able to re-find the record. Errors are not presented when this happens because synchronization errors are not shown by default. Enabling Set pbShowAllRefindErrors to True will cause resynchronization errors to show.
A new OnConstraint is applied to show a better methodology. Server web properties, psFilter, psFilterFrom and psFilterTo, are defined in the code. These properties stay on the server and do not go to the client, which is better for security.
The values in the OnConstraint are retrieved directly from the user. The UpdateFilter has to be changed to update the properties that were created. The UpdateFilter will now read the values from the user interface, put them in the web properties that were created, rebuild the constraints, and then refill the list. This means that if the values are changed in the user interface on the client, the changes will not be reflected in the constraint until the ‘Update’ button is clicked.
When using session specific constraints, they need to be initialized for each request. The Framework automatically sends Rebuild_Constraints during the synchronization process. Web properties can be used to determine what the data should be constrained on.
User Interface values should not be used directly because they may have changed on the client between requests, which may cause refind issues for the DDO synchronization process. Always use a web property in between that will store the current restraint value.
Data Dictionary SQL filters have the same rules as regular DataFlex constraints. Always create constraints in OnConstrain. The Framework makes sure Rebuild-Constraints is called. Use web properties to store the data. Do not use user interface values directly.
For global SQL filters, developers need to reset for each request manually, which are typically set in OnSessionPropertiesSet.