PDA

View Full Version : When, Where and How? Constraining records across views.



Peter Bragg
3-May-2015, 06:19 AM
Finally just starting to have a play with the new mobile touch framework, so bear with me.

So for example, let's say I'm on the Dashboard view and I've an entry object where a user can free type a string. They then click a button to invoke a Select view (Customers, say) but the list is now constrained according to the value entered. What's the recommended way to handle this - in terms of the Events available to me?

For example, I can see OnNavigateForward. Should I be coding in here (OnNavigateForward of the Customers Select view) to see "how I got here" and then set constraints accordingly? I can see for example that I could code OnGetNavigateForwardData in the button that was clicked to set data in the NavigateData struct that could then be used in OnNavigateForward. I know I can do this but that fact that it seems I also then need to send MoveToFirstRow of the list object in order to get it to refresh suggests that by this time the list is already filled and so there may be an earlier opportunity to code something?

If we take this as a basic example - Dashboard with String Entry Object and Button. Click Button, invoke Customers list with names constrained to contain the entered text in Dashboard view - is using OnNavigateForward and OnGetNavigateForwardData the way to go here? Or is there a better way?


It's a pretty basic question I know, but given the way the framework hangs together in terms of objects talking to each other, I want to make sure I start off on the best footings.


Thanks in advance.

Peter Bragg
4-May-2015, 02:48 AM
So I figure I'm trying to be too "windows" here, with a mind set of callback messages, encapsulation and the like. Therefore I can achieve this by keeping things simple. Question remains though - is this the "recommended way" for such a thing?

I start with creating a web property inside my cWebView. I will use it from within my DDO but cannot create the property inside the DDO because web properties are not supported here.



Object oSelectCustomer is a cWebView
{WebProperty=True}
Property String psCustomerFilter


When leaving this view I want to make sure this filter is removed, so I can use OnHide for this, but need to also set pbServerOnHide to True first.



Set pbServerOnHide to True

Procedure OnHide
Forward Send OnHide
WebSet psCustomerFilter to ""
End_Procedure


If constraining by this value then I obviously need to add code to the oCustomer_DD object - so for the sake of example, something as simple as:



Procedure OnConstrain
String sCustomerFilter

Forward Send OnConstrain
WebGet psCustomerFilter of oSelectCustomer to sCustomerFilter
If (sCustomerFilter<>"") Begin
Constrain Customer.Name ge sCustomerFilter
End
End_Procedure


It's then just a question of creating a simple form in the Dashboard view in which a filter can be added and a button that calls the Customer Select view with the filter in place. So something along the lines of:



Object oFilterValue is a cWebForm
Set piColumnSpan to 10
Set psLabel to "Filter"
End_Object


Object oSearch_Btn is a cWebButton
Set piColumnSpan to 4
Set psCaption to "Search"
Set piColumnIndex to 10


Procedure OnClick
String sFilter

WebGet psValue of oFilterValue to sFilter
WebSet psCustomerFilter of oSelectCustomer to sFilter
Send NavigateForward to oSelectCustomer nfUndefined Self
End_Procedure
End_Object


Is it really as straightforward as this? Is the OnHide approach the best way to clear down the filter when done (I'm conscious of wanting to keep the number of additional events down to a minimum)?


Like I say, I guess it's a mind set thing. Normally I wouldn't talk across views like this in a windows environment because of breaking encapsulation and so on. But this isn't a windows application - and I figure the sooner my brain gets that, the better.

Harm Wibier
4-May-2015, 04:56 AM
Hi Peter,

You are on the right track here and this is actually an area that we've done some work on since the last Alpha so things will change a little bit.

But the idea is that you implement OnGetNavigateForwardData on the button to provide the NavigateData (which would include your search value in this case) and on the view you are entering you would implement OnNavigateForward to initialize the view based on the navigation data (in your case set / clear the constraint and seeding the list). Advantage of that method is that the calling view doesn't need internal knowledge of the view being called (in your code the web property you are setting).

Now you use a separate web property to store the search value being constrained on. If you use the NavigateData to pass the search value you could also get it directly from there as the NavigateData is also stored (in a web property actually) and accessible at any time using GetNavigateData. One of the changes that we have made is that the NavigateData in the next build will contain an array of name value pairs for custom data instead of just a single string as it does now.

Note that to seed a data bound list you shouldn't use MoveToFirst row as that is meant to change the selected record in a manually filled list. Better would be to perform a find on the DD or use either RefreshListFromDD or FindDDRecordInBuffer.

Regards,

Peter Bragg
4-May-2015, 08:28 AM
Thanks Harm,

The irony then that I pretty much had it right first time only to convince myself it wasn't the way to go. But that was the point of the post really, just to get an idea of the recommended approach for this sort of thing. As it turns out, the reason I wasn't sure it was correct because I wasn't quite getting the correct behaviour - but this was a coding error (yes, you've guess it, a "set" that should have been a "webset")

Peter Bragg
4-May-2015, 08:47 AM
So just to complete this, the code would be much simplified as it would end up simply being as follows:

The search button would simply contain:



Object oSearch_Btn is a cWebButton
Set piColumnSpan to 4
Set psCaption to "Search"
Set piColumnIndex to 10

Procedure OnClick
Send NavigateForward to oSelectCustomer nfUndefined Self
End_Procedure

Procedure OnGetNavigateForwardData tWebNavigateData ByRef NavigateData
String sFilter

WebGet psValue of oFilterValue to sFilter
Move sFilter to NavigateData.sData
End_Procedure
End_Object



And then inside the SelectCustomer view, you could simply code OnConstrain of the oCustomer_dd as:




Procedure OnConstrain
tWebNavigateData NavigateData

Forward Send OnConstrain
Get GetNavigateData to NavigateData
If (NavigateData.sData<>"") Begin
Constrain Customer.Name ge NavigateData.sData
End
End_Procedure



No need to create any new web property and no need therefore to clear that property down when leaving the view.

Obviously this is ok for now if you know the only data you ever want to pass is a filter value (for the name) - but if in the next release this "data" value is an array of name value pairs then obviously this framework becomes a lot more flexible.

John van Houten
4-May-2015, 01:25 PM
Peter, yes you have it right.

John van Houten
Data Access Corporation