Skip to main content
Version: 5.x

How-to: Binding properties

Example 1

Task

The concepts of Country, Region and City are defined. A region and a city are always located in a certain country. A city may have a specified region, but need not.

CLASS Country 'Country';
name 'Name' = DATA ISTRING[100] (Country) IN id;

CLASS Region 'Region';
name 'Name' = DATA ISTRING[100] (Region) IN id;

country 'Country' = DATA Country (Region) NONULL DELETE;
nameCountry 'Country' (Region r)= name(country(r)) IN id;

CLASS City 'City';
name 'Name' = DATA ISTRING[100] (City);

country 'Country' = DATA Country (City) NONULL DELETE;
nameCountry (City c) = name(country(c));

region 'Region' = DATA Region (City);
nameRegion (City c) = name(region(c));

FORM cities 'Cities'
OBJECTS c = City
PROPERTIES(c) name, nameCountry, nameRegion, NEW, DELETE
;

NAVIGATOR {
NEW cities;
}

We need to define the logic such that a city can only be linked to a region belonging to the country it is in.

Solution

CONSTRAINT country(City c) != country(region(c)) CHECKED BY region[City] MESSAGE 'The country of the city region must match the country of the city';

The CONSTRAINT statement defines a condition that must always be NULL. In this case, the constraint based on this condition will be violated if there is a country defined for the region, a region for the city, and a country for the region, and the region's country is not the same as the city's country. The CHECKED BY block indicates that when you select a region in a dialog, the regions will be filtered by default so as not to violate this constraint. It should be noted that if no country has yet been set for the given city then the condition will always be NULL, and all existing regions will be shown in the dialog.

Example 2

Task

Similar to Example 1.

We need to make it so that the country is automatically filled when a region is chosen.

Solution

WHEN LOCAL CHANGED(region(City c)) AND NOT CHANGED(country(c)) DO {
country(c) <- country(region(c));
}

It should be noted that after the user has chosen a region and a country is set, when the dialog is called again, only the regions of the selected country will be displayed. If the user wants to see all the regions again, he will need to clear the country first. The expression checks that the country has not changed is added to provide the following behavior: if the cities are changed by external actions that change both the country and the region, then the country should not be changed with this event.

Example 3

Task

Similar to Example 1.

We need to create the same kind of association between the region and the city, but in such a way that a region cannot be selected until a country has been set first.

Solution

CONSTRAINT region(City c) AND NOT country(c) = country(region(c)) CHECKED BY region[City] MESSAGE 'The country of the city region must match the country of the city';

The difference from the first example is that the new condition will also be true if a region is set and a country is not. Therefore, in this case the dialog will not display any regions.

Example 4

Task

Similar to Example 1.

If the user first selects a region, and then a country that does not correspond to the original region, the user will receive an error message when trying to save.

We need to make it so that the region is dropped when a new country is selected, if the region does not correspond to that country.

Solution

WHEN LOCAL CHANGED(country(City c)) AND country(c) != country(region(c)) DO {
region(c) <- NULL;
}

Example 5

Task

Similar to Example 1.

The solution to the first example has one drawback. The system will not allow you to change the country of a particular region, if the city links to it. The constraint will be violated.

We need to make it so that when a region's country is changed, it also changes automatically for all that region's cities.

Solution

// 1 option
WHEN SETCHANGED(country(region(City c))) DO
country(c) <- country(region(c));

// 2 option
WHEN SETCHANGED(country(Region r)) DO
country(City c) <- country(r) WHERE region(c) = r;