🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Bootcamp:Chapter 6
This page was created by Hans.karlsen on 2022-10-08. Last edited by Wikiadmin on 2026-07-29.

You will build a modal car picker in MDriven Designer that returns one or more selected cars to a Person, then replace the direct many-to-many display with a HistoricOwnership association class.

This chapter continues from Chapter 5. You work with the Person, Car, and CarsIUsedToOwn association created in Chapter 1. Save the model after each completed change and test it in the web application.

What you will build

By the end of this chapter, a user can:

  • Open a modal dialog from the Person ViewModel.
  • Search for a Car in a CarSeeker ViewModel.
  • Select a car and return that selection to the calling Person view.
  • Add one or several selected cars to CarsIUsedToOwn.
  • Model historical ownership as a link object (an association class) named HistoricOwnership, including a DateSold value.

Remove the obsolete CarsIUsedToOwn action

When the AutoForms were regenerated, the earlier Person action retained a connection to an older auto form. It no longer has the intended form connection.

  1. Open the Person ViewModel.
  2. Remove the button or ViewModel column named CarsIUsedToOwn.
  3. Remove the ViewModel action MultiLinkCarsIUsedToOwn.
  4. Save the model.

Create a button that opens a car picker

A ViewModelColumn marked Is Action renders as a button. Connect that button to a ViewModelAction to define what happens when the user presses it.

  1. In the Person ViewModel, add a ViewModelColumn.
  2. Set Is Action on the column. Verify that the column becomes a button.
  3. Name the button AddACarIUsedToOwn.
  4. Create a ViewModelAction named AddACarIUsedToOwnAction.
  5. On the AddACarIUsedToOwn button, use the picker beside Is Action to select AddACarIUsedToOwnAction.
  6. Save the model.

Adopt the CarSeeker AutoForm

The action needs a ViewModel to display. Use the generated car seeker as the starting point, then adopt it so that you can maintain your own version.

  1. In the ViewModelEditor, select NewEditor at the top.
  2. In the new editor window, find AutoFormCarSeeker.
  3. Adopt the AutoForm and name the adopted ViewModel CarSeeker.
  4. Return to AddACarIUsedToOwnAction.
  5. Set BringUpViewModel to CarSeeker.
  6. Save and test the web application.

At this point, the CarSeeker opens, but it does not yet open over the Person form.

Open the picker as a modal dialog

A modal dialog keeps the caller visible behind the dialog and requires the user to complete or cancel the dialog before continuing.

  1. Open AddACarIUsedToOwnAction.
  2. Select Is Modal.
  3. Save and test the web application.

Control when the modal OK button is enabled

A modal dialog has an OK button. Its EnableExpressionForModelOk must evaluate to true before the user can press OK.

Verify the initial behavior

  1. On AddACarIUsedToOwnAction, set the modal OK enable expression to the OCL constant true.
  2. Save and test the dialog.

This confirms that the dialog can return to its caller. The setting is not suitable for the finished picker because it allows OK without a selected car.

Require a selected search result

Use OCL to enable OK only when the seeker has a current result.

  1. Open the OCL editor for EnableExpressionForModelOk by selecting the three-dot button.
  2. In the expression helper tree, find vSeekerResult->notempty.
  3. Set the expression to:
vSeekerResult->notempty
  1. Save and test the web application.

The OK button is now available only when the current search result is nonempty. Test both cases:

  1. Search for cars and select a row. Verify that OK is enabled.
  2. Search for text that returns no cars, for example AAAAAAA. Verify that OK is not enabled.

Return the selected car to the Person

ActionAfterModalOk is an OCL action expression on the calling ViewModel action. MDriven evaluates it only when the user presses OK; it does not run when the user cancels or closes the modal dialog.

  1. Open the OCL editor for ActionAfterModalOk on AddACarIUsedToOwnAction.
  2. Enter this expression:
vCurrent_Person.CarsIUsedToOwn.Add(vModalResult_vCurrent_Car)
  1. Save and test the web application.
Expression part Meaning in this view
vCurrent_Person The root object of the current Person view: a Person object.
vCurrent_Person.CarsIUsedToOwn The current person's CarsIUsedToOwn association end.
.Add(...) Adds an object reference to that association.
vModalResult_vCurrent_Car The current Car selected in the modal CarSeeker.

