Skip to main content
Solved

How to app a pop up dialog box in customization screen

  • October 3, 2024
  • 9 replies
  • 235 views

Forum|alt.badge.img+1

In Production Details screen’s extension, I have added an Action called ConnectToMRN.  In it’s workflow extension I have defined a dialog box also. I customized the Action such that it pop up the dialog box on click the button using the customization editor as bellow.

 

Following is complete workflow customization code of the production details screen.

public class ProductionOrderWorkflow : PXGraphExtension<ProdDetail_Workflow, ProdDetail>
{
    public sealed override void Configure(PXScreenConfiguration config)
    {
        Configure(config.GetScreenConfigurationContext<ProdDetail, AMProdItem>());
    }
    protected static void Configure(WorkflowContext<ProdDetail, AMProdItem> context)
    {
        var formAssign = context.Forms.Create("FormAssign", form =>
            form.Prompt("connectto").WithFields(fields =>
            {
                fields.Add("ConnectTo", field => field
                    .WithSchemaOf<MRMaterialRequest.refNbr>()
                    .IsRequired()
                    .Prompt("connectto"));
            }));
        var repairCategory = context.Categories.CreateNew(
            ActionCategories.RepairCategoryID,
            category => category.DisplayName(ActionCategories.DisplayNames.RepairOrders));

        var viewOrder = context.ActionDefinitions
            .CreateExisting<ProdDetail_Extension_1>(g => g.ConnectToMRN, a => a.WithCategory(repairCategory));


        context.UpdateScreenConfigurationFor(screen => screen
             .UpdateDefaultFlow(flow =>
             {
                 return flow
                 .WithFlowStates(flowStates =>
                 {
                     flowStates.Update<ProductionOrderStatus.closed>(flowState =>
                     {
                         return flowState.WithActions(actions =>
                                actions.Add(viewOrder)
                            );
                     });
                     flowStates.Update<ProductionOrderStatus.completed>(flowState =>
                     {
                        return flowState.WithActions(actions =>
                                actions.Add(viewOrder)
                            );
                     });
                     flowStates.Update<ProductionOrderStatus.cancel>(flowState =>
                     {
                         return flowState.WithActions(actions =>
                                actions.Add(viewOrder)
                            );
                     });
                 });
             })
             .WithCategories(categories =>
             {
                 categories.Add(repairCategory);
             })
             .WithActions(actions =>
             {
                 actions.Add(viewOrder);
             })
             .WithForms(forms => forms.Add(formAssign))
             );


    }


following is my action code. It just contains the template without exact logic.

            public PXSelect<MRMaterialRequest> MRMaterialRequestPopupView;

