StrataFrame Forum

How to limit browse dialog on child dialog form

http://forum.strataframe.net/Topic14691.aspx

By Larry Tucker - 3/6/2008

Hi,

I've got a child dialog form (built from SF Maintenance class) working well except for its browse dialog, which is not limiting the offered records to those associated with the current parent record.  When it is searched, it offers all possible child records. 

The BO relationship is correctly setup, because adding a MyChildBO1 record correctly fills its FK_Parent foreign key field.  And when I navigate through the child records, only those for a given FK_Parent are shown.   What I would like is for only those records to be offered on the child form's browse dialog.

To help inform the browse dialog, I added a copy of the MyParentBO1 to the child form and have the parent form CFD fill both the MyChildBO1 and MyParentBO1.   I've checked that on the child form, MyParentBO1 is sitting there on the correct record after it is loaded, so that its PK does match the FK on the child records.

I've tried fiddling with the various settings within the ChildForm.BrowseDialog1.BusinessObjectToPopulate properties.  In there, the ParentBusinessObject is correctly set to MyParentBO1.  "ChildAutoFilterOption" looked promising but doesn't seem to help.

Any suggestions would be appreciated. 

TIA,

Larry

By Trent L. Taylor - 3/6/2008

The Filter is not respected in the BrowseDialog because a new instance of the BO is created...but aside from that it is querying the database, not the BO.  You can get around this though by either adding a SearchField that is hidden and setting the InitialSearchValue...or by handling the Searching event of the BrowseDialog and manually adding a WHERE condition to the query that only searches on the child records that match the parent.  This can be done fairly easily and it just depends on which avenue that you want to travel.

I recommend loading the 1.6.5 update and then looking at the Advanced BrowseDialog sample.  It shows a simple usage of the Searching event...additionally there is help documentation that has been added that shows how to add a WHERE element through the Searching event of the BrowseDialog.

By Larry Tucker - 3/6/2008

Trent,

Thanks for the quick reply.  Sounds like a good plan.

Larry

By Larry Tucker - 3/6/2008

Trent,

I've run the upgrade and had some success sending in an initial search value (the child FK) to the browse dialog.   But I notice that something more basic is amiss:  the browse dialog selection is not actually moving the record pointer in the calling form.  In other words, it doesn't matter what I select in the browse dialog... nothing is changed when it closes.  Again, I am calling the browse dialog from a child dialog form.  Is there something about a child dialog that precludes using a browse dialog? 

Just to test it, I started over with a fresh BrowseDialog on the ChildForm with no FK filtering or changes.  When I call the ChildForm directly (not via a CFD on a parent form), the BrowseDialog correctly moves the record pointer to the record selected.  When I call the exact same form via a CFD on a parent form, the browse selection does not move the record pointer.  It does appear that the CFD process is interfering with the BrowseDialog.

Larry

By Trent L. Taylor - 3/7/2008

I am not sure exacatly what you are doing, but the BrowseDialog will update the BO that is set in the BusinessObjectToPopulate property of the BrowseDialog, as well as set the current index to the selected record in the results.  So be sure to check that you have the correct instance of the BO being updated...otherwise, nothing will happen Smile
By Larry Tucker - 3/7/2008

Trent L. Taylor (03/07/2008)
I am not sure exacatly what you are doing, but the BrowseDialog will update the BO that is set in the BusinessObjectToPopulate property of the BrowseDialog, as well as set the current index to the selected record in the results.  So be sure to check that you have the correct instance of the BO being updated...otherwise, nothing will happen Smile

Trent, not sure if you were really asking for "exactly what I'm doing", but here are some attached screen shots <s>.  As you can see, the BusinessObjectToPopulate property is correctly set.

I deleted the child form completely and started from scratch with an absolute minimum configuration and am getting the same results.  The browse dialog does work when I call the child form directly (and fill it using a FillAll() button).  It does not work when I call the child form from the parent form.  This suggests that the browse settings are correct and that it the problem has something to do with the way the child form is being called (direct or as a CFD).

In a way, it makes sense to me that the browse should have trouble when the form is called as a child form.  Let's say the child form loads with 10 records associated with the parent record on the parent form.  Then you hit the browse button with no special conditions and it offers all 50 records in the child table (unfiltered).  And you pick one that is not even in the current 10 in the child form BO.  Where is the record pointer supposed to go when you close the browse?  Obviously, I don't yet know s#it from shinola about what is actually going on under Strataframe's hood but it seems logical that either the browse dialog is already tuned into the filter assumed by the child form... or its not.  And if its not, then I don't see how it could reliably work.  BTW, I tried setting the FK_TemHead filter in the browse window, which correctly limited the displayed records to the same ones in the child form... and the positioning still doesnt work.

