The 1000 steps program to MDriven Chapter 7
No edit summary
No edit summary
Line 40: Line 40:
And here are the steps as text:
And here are the steps as text:


=== Chapter 7, First mention of Derived Attributes, Editable Grid cells in Web UI ===
=== Chapter 7: First Mention of Derived Attributes; Editable Grid Cells in Web UI ===
215 CarsIUsedToOwn is actually a poor name - if we change the name to CarsPersonUsedToOwn its a better fit as it does not raise questions about whom "I" refers to. Type the new name in the Association end - save (that will run the error check) - see the many errors
215. CarsIUsedToOwn is actually a poor name. If we change the name to CarsPersonUsedToOwn, it is a better fit as it does not raise questions about whom "I" refers to. Type the new name in the Association end. Save (that will run the error check) and see the many errors.


216 Change it back to CarsIUsedToOwn temporarily, save , no errors
216. Change it back to CarsIUsedToOwn temporarily and save. You will see no errors.


217 Instead of changing it we will use the Rename-function that will help to rename everywhere it is used. Right click the association end - choose rename, new name: CarsPersonUsedToOwn - Check "Set former name" - and whenever you use "Rename" you should check "Set former name" to help MDriven to help you once your changes also involves creation of change scripts to a database.
217. Instead of changing it, we will use the Rename function that will help to rename it everywhere it is used. Right-click the association end, choose rename, new name: CarsPersonUsedToOwn - Check "Set former name." Whenever you use "Rename," you should check "Set former name" to guide MDriven to help you once your changes also involve the creation of change scripts to a database. Save and verify that you are error-free.


Save - verify error free.
218. Create a note on the diagram by right-clicking "Add note." Double-click the note box and write this in the note: we will assume that a person always has 1 car at a time and that when they sell the first car, that person immediately gets a new car on the same day. Close the note. Resize it and place it somewhere nice.


218 Create a Note on the diagram by right clicking "Add note" - double click the note box - write this in the note: We will assume that a person always has 1 car at a time - and that person immediately gets a new car on the same day the person sells the first.
219. Add a new attribute, DatePurchased of type DateTime?, in class HistoricOwnership.


Close the Note - resize and place it somewhere nice
220. Select DatePurchased and in the property inspector, change the AttributeMode from Persistent(default - means saved in the database) to Derived (means calculated somehow).


219 Add a new attribute DatePurchased of type DateTime? in class HistoricOwnership
221. Stay in the property inspector and find DerivationOcl. Click on the OCL editor with the three dots.


220 Select DatePurchased and In the property inspector - change the AttributeMode from Persistent(default - means saved in the database) to Derived (means calculated somehow)
222. We want ''this'' DatePurchased to be derived from the prior cars DateSold.


221 Stay in the property inspector - find DerivationOcl - click up ocl editor with the three dots
We want to have an expression that from HistoricOwnership (self) goes up to the person (self.Person), and from there looks at all HistoricOwnership (self.Person.HistoricOwnership), makes sure that this list is in DateSold order (self.Person.HistoricOwnership->orderby(h|h.DateSold) ), and checks where in this list '''THIS''' HistoricOwnership (self) is (self.Person.HistoricOwnership->orderby(h|h.DateSold)->indexof0(self) ). Once we have that, grab the one after '''THIS''' HistoricOwnership : listinorder->at0(listinorder->indexof0(self)+1).


222
We find that we need the same list twice and it seems fair to get it once and use it in the expression twice. This is done in OCL with the "let x=someexpr in someotherexpr" operator.
 
we want THIS DatePurchased to be derived from the prior cars DateSold
 
we want to have an expression that from HistoricOwnership (self) goes up to the person (self.Person) and from there looks at all HistoricOwnership (self.Person.HistoricOwnership), makes sure that this list is in DateSold order (self.Person.HistoricOwnership->orderby(h|h.DateSold) ), and check where in this list THIS HistoricOwnership (self) is (self.Person.HistoricOwnership->orderby(h|h.DateSold)->indexof0(self) ) and once we have that grab the one after THIS HistoricOwnership : listinorder->at0(listinorder->indexof0(self)+1)
 
We find that we need the same list twice and its seems fair to get it once and then use it in the expression twice. This is done in ocl with the "let x=someexpr in someotherexpr" operator.


We can write:
We can write:
Line 77: Line 71:
)
)


This expression will return a HistoricOwnership object - but we want THIS DatePurchased to be derived from the prior cars DateSold - so we append .DateSold
This expression will return a HistoricOwnership object, but we want ''this'' DatePurchased to be derived from the prior cars' DateSold. We append.DateSold


