This chapter shows you how to build a Seeker that searches Person objects by name and age, while using the MDriven Designer debugger to distinguish OCL, EAL (MDriven Action Language), and OCL-PS expressions.
Continue from Chapter 3, where you created the Person Document ViewModel. If you are starting the Bootcamp, begin with Chapter 1.
Before you start
Read Getting to the bottom of the Line of Business Application for the MDriven view of what a line-of-business application needs.
This chapter uses the Person model and Person ViewModel created in earlier chapters. Save the model regularly with Ctrl+S and check for model or ViewModel errors after each change.
What you will build
A Seeker Form is a ViewModel used to find objects. Unlike the Person Document form from Chapter 3, a seeker presents a result set and lets the user search it.
You will extend AutoFormPersonSeeker so that:
- a text value such as
123is converted to the Integer value123; - non-numeric text such as
Oneproducesnullrather than an Integer value; - the main Search action stores the converted value in a ViewModel variable; and
- an OCL-PS search expression returns Person objects whose Age is greater than or equal to the entered number.
Open the Person Seeker
- In MDriven Designer, find
AutoFormPersonSeeker. - Open it in the ViewModel Editor.
- Review the existing columns and search configuration before changing it. Adapt the layout later, but keep the existing Filter and Search behavior while completing the exercises.
Use the debugger to evaluate OCL and EAL
The debugger lets you evaluate expressions and inspect variables before you put an expression in a ViewModel.
- Start the debugger.
- If the debugger does not start because it reports that Turnkey was started with a special button, select the XML radio button instead of Local TurnkeyPrototyper.
Test Integer.Parse in OCL
OCL reads data and calculates a result. It does not assign values or otherwise change data.
- In an OCL expression box, enter
Integer.Parse('1')and execute it. The result is1. - Enter
Integer.Parse('One')and execute it. The result is blank, which representsnull. - Enter
Integer.Parse('One').isnull. The result istrue. - Enter
Integer.Parse('10').isnull. The result isfalse. - Enter
Integer.Parse('123'). The result is123.
Null is not zero. null means that there is no value. In this example, there is no Integer result because 'One' cannot be parsed as an Integer.
Declare and inspect a debugger variable
An expression cannot use an undeclared variable.
- Enter
Integer.Parse(vANewVariable). The debugger reports an error becausevANewVariablehas not been declared. - In the Your variables box, enter the following declaration and press Return:
vANewVariable:String='456'
- Execute
Integer.Parse(vANewVariable). The result is456. - Inspect the variable and its current value in the debugger's variable pane.
Assign values with EAL
EAL is the language used for expressions that change data or assign values. The EAL assignment operator is :=.
- Select Add Expression in the debugger to add another expression box. The yellow current marker identifies the selected expression.
- Set the new, lower expression box to Action.
- Enter and execute the following EAL expression:
vANewVariable:='200'
- Return to the OCL expression
Integer.Parse(vANewVariable)and execute it. Its result is now200.
Declare an Integer variable in Your variables:
vIntHolder:Integer=12
- Execute
vIntHolderin an OCL expression box. The result is12. - In the Action expression box, execute:
vIntHolder:=Integer.Parse(vANewVariable)
- Confirm in the variable pane that
vIntHoldernow has the value200.
Run multiple EAL expressions
Use a semicolon (;) to separate EAL expressions when you need an earlier expression to perform work and a later expression to provide the result.
- In the Action expression box, enter:
vIntHolder:=Integer.Parse(vANewVariable);vIntHolder+1
- Execute the expression and note the result.
- Change that expression box from Action to OCL and execute it again. OCL reports errors because
:=and;are EAL operators, not OCL operators.
Add a typed age value to PersonSeeker
The existing Filter column assigns the user's search text to vSeekParam. You will parse that text once and store the Integer result in a ViewModel variable named vSeekIntValue.
Create temporary test controls
These controls let you verify the conversion before connecting it to the real Search action.
- In PersonSeeker, right-click Columns, select Add a new Action Column, and place the new button where it does not cover an existing control.
- In the new button's Action expression, enter:
Integer.Parse(vSeekParam)
- Select the green
PersonSeekerViewModel root. - Open the Variables and Validations foldout in the left-side properties. In recent MDriven Designer versions, the left side updates to show properties for the selected ViewModel-tree level.
- Select Add Variable. Name the variable
vSeekIntValue, set its type to Integer, and leave its initial value empty. - Return to the new button and change its Action expression to:
vSeekIntValue:=Integer.Parse(vSeekParam)
- Save and check that neither the ViewModel nor the model has a red error indicator. Use the OCL editor when you need help validating expression syntax.
- Add another ViewModel column, choose a GenericViewModel column, and place it next to the new button.
- Set the new column's expression to
vSeekIntValue. - Save, open the Seeker in the web application, enter
123in Filter, and select the new button. The helper column shows123. - Enter non-numeric text, select the button, and confirm that the helper column is empty (
null).
Initialize the typed value when the user searches
Move the conversion into the existing main Search action. The existing search action prepares a wildcard text value and calls selfVM.Search.
- Open the existing Search action in the Action editor.
- Add the Integer conversion before the current expressions. Use semicolons to separate the actions:
vSeekIntValue:=Integer.Parse(vSeekParam);
vSeekParamWildcard:='%'+vSeekParam+'%';
selfVM.Search
- Save the model.
The first expression now produces either an Integer value, such as 123, or null. The remaining expressions continue to prepare the text wildcard and execute the search.
Search age in OCL-PS
The orange ViewModel classes in a Seeker are search expressions. They use OCL-PS, where PS means persistent storage. OCL-PS lets MDriven translate the search expression for the database storage in use, rather than first loading every Person object and filtering it in memory. This matters when the database contains many objects.
Add the age criterion
- In PersonSeeker, select the orange ViewModel class for the Seeker expression named
seekCrit. - Select
Crit1within it. - Change its expression from
Person.allinstancesto:
Person.allinstances->select(p|p.Age=vSeekIntValue)
- Save and test the web application. Enter an age in Filter and run Search to find Person objects with exactly that age.
- Remove the active expressions of
Crit1so that this new search expression can take effect. - Change the expression to search for people older than the entered age:
Person.allinstances->select(p|p.Age>vSeekIntValue)
- Save and test.
- Change the expression to include the entered age:
Person.allinstances->select(p|p.Age>=vSeekIntValue)
- Set the Active expression to:
vSeekIntValue.notnull
- Save and test with both a numeric Filter value and non-numeric text.
The Active expression prevents the age criterion from running unless the input was successfully converted to an Integer. For example, entering 130 enables the age criterion; entering Guy leaves vSeekIntValue null and does not activate it.
Clean up and test combined search behavior
- Remove the temporary GenericViewModel helper column and the temporary Action Column. They were used only to verify the conversion.
- Create a Person named
123with Age456and save it. - Create another Person named
Guy#5with Age130and save it. - Search for
123. Review the result, including the effect of the text Filter and the active age criterion. - Without changing the Filter, select Search again and compare the result.
Read Seeker view, especially the section about batches of search expressions. A Seeker can use multiple search expressions, and their active expressions determine which expressions participate in each search.
Key points
- Use OCL to read data and calculate results, such as
Integer.Parse(vSeekParam). - Use EAL when an expression must assign or otherwise change a value, such as
vSeekIntValue:=Integer.Parse(vSeekParam). - Use
;only in EAL to sequence expressions. - Use OCL-PS in Seeker search expressions to filter persistent data, such as
Person.allinstances->select(p|p.Age>=vSeekIntValue). - Guard a typed search criterion with an Active expression such as
vSeekIntValue.notnullso invalid input does not activate that criterion.
Next chapter
Continue with Bootcamp: Chapter 5.
