Friday, 27 November 2015

Add a Custom Popup Panel

Hi Everyone,

Today I want to share with you some practices how you can do iteration with user from Acumatica business logic code. In general:
  • You can ask some simple question with strait forward answer, like: "Do you really want to delete this record? Yes/No"
  • You can use redirection feature to redirect user to some hidden screen, where he will do some additional configuration and processing.You can hide screen by putting it into the hiden folder of Acumatica sitemap. When screen is hidden user can access it only with redirection from some other screen.
    Acumatica Sitemap
  • But if you want to do more interactive dialog with user you may need use popup dialog with smart panel. In This case you can show some configuration to user that is related to requested operation. This panel will be hidden on the screen until you call it with appropriate code from your business logic. When user close panel, your code will be automatically notified about configuration changes.
    Acumatica smart popup panel

Web Dialogs
The first and simplest way to communicate with user is just simple dialog.

Code snippet:
Please note some important notes about dialogs:
  • When you call "Ask" method from DataView, system will throw PXDialogRequiredException. You should not catch it as it is good exception, that will be automatically handled by user presentation logic. When user will answer on the question, system will automatically rund your method in second time. In this case DataView will have dialog result from user interface, so exception will not be thrown. So you need to plan your business logic according to the rule, that your code will be called twice.
  • You need to aware about localization of your questions by you own. In general your message should be a constant string in some static class with [PXLocalizableAttribute]. When you are colling dialog, you should call localization engine manually by function: PXMessages.LocalizeFormatNoPrefix(...);

Smart Panels
Smart panels are similar to web dialogs, but instead of showing simple question, system will show a specific control - smart panel, that will be mapped to some DataView inside business logic container. Smart panel should have at least one container control (PXForm, PXGrid, PXTab), that will be mapped to the same DataView as smart panel. Container control will select and update data inside PXCache that is associated with their DataView.

Business logic code snippet:

Presentation logic code snippet (*.aspx):

Some points from these examples:

  • Panel is mapped to DataView by attribute "Key"
  • To call smart panel you need to use "AskExt" method instead of using standard "Ask"
  • If you need buttons, you need to define it by your own in the smart panel:
    • Use panel with predefined skin - SkinID="Buttons".
    • Specify dialog result for all buttons - DialogResult="OK".
    • Enable auto-callback if you need to commit cahnges from smart panel of OK button - <AutoCallBack Command="Save" Target="frmMyCommand" />.
Now it should works fine. Have a nice development!

12 comments:

abanoub labeeb said...

i follow these steps >> the dialog pop up appear but no action performed after return

Sergey Marenich said...

Hi Abanoub,
Have you defined buttons on popup panel with dialogResult and callbacks?

VANNAK said...

It worked but It show this message "An unhandled exception has occurred in function 'MoveNext'. Please see the trace log for more detail". Do you know why it happen ?

Sergey Marenich said...

Vannal,
I need your trace. Contact me by skype i'll try to help.

vlad lesh said...
This comment has been removed by the author.
Sergey Marenich said...

Vlad, This is correct behavior. Dialog result Cancel does not do anything - just closes window with no any callback. If yoг туув callbacks use other dialog results.

vlad lesh said...

Hello Sergey, i have problem with dialog window.
My Dialog Window is closed after entered incorrect values, if i click 'cancel' button earlier.
To reproduce it, you need:
1) Write validation on any field.
2) Open Dialog window.
3) Close Dialog Window.
4) Open Dialog Window.
5) Enter incorrect values in our field => Dialog Window is closed.

I use validation like this:
Base.Document.Cache.RaiseExceptionHandling(
Base.Document.Current, value, new PXSetPropertyException(
"Message"));
throw new PXException();

It is a known issue or i made something wrong. Because when i open window in the first time validation work correctly.

Sergey Marenich said...

Vlad,
what do you mean under "Dialog Window is closed."? Do you mean that dialog is automatically closed when you change field?
If yes, it might be related to dialog answer exists some where in data view form previous attempt to close.
If no, than i need a way to reproduce it exactly.

vlad lesh said...

Sergey,
When i click 'OK' button my window is closed(but it happends if i earlier click 'cancel' button). For example:

Code for dialog window:











{
public abstract class f2 : IBqlField { }
[PXDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Field 2")]
public virtual decimal? F2 { get; set; }
}

Graph Extension:
public class SOOrderEntryExt : PXGraphExtension
{
public PXAction DialogTest;

[PXUIField(DisplayName = "Dialog Test")]
[PXButton]
public IEnumerable dialogTest(PXAdapter a)
{
if (Base.Document.AskExt() == WebDialogResult.OK)
{
ValidateVendorPaymentAmount();
//something else
}

return a.Get();
}

private void ValidateVendorPaymentAmount()
{
Base.Document.Cache.RaiseExceptionHandling(
Base.Document.Current, -12, new PXSetPropertyException(
"Something was wrong"));
throw new PXException();
}
}

vlad lesh said...

Code for dialog window
px:PXSmartPanel runat="server" ID="PanelPayBillJC"
CommandSourceID="ds" Key="Document" LoadOnDemand="True" Caption="Indicate Amounts to Pay"
CaptionVisible="True" Width="850px" Height="400px" AutoReload="True">
px:PXFormView runat="server" ID="frmVendor" SkinID="Transparent" DataMember="Document" DataSourceID="ds">
Template>
px:PXNumberEdit runat="server" ID="usrF2" DataField="f2" CommitChanges="True" />


px:PXPanel runat="server" ID="IndicateAmounts" SkinID="Buttons">



Sergey Marenich said...

Vlad,
Move your validation from action handler to DAC_FieldVerifying event. Than your field will be validated when you change focus and not on action click.
In your case it is designed behavior - actions close panel in javascript, but validation is done on server side.
Event should help you.

vlad lesh said...

Sergey ,thanks!!!