For example, if the Person is Pat and the selected Car is OldCar1, pressing OK adds OldCar1 to Pat's CarsIUsedToOwn list.

Test save, undo, and redo

Test the operation in the web application:

  1. Add a car through the modal picker.
  2. Save the operation.
  3. Make another change without saving.
  4. Use undo and redo to verify that unsaved changes can be reversed and reapplied.

Allow an empty PersonSeeker search

The PersonSeeker currently returns no result for a blank search value. Add a search expression that applies only when the search parameter is empty.

  1. Open the PersonSeeker ViewModel.
  2. Add another Search Expression.
  3. Set its Criteria to:
Person.allinstances
  1. Set its Active expression to:
vSeekParam->isnullorempty
  1. Save and test the web application.

When the search input is blank, this expression is active and returns all Person instances. When the input has a value, the other applicable search expression handles the search.

Change previous ownership to many-to-many

Open a second browser window and navigate to PersonSeeker. In one window, open one Person and assign a car that they used to own. In the other window, open SomeOtherDude and try to assign the same car.

The original model defines PreviousOwner with cardinality 0..1, so a Car can have only one previous owner. Historical ownership requires multiple people to be able to reference the same car.

  1. In the class diagram, select the PreviousOwner association end.
  2. Change its cardinality from 0..1 to 0..*.
  3. Save the model.

The model can show errors after this cardinality change because generated AutoForms reflect the previous relationship shape.

  1. Refresh AutoForms.
  2. Save the model again.
  3. Repeat the two-browser test. Verify that both people can now reference the same car as a previously owned car.

Return multiple selected cars

The current modal action returns one current Car through vModalResult_vCurrent_Car. To add every selected Car, use the modal selection collection instead.

  1. Open AddACarIUsedToOwnAction.
  2. Replace the ActionAfterModalOk expression with:
vModalResult_vSelected_Car->collect(pc| vCurrent_Person.CarsIUsedToOwn.Add(pc))
  1. Save and test by selecting multiple cars in the CarSeeker before pressing OK.

In this expression, vModalResult_vSelected_Car is the selected Car collection. The collect operation evaluates the add action for each selected car, represented by pc.

Add HistoricOwnership as an association class

A many-to-many association tells you that a Person and Car are related. An association class adds an object for each exact Person–Car relationship, so that you can store data about that relationship. In this exercise, HistoricOwnership stores when the car was sold.

  1. In the class diagram, create a new class named HistoricOwnership.
  2. Select the association-class-connection-tool.
  3. Select HistoricOwnership, drag it to the many-to-many association between Person and Car, and release when the dotted connection appears.
  4. Add an attribute to HistoricOwnership:
Attribute Type Purpose
DateSold DateTime? Stores the date for this specific historic ownership relationship. The question mark makes the value nullable.
  1. Set the inner link name for navigation to Car to Car.
  2. Set the inner link name for navigation to Person to Person.
  3. Save the model.

Show the HistoricOwnership link objects in the Person ViewModel

When you use an association class, show the link objects rather than only the associated end objects. The link object identifies the exact Person–Car pair and can display relationship-specific values such as DateSold.

  1. Open the Person ViewModel.
  2. Add a nested ViewModelClass as a multilink.
  3. Select HistoricOwnership.
  4. Save and test the web application.
  5. Verify that the CarsIUsedToOwn list and the HistoricOwnership list are maintained automatically.
  6. Remove the older CarsIUsedToOwn grid. The HistoricOwnership grid represents the same relationship and also exposes the additional relationship data.
  7. On the HistoricOwnership nesting, set Act As For Actions to:
self.Car
  1. Save and test the web application.

Act As For Actions makes actions in the HistoricOwnership context act as the linked Car, using self.Car.

Checkpoint

Your Person view should now provide an AddACarIUsedToOwn button that opens CarSeeker as a modal dialog. The user can search, select one or more cars, and press OK only when the modal has a valid result. HistoricOwnership should display the Person–Car relationship together with DateSold.

Next chapter

Continue with Chapter 7, where you continue working with HistoricOwnership data and the Person ViewModel.

See also