Enough speculating... If you could take a look at the attachment, I'd appreciate it.  I fully expect that it will take you 2 seconds to find a setting I have missed.Unsure

Larry

By Edhy Rijo - 3/7/2008

Hi Larry,

I am confuse here, why would you need (or want) a Browser Dialog in a child form which I believe will only display filtered records by its parent?

By Larry Tucker - 3/8/2008

Hi Edhy,

Good to hear from you. 

Edhy Rijo (03/07/2008)
confused here, why would you need (or want) a Browser Dialog in a child form which I believe will only display filtered records by its parent?

It's like the "related forms" we've been using in VPM (Visual ProMatrix for Foxpro):  when you open a child form you have both toolbar arrow and list button navigation options which are synchronized and limited to the value on the parent table.  In Strataframe, I'm testing using a "SF Maintenance Form" class for both the parent and related child maintenance.  I just want the UI to be consistent so that if I offer a browse dialog on the parent form, then I'd like it offered on the child form too. 

The child form's browse dialog would be more for navigation than subsetting and would simply produce a list of available child records with incremental search in the list but no search fields per se.   (The Advance Browse sample shows something like this where all "Smith" records are presented immediately when you hit the browse button with no search fields or query).

I think your question concerns the subsetting / query function of the browse dialog and you're right, most child tables will have few enough related items that further subsetting would not be necessary.  So I'm just thinking of it as a quick navigation option through say 30 or so child records. 

Again, I was starting with the idea of using an SF Maintenance form for the child table with only one record showing at a time.  In contrast, the sample ChildDialog puts the navigation list right on the child form (CustomerNotes) and requires a third edit form to do the editing of a child item (CustomerNoteEditor).  I was thinking of having the child form itself be the edit form (SF Maintenance) with the same toolbar and browse options as the parent form.   If there are only a few child records, then the toolbar nav buttons will suffice; if there are 20 or 30 child records, then a quick browse button would be nice.  Not a big deal really.  I just thought the user would find it more familiar if the parent, child and possible grandchild forms all had the same presentation (SF Maintenance) and didn't require additional "edit forms" to get anything done. 

Larry

By Edhy Rijo - 3/8/2008

Hi Larry,

Good to hear from you too!

I think I now understand what you want to do, but keep in mind that the key to success with any framework with to work with it not against it Smile

I still need to learn a lot about SF but I believe that if all you need is to provide end user with an easy way to locate a child record, you can simply add a grid or list where then can just scroll to the record faster and edit the current selected one.

I am working on a simple project and been playing with relations and came up with something like in the iamge attached, where you have the following:

  • Parent record on top
  • Multiple Children at the bottom
  • Edit of child record data in the same page of the child listing.

Again, this is just a sample view, but I sure it can be done in many ways, specially in SF where is easier to handle related records than in VPM (VFP).

By Larry Tucker - 3/8/2008

Hi Edhy,

Actually, I thought using a built-in browse dialog was working with the framework <s>... but maybe not. 

Thanks for the suggestion and screen shot.  I agree it is easier to work with a child BO on the same parent form because of SF's automatic synchronization (both when you navigate the parent and when you add a child).  SF does a nice job of managing a lot for you.  And your example avoids the separate browse and edit windows.

Keeping the children on the same page may also better communicate to the user that they really are connected to the current parent; a separate child form floating on its own makes this connection less concrete. 

