I am working on a process screen with an Action drop-down and a selector. I want the selector to display values based on Action selected.
For example, I have an Action drop-down of two values 1. Prepare and Release Invoice and 2. Print COnsolidated Invoice and selector which shows Sales orders with Completed status when the first Action is selected. Can anyone give me an idea on how to implement this? Below is my filter table with Action and a selector fields.
[Serializable()]
public partial class ImportInvoiceFilter : PX.Data.IBqlTable
{
public const string PrintConsolidatedInvoice = "PCI";
public const string PrepareAndReleaseInvoice = "PRI";
public class prepareAndReleaseInvoice : Constant<string> { public prepareAndReleaseInvoice() : base(PrepareAndReleaseInvoice) { } }
public class printConsolidatedInvoice : Constant<string> { public printConsolidatedInvoice() : base(PrintConsolidatedInvoice) { } }
#region ReferenceID
[PXString(30, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Customer Reference Nbr")]
[PXSelector(typeof(Search<SOOrder.customerRefNbr,
Where<Where2<Where<SOOrder.status,
Equal<SOOrderStatus.open>,
And<Current<ImportInvoiceFilter.selectAction>,
Equal<ImportInvoiceFilter.prepareAndReleaseInvoice>>>,
Or<Where2<Where<SOOrder.status,
Equal<SOOrderStatus.completed>>,
And<Current<ImportInvoiceFilter.selectAction>,
Equal<ImportInvoiceFilter.printConsolidatedInvoice>>>>>>>),
typeof(SOOrder.orderNbr),typeof(SOOrder.orderDesc),
typeof(SOOrder.customerRefNbr))]
public virtual string ReferenceID { get; set; }
public abstract class referenceID : IBqlField { }
#region SelectAction
public abstract class selectAction : PX.Data.IBqlField
{
}
protected string _SelectAction;
[PXUIField(DisplayName = "Select ")]
[PXStringList(new string[] { PrepareAndReleaseInvoice, PrintConsolidatedInvoice },
new string[] { "Prepare and Release Invoice", "Print Consolidated Invoice" })]
[PXDefault(PrepareAndReleaseInvoice)]
public virtual string SelectTemplate
{
get
{
return this._SelectAction;
}
set
{
this._SelectAction = value;
}
}
#endregion
}
ASPX:
<%# Page Language="C#"
MasterPageFile="~/MasterPages/FormDetail.master"
AutoEventWireup="true" ValidateRequest="false"
CodeFile="KN506000.aspx.cs" Inherits="Page_KN506000" Title="Untitled
Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormDetail.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
PrimaryView="Filter" TypeName="KNLANOrderProcess.OrderInvoiceProcess">
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Style="z-
index: 100"
Width="100%" DataMember="Filter">
<Template>
<px:PXLayoutRule runat="server" ID="CstPXLayoutRule8" StartColumn="True" ></px:PXLayoutRule>
<px:PXDropDown runat="server" ID="CstPXDropDown10" DataField="SelectTemplate" CommitChanges="True" ></px:PXDropDown>
<px:PXSelector runat="server" ID="CstPXSelector9" DataField="ReferenceID" CommitChanges="True" AutoRefresh="True" ></px:PXSelector></Template>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" Runat="Server">
<px:PXGrid ID="grid" runat="server" DataSourceID="ds" Style="z-index: 100"
Width="100%" Height="150px" SkinID="Details" TabIndex="300"
TemporaryFilterCaption="Filter Applied">
<EmptyMsg ComboAddMessage="No records found.
Try to change filter or modify parameters above to see records here."
NamedComboMessage="No records found as '{0}'.
Try to change filter or modify parameters above to see records here."
NamedComboAddMessage="No records found as '{0}'.
Try to change filter or modify parameters above to see records here."
FilteredMessage="No records found.
Try to change filter to see records here." FilteredAddMessage="No records
found.
Try to change filter to see records here." NamedFilteredMessage="No
records found as '{0}'.
Try to change filter to see records here." NamedFilteredAddMessage="No
records found as '{0}'.
Try to change filter to see records here." AnonFilteredMessage="No records
found.
Try to change filter to see records here." AnonFilteredAddMessage="No
records found.
Try to change filter to see records here."></EmptyMsg>
<Levels>
<px:PXGridLevel DataKeyNames="OrderType,OrderNbr,LineNbr"
DataMember="ImportInvoiceList">
<Columns>
<px:PXGridColumn DataField="OrderType">
</px:PXGridColumn>
<px:PXGridColumn DataField="OrderNbr">
</px:PXGridColumn>
<px:PXGridColumn DataField="OrderQty" TextAlign="Right" Width="100px">
</px:PXGridColumn></Columns>
</px:PXGridLevel>
</Levels>
<AutoSize Container="Window" Enabled="True" MinHeight="150" ></AutoSize>
</px:PXGrid>
</asp:Content>
Sample Screen:
Graph:
public class OrderInvoiceProcess : PXGraph<OrderInvoiceProcess>
{
#region Views
public PXCancel<ImportInvoiceFilter> Cancel;
public PXFilter<ImportInvoiceFilter> Filter;
[PXFilterable]
public PXFilteredProcessing<SOOrder, ImportInvoiceFilter> ImportInvoiceList;
public PXSelect<SOOrder, Where<SOOrder.customerRefNbr, Equal<Current<ImportInvoiceFilter.referenceID>>
>> SOOrders;
#endregion
public OrderInvoiceProcess()
{
ImportInvoiceList.SetProcessCaption("Process");
ImportInvoiceList.SetProcessVisible(false);
ImportInvoiceList.SetProcessAllCaption("Process ALL");
ImportInvoiceFilter currentFilter = this.Filter.Current;
ImportInvoiceList.SetProcessDelegate(
delegate (List<SOOrder> list)
{
ProcessOrders(list, currentFilter, true);
});
}
public IEnumerable importInvoiceList()
{
PXSelectBase<SOOrder> ImportOrderListBase = null;
ImportInvoiceFilter currentInquiryfilter = Filter.Current;
if (currentInquiryfilter != null && !string.IsNullOrEmpty(currentInquiryfilter.SelectTemplate))
{
switch (currentInquiryfilter.SelectTemplate)
{
case ImportInvoiceFilter.PrepareAndReleaseInvoice:
ImportOrderListBase = new PXSelectJoin<SOOrder, LeftJoin<SOOrderShipment, On<SOOrder.orderNbr,
Equal<SOOrderShipment.orderNbr>>>, Where2<Where<SOOrderShipment.confirmed, Equal<True>,
And<Where<SOOrderShipment.invoiceNbr, IsNull, And<SOOrder.customerRefNbr, Equal<Current<ImportInvoiceFilter.referenceID>>>>>>,
And<Where<SOOrder.orderType, Equal<salesOrderTypeRO>,
Or<SOOrder.orderType, Equal<salesOrderTypeCO>>>>>>(this);
return ImportOrderListBase.Select();
case ImportInvoiceFilter.PrintConsolidatedInvoice:
break;
}
}
return ImportOrderListBase.Select();
}
}
EDIT:
The other issue was that you were missing the base type attribute on the SelectAction field. You only had PXStringList:
[PXStringList(new string[] { PrepareAndReleaseInvoice, PrintConsolidatedInvoice },
new string[] { "Prepare and Release Invoice", "Print Consolidated Invoice" })]
PXStringList is not a base type so you should add the PXString attribute which is the base type:
[PXString(30, IsUnicode = true, InputMask = "")]
[PXStringList(new string[] { PrepareAndReleaseInvoice, PrintConsolidatedInvoice },
new string[] { "Prepare and Release Invoice", "Print Consolidated Invoice" })]
You can use your DAC filter field (selectAction) in the selector BQL query to filter the selector data based on your filter field:
[PXSelector(typeof(Search<SOOrder.orderNbr,
Where<Where2<Where<SOOrder.status, Equal<SOOrderStatus.open>, And<Current<SOImportFilter.selectAction>, Equal<SOImportFilter.createandConfirmShipment>>>,
Or<Where2<Where<SOOrder.status, Equal<SOOrderStatus.completed>>, And<Current<SOImportFilter.selectAction>, Equal<SOImportFilter.printInvoice>>>>>>>
In the above BQL request the logic of the where clause is equivalent to:
If (sales order status is open And select action is create and confirm shipment)
Or (sales order status is completed And select action is print invoice)
You can tweak it with your own rules.
For this filter to work you need to handle refresh behavior with CommitChanges and AutoRefresh properties on the ASPX controls.
You need CommitChanges set to true to send back the filter DAC modifications to the business layer as soon as the user change it:
// In a Grid
<px:PXGridColumn DataField="SelectAction" CommitChanges="True" />
// In a Form or in the RowTemplate of the Grid
<px:PXDropDown runat="server" ID="edSelectAction" DataField="SelectAction" CommitChanges="True" />
For the Sales Order selector you need AutoRefresh set to true so that the BQL query of the selector is executed every time the user opens the selector instead of using the stale values from cache:
// In a Grid RowTemplate element
<px:PXGridLevel DataMember="YourDataView"
<RowTemplate>
<px:PXSelector runat="server" ID="edSalesOrderSelector" DataField="SalesOrderSelector" AutoRefresh="True" />
</RowTemplate>
<Columns>
<px:PXGridColumn DataField="SalesOrderSelector" CommitChanges="True" />
</Columns>
</px:PXGridLevel>
// In a Form
<px:PXSelector runat="server" ID="edSalesOrderSelector" DataField="SalesOrderSelector" AutoRefresh="True" />
Related
I have a customization form that I need to fill “Transaction Period” and company’s “Financial Period” by defult from a date field and the selected branch but I can not make it work. I reviewed a couple Acumatica’s owen screens and I’m doing exctly the same (at least I think so) but these two fields are not filled by default. Any help appreciated. Here is my little Graph, partial DAC and Partial ASPX.
namespace MyCustom
}
// Graph
public class PMCashflowProjectionEntry : PXGraph<PMCashflowProjectionEntry, PMCashflowProjection>
{
[PXViewName("Projects Cashflow Projections")]
public PXSelect<PMCashflowProjection> CashflowProjections;
public PXSelect<PMCashflowProjectionSchedule, Where<PMCashflowProjectionSchedule.projectID, Equal<Current<PMCashflowProjection.projectID>>>> CashflowProjectionSchedules;
}
//Partial Header DAC
public class PMCashflowProjection : IBqlTable
{
#region BranchID
public abstract class branchID : PX.Data.BQL.BqlInt.Field<branchID> { }
protected Int32? _BranchID;
[Branch()]
[PXForeignReference(typeof(Field<branchID>.IsRelatedTo<Branch.branchID>))]
[PXUIField(DisplayName = "Branch", Visibility = PXUIVisibility.SelectorVisible, Required = true, Enabled = true, Visible = true)]
public virtual Int32? BranchID
{
get
{
return this._BranchID;
}
set
{
this._BranchID = value;
}
}
#endregion
}
//Partial Detail DAC
public class PMCashflowProjectionSchedule : IBqlTable
{
#region Date
public abstract class date : PX.Data.BQL.BqlDateTime.Field<date> { }
protected DateTime? _Date;
[PXDBDate()]
[PXDefault(typeof(AccessInfo.businessDate), PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "Date", Visibility = PXUIVisibility.SelectorVisible, Required = true, Enabled = true, Visible = true, IsReadOnly = false)]
public virtual DateTime? Date
{
get
{
return this._Date;
}
set
{
this._Date = value;
}
}
#endregion
#region TranPeriodID
public abstract class tranPeriodID : PX.Data.BQL.BqlString.Field<tranPeriodID> { }
protected String _TranPeriodID;
[PXDefault()]
[PeriodID(
searchType: null,
sourceType: typeof(date),
defaultType: null,
redefaultOnDateChanged: true)]
[PXUIField(DisplayName = "Tran. Period", Visibility = PXUIVisibility.SelectorVisible, Required = true, Enabled = true, Visible = true)]
public virtual String TranPeriodID
{
get
{
return this._TranPeriodID;
}
set
{
this._TranPeriodID = value;
}
}
#endregion
#region FinPeriodID
public abstract class finPeriodID : PX.Data.BQL.BqlString.Field<finPeriodID> { }
protected String _FinPeriodID;
[PXDefault()]
[FinPeriodID(
sourceType: typeof(date),
branchSourceType: typeof(PMCashflowProjection.branchID),
masterFinPeriodIDType: typeof(tranPeriodID),
headerMasterFinPeriodIDType: typeof(tranPeriodID),
redefaultOnDateChanged: true)]
[PXUIField(DisplayName = "Fin. Period", Visibility = PXUIVisibility.SelectorVisible, Required = true, Enabled = true, Visible = true)]
public virtual String FinPeriodID
{
get
{
return this._FinPeriodID;
}
set
{
this._FinPeriodID = value;
}
}
#endregion
}
}
Partial ASPX Example
//Form
<px:PXSegmentMask runat="server" ID="edBranchID" DataField="BranchID" CommitChanges="True" AutoRefresh="True" />
//Grid Clumns
<px:PXGridColumn DataField="Date" Width="80" CommitChanges="True" ></px:PXGridColumn>
<px:PXGridColumn DataField="TranPeriodID" Width="80" CommitChanges="True" ></px:PXGridColumn>
<px:PXGridColumn DataField="FinPeriodID" Width="80" CommitChanges="True" ></px:PXGridColumn>
// Grid Row Template
<px:PXDateTimeEdit runat="server" ID="edDate" DataField="Date" CommitChanges="True" AutoRefresh="True" ></px:PXDateTimeEdit>
<px:PXMaskEdit runat="server" ID="edTranPeriodID" DataField="TranPeriodID" CommitChanges="True" Size="s" ></px:PXMaskEdit>
<px:PXMaskEdit runat="server" ID="edFinPeriodID" DataField="FinPeriodID" CommitChanges="True" Size="s" ></px:PXMaskEdit>
The work of PeriodId attribute and its descendants looks kind of tricky, as they share their cache. Without doing this customization and debugging, the rule of a thumb is to mimic the declaration of multiple out-of-the box DACs using these periods. I see two differencies of this declaration from standard which might play a role:
FinPeriodId generally precedes the TranPeriodId declaration. It looks important because the source field used for the periodid defaulting comes from the specification for the attribute on the FinPeriodId field
In the sourceType declaration, the DAC name is generally specified. So consider using the following syntax:
[FinPeriodID(
sourceType: typeof(PMCashflowProjectionSchedule.date),
You could use PXDefault attribute to set a default value on page load and if you would like to allow the users to change the default value the field can be made as a Selector type with PXSelector attribute.
an example below for PXDefault attribute getting default value from the financial periods and current business date :
[PXUIField(DisplayName = "Fin. Period", Required = true)]
[FinPeriodIDFormatting()]
[PXDefault(typeof(SearchFor<MasterFinPeriod.finPeriodID>
.Where<MasterFinPeriod.endDate.IsGreaterEqual<AccessInfo.businessDate.FromCurrent>
.And<MasterFinPeriod.startDate.IsLessEqual<AccessInfo.businessDate.FromCurrent>>>),
PersistingCheck = PXPersistingCheck.Nothing)]
[PXSelector(typeof(SearchFor<MasterFinPeriod.finPeriodID>.In<SelectFrom<MasterFinPeriod>
.Where<MasterFinPeriod.endDate.IsLessEqual<AccessInfo.businessDate.FromCurrent>
.And<MasterFinPeriod.finPeriodID.IsNotNull>>>
.OrderBy<MasterFinPeriod.finPeriodID.Desc>>))]
FinPeriodIDFormatting() attribute formats to MM-YYYY
<px:PXSelector CommitChanges="True" runat="server" ID="edTranPeriodID" DataField="TranPeriodID" ></px:PXSelector>
<px:PXSelector CommitChanges="True" runat="server" ID="edFinPeriodID" DataField="FinPeriodID" ></px:PXSelector>
I want to display a GI on one of the tab in any screen.
For example, there is a new custom GI for OrderMargin which I want to display on SO screen on a new tab that will show the Order Margin for a particular order only.
OrderMargin is simple GI with SOOrder, SOLine and InventoryItem table joins and few columns required columns with margin calculations.
Can anyone suggest?
Let's say you've created a GI called SalesOrderMargin with 2 hidden parameters:
To embed this GI into the Sales Orders page, you should follow the steps below:
Declare new unbound field for SOOrder to return absolute URL for the SalesOrderMargin GI:
public class SOOrderExt : PXCacheExtension<SOOrder>
{
public abstract class marginGiUrl : IBqlField { }
[PXString]
[PXUIField(Visible = false)]
public string MarginGiUrl
{
get
{
if (string.IsNullOrEmpty(Base.OrderType) ||
string.IsNullOrEmpty(Base.OrderNbr)) return string.Empty;
string inqName = "SalesOrderMargin";
var url = new StringBuilder(PXGenericInqGrph.INQUIRY_URL)
.Append("?name=").Append(inqName)
.Append("&SOOrderType=").Append(Base.OrderType);
.Append("&SOOrderNbr=").Append(Base.OrderNbr);
.Append("&hidePageTitle=true");
return PX.Common.PXUrl.SiteUrlWithPath().TrimEnd('/') +
url.ToString().Remove(0, 1);
}
}
}
On the Sales Orders screen, add new tab with a PXSmartPanel container set up to render as an iframe:
<px:PXTabItem Text="Margins" >
<Template>
<px:PXSmartPanel runat="server" ID="panelMarginGI" RenderIFrame="True"
AutoSize-Enabled="true" SkinID="Frame" LoadOnDemand="true"/>
</Template>
</px:PXTabItem>
Place input control for the custom SOOrder unbound field declared in step 1 somewhere in the Sales Orders' top level PXFormView container (input control will always be hidden from the users and is only required to assign source URL for the PXSmartPanel):
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Width="100%"
DataMember="Document" Caption="Order Summary"...>
<Template>
...
<px:PXTextEdit ID="edMarginGiUrl" runat="server" DataField="MarginGiUrl" />
</Template>
</px:PXFormView>
In SO301000.aspx insert JavaScript code to assign source URL for the PXSmartPanel:
<script type="text/javascript" language="javascript">
function commandResult(ds, context) {
var commands = ["ReloadPage", "Save", "Cancel", "Insert", "First", "Previous", "Next", "Last"];
if (commands.indexOf(context.command) >= 0) {
var marginGiUrl = px_alls["edMarginGiUrl"];
var smartpanel = px_alls["panelMarginGI"];
if (marginGiUrl || smartpanel) {
var url = marginGiUrl.getValue();
smartpanel.setPageUrl(url);
smartpanel.repaint();
}
}
}
</script>
Subscribe to the CommandPerformed event of PXDataSource to invoke the commandResult JavaScript function:
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" TypeName="PX.Objects.SO.SOOrderEntry" PrimaryView="Document">
<ClientEvents CommandPerformed="commandResult" />
...
</px:PXDataSource>
And this is how your SalesOrderMargin GI should appear on the Sales Orders screen:
I have an attribute with the case number from another instance. I have to make it appear as a hyperlink so user can click on it and it can direct visit to that case.
Any suggestion.
It adds up the link to all row, but I need hyperlink only on Case Number attribute. (see below image).
Assuming you want the link inside a grid cell.
First make an action in your graph with it's primary DAC:
public PXAction<MyPrimaryDAC> viewCase;
Primary DAC can be found in the graph:
public class MyGraph : PXGraph<MyGraph, MyPrimaryDAC>
Make an event handler for the action in your graph to open the case:
[PXButton]
public virtual IEnumerable ViewCase(PXAdapter adapter)
{
// Assuming the case you want is already set as current
// Otherwise lookup case by ID if necessary
CRCase crCase = CRCases.Current as CRCase;
if (crCase != null && crCase.CaseID != null)
PXRedirectHelper.TryRedirect(this, crCase, PXRedirectHelper.WindowMode.NewWindow);
return adapter.Get();
}
Declare the action in the CallbackCommands of your ASPX page:
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
PrimaryView="MyDataView" TypeName="MyNamespace.MyGraph">
<CallbackCommands>
<px:PXDSCallbackCommand CommitChanges="True" Name="ViewCase" DependOnGrid="gridCase" Visible="False" />
</CallbackCommands>
</px:PXDataSource>
</asp:Content>
Finally use LinkCommand attribute on your grid field to bind the action:
<px:PXGridColumn DataField="MyField" LinkCommand="ViewCase" />
I have the need in one of my customization to show a popup directly after the user modifies the value of one of the controls (in this case, a custom field in the SOLine of the Sales Order Entry screen). This popup shows some additional values in a grid that the user must select before completing the row.
Using the standard process a SmartPanel was added to the screen.
If I call this from an action / PXLookupButton, the popup shows and the grid is populated correctly.
If I move this to either the "FieldUpdated" or "RowSelected" event, the smartpanel is displayed however the grid is always empty. Once more, if I then click on the button the grid stays empty till I cancel the modifications and re-enter using only the button.
I tried calling the action's press method in these events as well but the same result occurs.
Watching SQL profiler and the debugger events I can see that the BQL statement is being executed and returning the correct rows it's just not displaying in the smartpanel's grid.
Is it possible to handle this type of request? I'm assuming I need to either move this to a different method and/or pass some additional values but haven't found the right combination.
This holds true on Acumatica 5.3 / 6.1
Any input would be appreciated.
RowUpdated handler allowed me to achieve requested behavior and show SmartPanel after field value change.
Example below relies on custom unbound Trigger Dialog field declared for the SOLine DAC. When a user checks or uncheckes Trigger Dialog flag, the system will show Item Quantity dialog to update Quantity for selected SOLine record:
public class SOLineExt : PXCacheExtension<SOLine>
{
#region TriggerDialog
public abstract class triggerDialog : PX.Data.IBqlField
{
}
[PXBool]
[PXUIField(DisplayName = "Trigger Dialog")]
public virtual bool? TriggerDialog { get; set; }
#endregion
}
Very basic SmartPanel declaration in Aspx:
<px:PXSmartPanel runat="server" ID="CstSmartPanel2" Key="SOLineParam" Caption="Item Quantity" AutoRepaint="True"
CaptionVisible="True" AcceptButtonID="CstButton6" AutoReload="true" >
<px:PXFormView runat="server" ID="CstFormView3" DataMember="SOLineParam" SkinID="Transparent" >
<Template>
<px:PXLayoutRule runat="server" StartColumn="True" />
<px:PXNumberEdit runat="server" ID="CstPXNumberEdit10" DataField="OrderQty" />
</Template>
</px:PXFormView>
<px:PXLayoutRule runat="server" StartRow="True" />
<px:PXPanel runat="server" ID="CstPanel5" SkinID="Buttons">
<px:PXButton runat="server" ID="CstButton6" DialogResult="OK" CommandName="ChangeOk" CommandSourceID="ds" />
<px:PXButton runat="server" ID="CstButton7" DialogResult="Cancel" Text="Cancel" />
</px:PXPanel>
</px:PXSmartPanel>
Accomplished with the SOOrderEntry BLC extension subscribing to RowUpdated handler for the SOLine DAC to show Item Quantity dialog to a user:
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
[Serializable]
public class SOLineParams : IBqlTable
{
#region OrderQty
public abstract class orderQty : PX.Data.IBqlField
{
}
[PXDBDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Quantity")]
public virtual decimal? OrderQty { get; set; }
#endregion
}
public PXFilter<SOLineParams> SOLineParam;
public PXAction<SOOrder> ChangeOk;
[PXUIField(DisplayName = "OK")]
[PXButton(CommitChanges = true)]
protected void changeOk()
{
var lineParams = SOLineParam.Current;
Base.Transactions.Cache.SetValue<SOLine.orderQty>(Base.Transactions.Current, lineParams.OrderQty);
SOLineParam.Cache.Clear();
}
public void SOLine_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
if (!sender.ObjectsEqual<SOLineExt.triggerDialog>(e.Row, e.OldRow) && e.ExternalCall == true)
{
SOLineParam.AskExt();
}
}
}
Another part of the extension class is ChangeOk action invoked by SmartPanel to update Quantity for selected record in the Document Details grid. To hide ChangeOk action from screen toolbar, it's also necessary to add the following command into PXDataSource.CallbackCommands collection:
<px:PXDSCallbackCommand Name="ChangeOk" Visible="False" />
I am displaying few textboxes on my custom smartpanel. The text to display is obtained by clicking each row in the grid and showed on smartpanel.
However, the issue is whenever I click on first time any row, it displays correctly all text correctly but next time onwards it still shows the previous one and do not get refreshed.
Here is the code I am using-
public PXSelect<CRAcumaticaActivity,
Where<CRAcumaticaActivity.activityID, Equal<Current<CRAcumaticaActivity.activityID>>>> CurrentAcuViewActivity;
public PXAction<CRCase> acuViewActivity;
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.ArrowUp, CommitChanges = false)]
[PXUIField(DisplayName = "View Activity", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable AcuViewActivity(PXAdapter adapter)
{
CurrentAcuViewActivity.AskExt();
return adapter.Get();
}
Here is the smartpanel aspx code-
<px:PXSmartPanel ID="pnlAcuViewActivity" runat="server" Style="z-index: 108;"
Caption="Acumatica Activity" CaptionVisible="True" LoadOnDemand="true"
ShowAfterLoad="true" AutoCallBack-Command="Refresh" Key="CurrentAcuViewActivity"
AutoCallBack-Target="frmAcuViewActivity" DesignView="Content"
AcceptButtonID="PXButtonOK" CancelButtonID="PXButtonOK">
<px:PXFormView ID="frmAcuViewActivity" runat="server" DataSourceID="ds" DataMember="CurrentAcuViewActivity"
Style="z-index: 100"
Caption="Acumatica Activity" CaptionVisible="False"
SkinID="Transparent" TabIndex="17100">
<Template>
<px:PXLayoutRule runat="server" StartRow="True">
</px:PXLayoutRule>
<px:PXTextEdit ID="edSummary" runat="server" DataField="Summary" Enabled="false">
</px:PXTextEdit>
<px:PXRichTextEdit ID="edDescription" runat="server" DataField="Description" Height="200px" Width="500px">
</px:PXRichTextEdit>
</Template>
</px:PXFormView>
<px:PXPanel ID="PXPanel1" runat="server" SkinID="Buttons">
<px:PXButton ID="pxBtnOK" runat="server" DialogResult="OK" Text="Close" />
</px:PXPanel>
</px:PXSmartPanel>
Is there anything I am missing. Please suggest.
For your smartpanel, why do you have:
ShowAfterLoad,
AutoCallBack-*, and
AcceptButtonID/CancelButtonID set to same button?
ShowAfterLoad property controls the display during loading of the panel. AutoCallBack properties apply to any callback generated by controls on the panel
I suggest to have your smartpanel declared as follows: Note, AutoRepaint property which forces the panel to repaint itself everytime it opens.
<px:PXSmartPanel ID="pnlAcuViewActivity" runat="server" Style="z-index: 108;"
Caption="Acumatica Activity" CaptionVisible="True" LoadOnDemand="true"
Key="CurrentAcuViewActivity"
AcceptButtonID="PXButtonOK"
AutoRepaint="true">
The other thing I can think of is you should ensure not to use the same data view in more than one container.
To refresh data in a SmartPanel you should use AskExt(PXView.InitializePanel initializeHandler, bool refreshRequired);
the code will look like this:
if (CurrentAcuViewActivity.AskExt(
(graph, view) =>
{
CurrentAcuViewActivity.Cache.ClearQueryCache();
CurrentAcuViewActivity.View.Clear();
CurrentAcuViewActivityCache.Clear();
}
, true) != WebDialogResult.OK)
return adapter.Get();
Did you set the grid's SyncPosition = true?
The SyncPosition property of a grid enables setting the Current
property of the cache object to each row selected by the user in the
grid. This property is required for syncing the lookup lists with the
currently selected row in the grid, if the data displayed in the
lookup depends on the selected row.
If still not working just try clearing the cache of the related view for every select using a delegate.
NOT TESTED
public PXSelect<CRAcumaticaActivity,
Where<CRAcumaticaActivity.activityID, Equal<Current<CRAcumaticaActivity.activityID>>>> CurrentAcuViewActivity;
protected virtual IEnumerable currentAcuViewActivity()
{
CurrentAcuViewActivity.Cache.Clear();
return CurrentAcuViewActivity.Select();
}