let  listinorder=self.Person.HistoricOwnership->orderby(h|h.DateSold) in
let listinorder=self.Person.HistoricOwnership->orderby(h|h.DateSold) in


(
(
Line 87: Line 81:
).DateSold
).DateSold


223 Go to Person viewmodel - add the date purchased in the HistoricOwnershipGrid - save - test web
223. Go to Person ViewModel and add the date purchased in the HistoricOwnershipGrid. Save and test the web.


224 We notice that there is no good way for us to edit the DateSold - and thus the DatePurchased will get null all the time. Make the grid Editable by selecting the HistoricOwnership nesting head (blue)
224. We notice that there is no easy way for us to edit the DateSold; thus, the DatePurchased will get a null result all the time. Make the grid Editable by selecting the HistoricOwnership nesting head (blue).


225 Here we will add a tagged value - tagged values are extra meta information we can dress up our model with on most levels, like classes, attrtibutes and viewmodels. Press the Tagged values button in the ViewModelEditor.
225. Here we will add a tagged value (tagged values are extra meta information we can dress up our model with on most levels, like classes, attributes, and ViewModels). Press the Tagged values button in the ViewModelEditor.


226 In the shown window - press the Refresh from wiki button. Note how many predefined possible values (value store) are shown. You are not limitited to these tagged values - but the predefined has special meaning to Turnkey (the web front end engine, or to Wecpof the WPF engine)
226. In the shown window, press the Refresh from wiki button. Note how many predefined possible values (value store) are shown. You are not limited to these tagged values, but the predefined has a special meaning to the Turnkey (the web front-end engine, or to the WECPOF of the WPF engine).


227 Find Editable in the top selector Add that - set its value to True - close save
227. Find Editable in the top selector. Add that, set its value to True, close, and save.


228 In order to make a cell in a grid editable it must be in an editable grid - and we fixed that just now - but a column must also have an ReadOnly expression that does NOT result in true (but rather false or left empty) - clear the DateSold viewModelColumn in the grid ReadOnlyExpression
228. In order to make a cell in a grid editable. it must be in an editable grid - we fixed that just now - but a column must also have a ReadOnly expression that does ''not'' result in true (but rather false or left empty). Clear the DateSold viewModelColumn in the grid ReadOnlyExpression.


229 Save - test web - you have an editable datepicker in date sold
229. Save and test the web. You have an editable date-picker in date sold.


230 Enter some different dates in the rows - if you dont have rows - add some - notice the instant calculation of the DatePurchase as the DateSold comes available on the row after
230. Enter some different dates in the rows - if you don't have rows, add some. Notice the instant calculation of the DatePurchase as the DateSold comes available on the row below.


231 Click the DateSold column head in the grid  - to verify you get the correct values
231. Click the DateSold column head in the grid to verify that you get the correct values.


232 in the column DatePurchased we want to force iso date - and not trust browser setting to change expression to self.DatePurchased.ToString('yyyy-MM-dd'). Save test web
232. In the column DatePurchased, we want to force the iso date because we don't trust the browser setting. Change expression to self.DatePurchased.ToString('yyyy-MM-dd'). Save and test the web.


233 Discover the issue with use taking IndexOf0 +1 one - when the prior car is at -1 - fix derivation. Save test web
233 Discover the issue with use taking IndexOf0 +1 one - when the prior car is at -1 - fix derivation. Save test web

Revision as of 08:41, 19 January 2023

This is Chapter 7 of the training material. If you want to start from the top: The_1000_steps_program_to_MDriven, Chapter 6 is found here

Here is the video for Chapter 7: https://youtu.be/QxXA5D4mEio

Video 7: MDrivenEducationVideo Steps 215 - 238

Title Content Time(segment start) Youtube link
Introduction Introduction 00:00
Renaming and notes Renaming and notes. 00:08
Derived AttributeMode: Derived

Ordering a list in OCL

04:00
Tagged value Adding tagged value, making value editable 15:55
DateTime Type DateTime, IsStatic 22:25
Selectbox SelectBox (single-link with setter) 30:03

And here are the steps as text:

Chapter 7: First Mention of Derived Attributes; Editable Grid Cells in Web UI

215. CarsIUsedToOwn is actually a poor name. If we change the name to CarsPersonUsedToOwn, it is a better fit as it does not raise questions about whom "I" refers to. Type the new name in the Association end. Save (that will run the error check) and see the many errors.

216. Change it back to CarsIUsedToOwn temporarily and save. You will see no errors.

217. Instead of changing it, we will use the Rename function that will help to rename it everywhere it is used. Right-click the association end, choose rename, new name: CarsPersonUsedToOwn - Check "Set former name." Whenever you use "Rename," you should check "Set former name" to guide MDriven to help you once your changes also involve the creation of change scripts to a database. Save and verify that you are error-free.

218. Create a note on the diagram by right-clicking "Add note." Double-click the note box and write this in the note: we will assume that a person always has 1 car at a time and that when they sell the first car, that person immediately gets a new car on the same day. Close the note. Resize it and place it somewhere nice.

219. Add a new attribute, DatePurchased of type DateTime?, in class HistoricOwnership.

220. Select DatePurchased and in the property inspector, change the AttributeMode from Persistent(default - means saved in the database) to Derived (means calculated somehow).

221. Stay in the property inspector and find DerivationOcl. Click on the OCL editor with the three dots.

222. We want this DatePurchased to be derived from the prior cars DateSold.

We want to have an expression that from HistoricOwnership (self) goes up to the person (self.Person), and from there looks at all HistoricOwnership (self.Person.HistoricOwnership), makes sure that this list is in DateSold order (self.Person.HistoricOwnership->orderby(h|h.DateSold) ), and checks where in this list THIS HistoricOwnership (self) is (self.Person.HistoricOwnership->orderby(h|h.DateSold)->indexof0(self) ). Once we have that, grab the one after THIS HistoricOwnership : listinorder->at0(listinorder->indexof0(self)+1).

We find that we need the same list twice and it seems fair to get it once and use it in the expression twice. This is done in OCL with the "let x=someexpr in someotherexpr" operator.

We can write:

let  listinorder=self.Person.HistoricOwnership->orderby(h|h.DateSold) in

(

listinorder->at0(listinorder->indexof0(self)+1)

)

This expression will return a HistoricOwnership object, but we want this DatePurchased to be derived from the prior cars' DateSold. We append.DateSold

let listinorder=self.Person.HistoricOwnership->orderby(h|h.DateSold) in

(

listinorder->at0(listinorder->indexof0(self)+1)

).DateSold

223. Go to Person ViewModel and add the date purchased in the HistoricOwnershipGrid. Save and test the web.

224. We notice that there is no easy way for us to edit the DateSold; thus, the DatePurchased will get a null result all the time. Make the grid Editable by selecting the HistoricOwnership nesting head (blue).

225. Here we will add a tagged value (tagged values are extra meta information we can dress up our model with on most levels, like classes, attributes, and ViewModels). Press the Tagged values button in the ViewModelEditor.

226. In the shown window, press the Refresh from wiki button. Note how many predefined possible values (value store) are shown. You are not limited to these tagged values, but the predefined has a special meaning to the Turnkey (the web front-end engine, or to the WECPOF of the WPF engine).

227. Find Editable in the top selector. Add that, set its value to True, close, and save.

228. In order to make a cell in a grid editable. it must be in an editable grid - we fixed that just now - but a column must also have a ReadOnly expression that does not result in true (but rather false or left empty). Clear the DateSold viewModelColumn in the grid ReadOnlyExpression.

229. Save and test the web. You have an editable date-picker in date sold.

230. Enter some different dates in the rows - if you don't have rows, add some. Notice the instant calculation of the DatePurchase as the DateSold comes available on the row below.

231. Click the DateSold column head in the grid to verify that you get the correct values.

232. In the column DatePurchased, we want to force the iso date because we don't trust the browser setting. Change expression to self.DatePurchased.ToString('yyyy-MM-dd'). Save and test the web.

233 Discover the issue with use taking IndexOf0 +1 one - when the prior car is at -1 - fix derivation. Save test web

234 Notice the Name column - it now looks like an edit box - this is because we made the grid editable. Set column to IsStatic=true - save , verify in now looks like simple string

235 We actually dont even want the Name column here - since it will always be our own name - drop it

236 From class Car drag out new association arrow to Person - The Car-end you name CurrentCar and the Person-End you name CurrentOwner

237 In the Person ViewModel - add a SelectBox by right clicking in the green tree,Add Nesting ViewModelClass, SingleLinkWithSetter, CurrentCar - save, test web

238 Clean up the view and remove bogus columns

Next: The_1000_steps_program_to_MDriven_Chapter_8

This page was edited 35 days ago on 04/12/2024. What links here