            public PXAction<AMProdItem> ConnectToMRN;
            [PXButton(CommitChanges = true)]
            [PXUIField(DisplayName = "Connect To MRN", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
            protected virtual IEnumerable connectToMRN(PXAdapter adapter)
            {
                // Show the popup to select MRMaterialRequest
                return adapter.Get();
            }
  1. How can I access the value selected from the dialog box from my action?
  2. how to configure the action with Dialog box via the customization code? Without using the customization editor. 
  3. is there any other way to implement above requirement without dealing with workflows?

 

 

Best answer by PDharmasena10

I Create Separate dialog box as below.

    <px:PXSmartPanel runat="server" ID="PXSmartPanel1" style="z-index: 108;" Caption="Connect To MRN" CaptionVisible="True" Key="MRNView" LoadOnDemand="true" AutoCallBack-Command="Refresh" 
    AutoCallBack-Target="formConnectToMRN" AutoCallBack-Enabled="true" AcceptButtonID="ConnectToMRNBtn" CancelButtonID="cancelBtn" Height="360px" Width="960px">
		<px:PXFormView runat="server" ID="PXFormView1" Caption="Connect To MRN" CaptionVisible="False" DataMember="MRNView" SkinID="Transparent" Width="100%" DataSourceID="ds">
			<Template>
				<px:PXSelector runat="server" ID="CstPXSelector3" DataField="RefNbr" />
				<px:PXButton runat="server" ID="ConnectToMRNBtn" Height="20px" Text="OK" CommandSourceID="ds" DialogResult="OK" />
                <px:PXButton runat="server" ID="cancelBtn" Height="20px" Text="Cancel" DialogResult="Cancel" />
            </Template></px:PXFormView>
    </px:PXSmartPanel>

Create a Separate DAC to hold the Value from the dialog box

    [PXHidden]
    public class MRMRNRefNbrDac : PXBqlTable, IBqlTable
    {
        #region RefNbr
        [PXString(15, IsFixed = false)]
        [PXUIField(DisplayName = "Ref Nbr")]
        [PXSelector(typeof(MRMaterialRequest.refNbr), typeof(MRMaterialRequest.refNbr))]
        public virtual string RefNbr { get; set; }
        public abstract class refNbr :
        PX.Data.BQL.BqlString.Field<refNbr>
        { }
        #endregion

    }

Create View and action as below. then it works.

public PXFilter<MRMRNRefNbrDac> MRNView;

public PXAction<AMProdItem> ConnectToMRN;
[PXUIField(DisplayName = "Connect MRN", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
[PXButton(DisplayOnMainToolbar = true, CommitChanges = true)]
public virtual IEnumerable connectToMRN(PXAdapter adapter)
{
    if (MRNView.AskExt() == WebDialogResult.OK && string.IsNullOrEmpty(MRNView.Current.RefNbr) == false)
    {

        // business logic

    }
    return adapter.Get();
}

For more details refer the following Acumatica documentation.

To Display a Dialog Box
 

View original
Did this topic help you find an answer to your question?

9 replies

darylbowman
Captain II
Forum|alt.badge.img+13

To use the values from the workflow dialog, change your action definition to set field values based on the fields you add to your dialog:

var viewOrder = context.ActionDefinitions
    .CreateExisting<ProdDetail_Extension_1>(g => g.ConnectToMRN, a => a
    .WithCategory(repairCategory)
    .WithFieldAssignments(fas =>
    {
        // This will assign 'YourDac.YourField' the value from the dialog
        fas.Add<YourDac.yourField>(f => f.SetFromFormField(formAssign, "ConnectTo"));
    })
    .WithForm(formAssign));

 


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 57 replies
  • October 3, 2024

Hi @darylbowman It works now. but I can’t access the selected value in the scope of action method, I tried following codes. 
            var data = Base.Caches<MRMaterialRequest>().Current as MRMRNRefNbrDac;
            var data = adapter.Get<MRMaterialRequest>().ToList().First();
But both are not works for me.


darylbowman
Captain II
Forum|alt.badge.img+13

I don't believe you can do that, no. Workflow is it's own little ecosystem.

If you wanna write regular code, you'd need to pop a custom smart panel with Base.SomeView.AskExt(). It's more work and has its own oddities but it would work with more normal code.


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 57 replies
  • October 4, 2024

Hi @darylbowman 
I Implement a separate dialog box as below.
 

	<px:PXSmartPanel runat="server" ID="PanelConnectToMRN" Caption="Connect To MRN" CaptionVisible="True" Height="360px" LoadOnDemand="True" Width="960px">
		<px:PXFormView runat="server" ID="formConnectToMRN" Caption="Connect To MRN" CaptionVisible="False" DataMember="MRNView" SkinID="Transparent" Width="100%" DataSourceID="ds">
			<Template>
				<px:PXSelector runat="server" ID="CstPXSelector3" DataField="RefNbr" />
				<px:PXButton runat="server" ID="ConnectToMRNBtn" Height="20px" Text="OK" /></Template></px:PXFormView></px:PXSmartPanel></asp:Content>

Following is the code related to action in ProdDetails graph extention
 

public SelectFrom<MRMaterialRequest>.View MRNView;

        public PXAction<AMProdItem> ConnectToMRN;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Connect To MRN", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
        protected virtual IEnumerable connectToMRN(PXAdapter adapter)
        {
            MRNView.AskExt();
            string msg = "WOrk fine";
            PXLongOperation.StartOperation(this,
            () => ConnectToMRNDoc(msg)
            );
        return adapter.Get();
        }

        public static void ConnectToMRNDoc(string refNbr)
        {
            string msg = "Triggers the method " + refNbr;
            throw new PXException(msg);
        }

But still not working the button. it shows the button in UI, when clicks nothing happens. Didi not show any error.
Note: I use the skinId as Transparent, it is the id used in other default panels in the screen


darylbowman
Captain II
Forum|alt.badge.img+13

Sorry, I forgot an important piece. The dialog needs to be called from a PXFilter view of the type of record that the dialog will display. Usually a new unbound DAC is created with the fields that you want on your dialog. Then, bind that view name to the form the way you did.

AskExt returns a PXDialogResult, so you can map different results to your buttons and find the user's intent.

Last thing is, the dialog method runs twice: once to show the dialog, once to continue after the dialog. This makes the behavior more tricky. I'm not certain why you're not receiving an error, but I would try something like PXTrace.WriteInformation to use as an indicator instead of throwing an exception. You can check the trace and see if it's making it there.


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 57 replies
  • October 4, 2024

Hi @darylbowman I update the code as below. but the still same issue. MRNView.AskExt(); throws a null reference exception.

       public PXFilter<MRMRNRefNbrDac> MRNView; 

public PXAction<AMProdItem> ConnectToMRN;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Connect To MRN", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
        protected virtual IEnumerable connectToMRN(PXAdapter adapter)
        {
            try
            {
                MRNView.AskExt();
            }catch (Exception ex)
            {
                string errorMsg = ex.Message;
                throw new PXException(errorMsg);
            }

            string msg = "WOrk fine";
            PXLongOperation.StartOperation(this,
            () => ConnectToMRNDoc(msg)
            );
        return adapter.Get();
        }

Create a separate Dac as below
 

    [PXHidden]
    public class MRMRNRefNbrDac : PXBqlTable, IBqlTable
    {
        #region RefNbr
        [PXString(15, IsFixed = false)]
        [PXUIField(DisplayName = "Ref Nbr")]
        [PXSelector(typeof(MRMaterialRequest.refNbr), typeof(MRMaterialRequest.refNbr))]
        public virtual string RefNbr { get; set; }
        public abstract class refNbr :
        PX.Data.BQL.BqlString.Field<refNbr>
        { }
        #endregion

    }

 


darylbowman
Captain II
Forum|alt.badge.img+13

Looking over my personal documentation, I believe a key part of this is having the ‘key’ of the smart panel be the name of your data view:

 

Also, the dialog itself is raised by an exception, so if you wrap it in a try / catch, that is almost certainly going to actively prevent it from opening.

I usually do something like this:

if (MyPanel.AskExt(true) != WebDialogResult.OK) return;

//Do some useful Stuff

 


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 57 replies
  • Answer
  • October 15, 2024

I Create Separate dialog box as below.

    <px:PXSmartPanel runat="server" ID="PXSmartPanel1" style="z-index: 108;" Caption="Connect To MRN" CaptionVisible="True" Key="MRNView" LoadOnDemand="true" AutoCallBack-Command="Refresh" 
    AutoCallBack-Target="formConnectToMRN" AutoCallBack-Enabled="true" AcceptButtonID="ConnectToMRNBtn" CancelButtonID="cancelBtn" Height="360px" Width="960px">
		<px:PXFormView runat="server" ID="PXFormView1" Caption="Connect To MRN" CaptionVisible="False" DataMember="MRNView" SkinID="Transparent" Width="100%" DataSourceID="ds">
			<Template>
				<px:PXSelector runat="server" ID="CstPXSelector3" DataField="RefNbr" />
				<px:PXButton runat="server" ID="ConnectToMRNBtn" Height="20px" Text="OK" CommandSourceID="ds" DialogResult="OK" />
                <px:PXButton runat="server" ID="cancelBtn" Height="20px" Text="Cancel" DialogResult="Cancel" />
            </Template></px:PXFormView>
    </px:PXSmartPanel>

Create a Separate DAC to hold the Value from the dialog box

    [PXHidden]
    public class MRMRNRefNbrDac : PXBqlTable, IBqlTable
    {
        #region RefNbr
        [PXString(15, IsFixed = false)]
        [PXUIField(DisplayName = "Ref Nbr")]
        [PXSelector(typeof(MRMaterialRequest.refNbr), typeof(MRMaterialRequest.refNbr))]
        public virtual string RefNbr { get; set; }
        public abstract class refNbr :
        PX.Data.BQL.BqlString.Field<refNbr>
        { }
        #endregion

    }

Create View and action as below. then it works.

public PXFilter<MRMRNRefNbrDac> MRNView;

public PXAction<AMProdItem> ConnectToMRN;
[PXUIField(DisplayName = "Connect MRN", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
[PXButton(DisplayOnMainToolbar = true, CommitChanges = true)]
public virtual IEnumerable connectToMRN(PXAdapter adapter)
{
    if (MRNView.AskExt() == WebDialogResult.OK && string.IsNullOrEmpty(MRNView.Current.RefNbr) == false)
    {

        // business logic

    }
    return adapter.Get();
}

For more details refer the following Acumatica documentation.

To Display a Dialog Box
 


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • 2759 replies
  • October 16, 2024

Thank you for sharing your solution with the community @PDharmasena10!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings