Hi Everyone,
Sometimes you need to have a screen with 2 grids that depend on each other. When you change line in one grid, it should refresh records in another. In this case you need to establish Grids Master-Detail relationship.
In general master-detail relationship for grids is almost the same as for form-grid. You can read more about it in T200 Framework Fundamentials Training Guide, Example 2.2, Setting Up the Master-Detail Relationship Between Data
As a summary from the training, we need to do 3 points
- Put PXDBDefault attributes in child DAC to auto-initialize dependent keys.
- Put PXParent attribute in child DAC to allow cascade deletion and few other functions.
- Use Current<> parameter in Data Views to refresh child table data based on parent record.
So for grids you need to do the same points,plus some more. I’ll show it based on example of Generic Inquires. We will speak about 2 tables: GIRelation and GIOn that are Master-Detail relationship.
1-Initialize Child Keys
We use PXDBDefault in GIOn DAC to auto-insert keys, so user should not wary about it in UI.
public class GIOn : IBqlTable { public abstract class relationNbr : IBqlField { } [PXDBInt(IsKey = true)] [PXDBDefault(typeof(GIRelation.lineNbr))] public int? RelationNbr { get; set; } }
2-Specify Parent Record
We also need to use PXParent attribute to enable cascade deletion, formulas, defaulting and some other fictions.
public class GIOn : IBqlTable { public abstract class relationNbr : IBqlField { } [PXDBInt(IsKey = true)] [PXDBDefault(typeof(GIRelation.lineNbr))] [PXParent(typeof(Select<GIRelation, Where<GIRelation.designID, Equal<Current<GIOn.designID>>, And<GIRelation.lineNbr, Equal<Current<GIOn.relationNbr>>>>>))] public int? RelationNbr { get; set; } }
3-Data View Dependent Select
We also use Current<> parameter in the PXSelect dataview to select proper detailed records. Please note that our child table has 2 conditions as it depends on GIRelation and GIDesign (as primary entity) also.
public class GenericInquiryDesigner : PXGraph<GenericInquiryDesigner, GIDesign> { public PXSelect<GIRelation, Where<GIRelation.designID, Equal<Current<GIDesign.designID>>>> Relations; public PXSelect<GIOn, Where<GIOn.designID, Equal<Current<GIDesign.designID>>, And<GIOn.relationNbr, Equal<Current<GIRelation.lineNbr>>>>> JoinConditions; }
4-Grids Auto-Refresh
That is all from the code perspective, but we also need to configure UI to automatically refresh child grid, when we update parent. To do this we enable auto-callback from the parent grid to the child grid. This callback will be triggered on changes in parent and refresh child grid.
<px:PXGrid ID="grdJoins" runat="server" ...> ..... <AutoCallBack Command="Refresh" Target="grdOns" ActiveBehavior="True"> <Behavior RepaintControlsIDs="grdOns" BlockPage="True" CommitChanges="False" ></Behavior> </AutoCallBack> ..... </px:PXGrid>
5-Grids Current Record Sync
And lastly we need to advise Acumatica UI that changes (or selected recird) in the parent grid should be synced back to graph, as dataview there need to know parent for proper child select. To do that we set SyncPosition=”True” for the parent grid.
<px:PXGrid ID="grdJoins" runat="server" SyncPosition="True" ...> ..... </px:PXGrid>
That is it, now Master-Detail relationship is established and child grid should be refreshed automatically as soon as you change record in the parent grid.
Have a nice development!
Hi Sergey,
In the Master grid, everytime i create a new record, the Detail lines of the previous Master record are deleted.
Can you think why?
Hi Hamza,>>> Relations;
Are you sure that the details records are deleted? Most probably they are still there in the PXCache. But when you insert a new master line, the new Master ID is generated, resultantly the details PXSelect selects no lines, since the are no lines with new ID.
like here:
public PXSelect
So if my guess is correct, the behavior you observe is correct.
If you need deails regardless of the master line, you should change the PXSelect Criteria
Hi Sergey,
I tried replicating the steps above but am very confused since I am still new in C# language and ASP.NET.
Basically, I have created a field called HS Code which accepts text as its input in Stock Items (IN202500) screen via Screen Editor. The location is as below
IN202500 > General tab > Warehouse Defaults > HS Code
I managed to insert similar field in Sales Orders (SO301000) screen, but the field does not linked with the that has been created in IN202500 screen. The location is as below
SO301000 > Details tab > Grid: Transactions > HS Code
Both fields are using their default names during creation: usrHSCode
Please assist on how to resolve this
Hi Eric,
There is no code that copies value from IventoryItem to SOLine. You should write this code on SOLine_InvetoryID_FieldUpdated event.
Hi Sergey:
Is there a way to refresh a form depending on the selected row on the grid?
Hi Anahi,
Yes, you can. In the grid ASPX add the AutoCallBack with Behavoir and RepaintControlIDs.