(In VPM, I actually used related pages a lot more than related forms for this reason... clicking on a child tab made more sense to my users than poping up a new window.  The less sophisticated the user, the more they seemed put off by multiple windows.  I've had some good luck building related pages forms in SF too. Wink

Overall I'm liking this framework a lot.

Larry 

By Richard Keller - 3/8/2008

I also like the Master Detail metaphor as well.  Where the summary rows are in one tab, edittable and the detail are another tab.  Please take a look at my screencast.  It shows how to create a master detail tab and bind to toolbar with minimal effort.

http://www.screencast.com/t/a3rEJbsYFtt

By Edhy Rijo - 3/8/2008

Larry Tucker (03/08/2008)

(In VPM, I actually used related pages a lot more than related forms for this reason... clicking on a child tab made more sense to my users than poping up a new window.  The less sophisticated the user, the more they seemed put off by multiple windows.  I've had some good luck building related pages forms in SF too. Wink

Hi Larry,

Honestly I never used the Related Form functionality in VPM, I am sure some developers may find it very useful, but in my case, I try to keep it simple whenever I can.  Also I am always looking at other commercial applications look and I have never seen the Related Form approach which lead me to just keep it in the bag in case I may ever use it, but after 10+ years working with VPM (Visual ProMatrix) I never actually use it and disable it at the base class.

I am glad to be of some help.  Please show us your final form when complete.

By Edhy Rijo - 3/8/2008

Hi Richard,

Thanks for sharing this video with us, it does provide a quick way to get this done, even though you are using a 3rd party controls.

One thing I notice is that at the end of the video the screen came up all red and IE just crashed, I tried twice and the same thing happen, so I guess the video is somehow corrupted.

I noticed from your toolbar that you are using IBIZ component for QuickBooks.  I purchased a license long time ago to be used with VFP as an ActiveX, but never got the chance to use it.  I may need to upgrade my license for .NET for an upcoming project, can you please give me your input on the use of these component under .NET?

Thanks again!

By Trent L. Taylor - 3/9/2008

Hey guys,

Thanks for all of your ideas here...good stuff.  I thought I would put in my two cents as well. Smile

Larry, I think that what Edhy was getting at when he mentioned working against the framework isn't that the BrowseDialog (a StrataFrame component) was working against the framework, it is more related to working against a disconnected data set.  We too are from a VFP background and one of the bigger learning curves to make is working with disconnected data.  In VFP, you could just slap on a filter and show only the records that you were interested in....this was easy since all of the records were ALWAYS brought the client side (even when using views, etc. since the query was performed on the client and not a server like SQL Server).

Edhy's example of the child data is similar to what we do.  We use a lot of ListViews instead of grids and then use teh ChildFormDialog control to popup a child form to add and edit those child records. 

If you want to filter out records allowed in the Browse, then you can use the Searching event of the BrowseDialog like we talked about in an earlier post.

But you have mentioned Related Forms from VPM...though a slightly different twist, using a ChildFormDialog control and setting the BusinessObject Translations is basically helping you achieve this same type of thing.  In FoxPro you would genreally have the parent form set as a Private data session and the child as a default so that it could see the parent's data session...in essence this is what the ChildFormDialog helps you to accomplish.  I will try to post some screen shots in the next couple of days showing how we implement this in our medical software (it might spark a few ideas). Smile

Richard,

Thanks for taking the time to create this video...these types of things are ALWAYS helpful for other developers out there! 

By Larry Tucker - 3/10/2008

Everyone,

Yes, this is very helpful and all the input is appreciated.  Both Edhy's and Richard's examples are great.  I think we are addressing 3 different issues at once:  1)  what is the easiest UI for the user; 2) what works best from a technical / efficiency point of view with disconnected data; 3) whether a browse dialog ever works on a child form.

Richard's "Master/Detail" tabs are similar to what I used to do in VFP (and called "related pages").  Using parameterized views, I'd requery the detail view as needed when it was clicked.  I think I've been able to do something similar in SF as follows

Private Sub pgfMain_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _

  Handles pgfMain.SelectedIndexChanged

If Me.pgfMain.SelectedIndex() = 1 Then ' page 2

  If Me.TemHeadBO1.IsDirty Then

    Me.TemHeadBO1.Save()

  End If

  Me.TemItemBO1.FillByParentPrimaryKey(Me.TemHeadBO1.PK_TEMHEAD)

Else ' back to page 1

  If Me.TemItemBO1.IsDirty Then

    Me.TemItemBO1.Save()

  End If

End If

End Sub

Not sure this is the best way to save dirty BOs, but the detail BO requery seems to work.  I notice Richard also changes the primary business object at this point to make the nav work on either the master (TemHead) or detail (TemItem) BO.  Very nice.  His example loads the entire detail BO at form load and then uses the SF BO.ChildAutoFilter setting to apply a filter.  I assume his approach is technically preferred for smaller detail tables and the separate queries when needed (as above) is better for larger ones.

As for the preferred UI, my guess is that for detail tables with fewer fields, Edhy's single page approach is preferable... and that the Master/Detail related tabs is better for complex child tables especially if the child tab has simply fields instead of a grid or even additional tabs if needed.

