Dynamically changing a selector for a given data record in grid for Acumatica

Hello everybody,

today I want to share with you one very cool technique. 

I’ll tell you how you can dynamically change the output data in the selector.

I’ll show you this by giving you an example of forming a selector depending on the selected "CommandID" field. The "APInvoiceEntry" chart and the AP301000 page were taken as an example.

 The first let's create a DAC with the fields we need:

[Serializable]
public class MyCommand : IBqlTable
{
    public abstract class commandID : PX.Data.BQL.BqlInt.Field<commandID>
    {
    }
 
    [PXDBInt(IsKey = true)]
    [PXIntList(new int[] { 0, 1 }, new string[] { "Command 1""Command 2" })]
    [PXUIField(DisplayName = "Command ID")]
    public virtual int? CommandID { getset; }
 
    public abstract class commandData : PX.Data.BQL.BqlString.Field<commandData>
    {
    }
 
    [PXDBString(50)]
    [PXUIField(DisplayName = "Data")]
    public virtual string CommandData { getset; }
}

 

Remember to create these fields in your database.

 We also need a class with an extension for “APInvoiceEntry”. Then we create a button with a Popup panel for convenience and an event that will control the change of data in the selector.

 

public class APInvoiceEntryExt : PXGraphExtension<APInvoiceEntry>
 {
     public PXSelect<MyCommand> Commands;
 
     public PXSelect<GLTran> GLTrans;
     public PXSelect<FixedAsset> FixedAssets;
 
     protected void MyCommand_CommandData_FieldSelecting(PXCache cachePXFieldSelectingEventArgs e)
     {
 
         var row = (MyCommand)e.Row;
         if (row == null)
             return;
 
         PXFieldState state = PXFieldState.CreateInstance(e.ReturnState,
             typeof(string), falsetrue, 1, nullnullnulltypeof(MyCommand.commandData).Name);
         e.ReturnState = state;
 
         var id = (int)row.CommandID;
         if (id == 0)
         {
             state.ViewName = "FixedAssets";
             state.DescriptionName = nameof(FixedAsset.description);
             state.FieldList = new string[]
             {
                 nameof(FixedAsset.assetID),
                 nameof(FixedAsset.description),
                 nameof(FixedAsset.assetTypeID),
                 nameof(FixedAsset.assetCD)
             };
             var selectorCache = Base.Caches<FixedAsset>();
             state.HeaderList = new string[]
             {
                 PXUIFieldAttribute.GetDisplayName<FixedAsset.assetID>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<FixedAsset.description>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<FixedAsset.assetTypeID>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<FixedAsset.assetCD>(selectorCache),
             };
         }
         else
         {
             state.ViewName = "GLTrans";
             state.DescriptionName = nameof(GLTran.tranDesc);
             state.FieldList = new string[]
             {
                 nameof(GLTran.module), nameof(GLTran.lineNbr), nameof(GLTran.batchNbr),
                 nameof(GLTran.accountID), nameof(GLTran.tranDesc), nameof(GLTran.branchID)
             };
             var selectorCache = Base.Caches<GLTran>();
             state.HeaderList = new string[]
             {
                 PXUIFieldAttribute.GetDisplayName<GLTran.module>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<GLTran.lineNbr>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<GLTran.batchNbr>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<GLTran.accountID>(selectorCache),
                 PXUIFieldAttribute.GetDisplayName<GLTran.tranDesc>(selectorCache)
             };
         }
 
         state.DisplayName = PXUIFieldAttribute.GetDisplayName<MyCommand.commandData>(cache);
         state.Visible = true;
         state.Visibility = PXUIVisibility.Visible;
         state.Enabled = true;
     }
 
     public PXAction<PX.Objects.AP.APInvoice> CommandButton;
 
     [PXButton(CommitChanges = true)]
     [PXUIField(DisplayName = "Command Button")]
     protected void commandButton()
     {
         Commands.AskExt();
     }
 }

 After these changes, you'll see on the page AP301000 this artefact:

Now add popup bar to the page:

<px:PXSmartPanel runat="server" ID="CstSmartPanel1" Width="600px" LoadOnDemand="True" CaptionVisible="True" Caption="My Command" Key="Commands" CancelButtonID="CstButton8">
    <px:PXGrid runat="server" ID="CstPXGrid6" SyncPosition="True" Height="150px" SkinID="Details" Width="100%" MatrixMode="True" DataSourceID="ds">
        <AutoSize Enabled="True" MinHeight="50" />
        <Levels>
            <px:PXGridLevel DataMember="Commands" DataKeyNames="CommandID">
                <Columns>
                    <px:PXGridColumn DataField="CommandID" Width="70" CommitChanges="True" />
                    <px:PXGridColumn DataField="CommandData" Width="70" CommitChanges="True" />
                </Columns>
            </px:PXGridLevel>
        </Levels>
    </px:PXGrid>
</px:PXSmartPanel>

 And as outcome, you'll see that if Command 1 is selected, then dropdown gives you list of fixed assets:

and if you select Command 2, you'll see list of Accounts:

Summary

If you need to have different selectors in scope of single line, you'll need to define a view in your graph or graph extension, add FieldSelecting event, add pop up panel, and here you go, different selectors for different rows. A bit complicated, but for some tricky cases it may work. Also it shows how flexible Acumatica really is.

 

 

 

 

 

Add comment

Loading