Finally, as for my original question on this thread concerning using a browse dialog with a child form, Trent, are you saying you are able to get the dialog to work?  I can filter it to match the records in the child table, but can't get it to position the child record pointer when it closes.

Larry

By Trent L. Taylor - 3/11/2008

what is the easiest UI for the user;

This in itself can be a very long.  Here is a sample of one of our maintenance forms in our medical software.  We take a different approach and use the IsDirtyChanged event to dynamically add the Save and Undo links to an action list for the end-user.  You can also see how we present child information to the end-user.

  1. Actions - This action list is in the same place on every form in the system (we actually call them pages since we use a folder style format).  This list grows with actions specific to the entry form at hand.
  2. Getting Started - This generally has a browse and an Add new link to help the end-user get started.  These links do the same thing that the Action list does...it is just on the first page (which is a page in a PanelManager).
  3. MRU List - We have a persistent MRU list for every maintenance form, by logged in user, in the entire system.  This is a huge feature that our users love....especially since it is persistent.

Once a record is selected for maintnenace (either a new record or existing record) then the PanelManager moves to Page two which has the editor:

You'll see that as soon as a text field is changed, the Save and Undo links automatically appear in the list.  This is done by handling the IsDirtyChanged event of the BO.  When we load the record, we use the FillMultpleDataTables method on the BO (refer to the docs on how to use this new method in 1.6.5) to retrieve the parent and child records in a single trip to the server...MUCH faster!  You can see that there is a page tab that has Provider Numbers.  In this maintnenace form, there are so many fields that we had to use a page tab, which is where the child records are presented.

You can see that they are already populted when the records is loaded...NOT when you go back and forth from page to page.  Doing this when a page becomes active can work in a scenario where the data is going to be very small.  But the larger the data becomes the less responsive your application becomes.  Users tend to be OK with an initial loading pause, but not when they are in the middle of modifying a record.  If a child record is selected or added, then a ChildFormDialog control is used to show the child form.  Here is what the child form for the list on the left looks like:

The Save doesn't actually save to the database, it just checks the rules and if all is well, returns back to the parent.  The Parent form is where all of the saving to the database should take place.

what works best from a technical / efficiency point of view with disconnected data

This one question could be an entire training session, and is something that we cover in our training class.  The bottom line is the fewer trips to the server the better and only bring back what you need.

whether a browse dialog ever works on a child form

A browse dialog will work anywhere that you put it.  I think that the issue that you are running into on this forum discussion is that this is generally not something that should be done to load a record for editing on a child.  If you are using the BrowseDialog to lookup a child or foreign key record then that is perfect, but to bring back a record for editing is not good programming technique and is confusing to an end-user.

His example loads the entire detail BO at form load and then uses the SF BO.ChildAutoFilter setting to apply a filter.

This can be dangerous and is something that we see people fight all the time.  There is a time and place for filters, but this is generally not the place.  If you are using this technique you are bringing back more data than you need to work on.  Secondly, this can present issues with you add or modify a record since the filter is dynamic.  I have seen MANY issues come from this approach.  You have to be very cautious in a designer environment when using a filter since you are going to be adding records and modifying records...records can start "disappearing" or "moving" on you which throws a wrench in your programming logic thus introducing bugs and "disappearing data."

Finally, as for my original question on this thread concerning using a browse dialog with a child form, Trent, are you saying you are able to get the dialog to work?  I can filter it to match the records in the child table, but can't get it to position the child record pointer when it closes.

This works fine and we have this in many places in our medical software.  The only reason that you record would be positioned wrong in this case would be some logic in your code moving the record pointer.  Check which events you are handling and where you have logic to reload or move a record pointer.  The record pointer in this case is being moved AFTER the BrowseDialog has done its work.

Final Note: Larry, I think that the training class that we have in July would be a major boost to your development cycle.  We cover all of these topics and more and you can move your learning curve to the left a year or more.  We have tweaked our training over time to tackle all of these types of issues so that you don't continue to churn your wheels in the muck and can get to business much faster.  Just a suggestion. Smile  Not just for Larry, but for anyone facing these types of questions!

By Larry Tucker - 3/11/2008

Trent,

Thanks very much for the detail and screen shots. 

As for the class suggestion, it is a good one and I was hoping to take the next class... but the scheduling conflicts with my vacation.  Maybe next time.

Larry