Hide a PXButton on a popup screen - acumatica

I am trying to hide a PXButton on a popup screen
Here is my code:
protected void _(Events.RowSelected<POReceipt> e)
{
if (e.Row is null) return;
ActionMoveAll.SetEnabled(e.Row.ReceiptType == POReceiptType.TransferReceipt);
ActionMoveAll.SetVisible(e.Row.ReceiptType == POReceiptType.TransferReceipt);
}
<px:PXButton runat="server" ID="btnfillwithall" CommandName="actionMoveAll" CommandSourceID="ds" />
I have set AutoRepaint="true" and autoreload="true" and loadOnDemand="true" all to no luck. When the PXButton hits the server I do get a popup saying "the FillWithAll action is disabled", but I would like for it just to be removed entirely from the popup instead of just getting an error response.

You should not do ActionMoveAll.SetVisible() in the primary DAC RowSelected event handler _(Events.RowSelected<POReceipt> e). You should move ActionMoveAll.SetVisible(e.Row.ReceiptType == POReceiptType.TransferReceipt) to your popup window DAC RowSelected event handler. In your case it might be like _(Events.RowSelected<POReceiptLineAllocation> e)
Add SyncVisible="" to your PXButton as well. Set it to True (or False if True doesn't work, and check the result. One setting should work)

Related

How do I force user input to commit and save automatically when executing an action?

I have a custom graph, in this case called MyGraph. The page contains a Form Tab in a similar fashion to the Stocked Items page in which the header is a few fields of my DAC (MyDAC), and a form on the 1st tab is a form of my additional fields. The views, for the sake of discussion, are MyView and MyCurrentView.
On the Stocked Items page, I can set a value in the ItemSettings view (General Settings tab) and then execute an action which also happens to save my user input. In my custom page, the user input of the similar "MyCurrentView" tab is lost when I execute an action. I have reviewed the training material once again for T230 Actions, but I cannot seem to overcome this problem. The code sample below shows 2 simplified methods of how I execute the action "ConvertIt". In both cases during a Debug, both myDAC and myDAC2 contain the stale data, indicating that the view was not updated as expected per CommitChanges in the Button attribute and in the DataSource Callback Command. The user input that is not saved is entered via a field presented to the UI only in MyCurrentView.
The T230 training guide indicates that I should set the AutoCallBack Behavior in the action bar, which appears to be possible for a grid, but not for a form. The example from the training guide is:
<ActionBar>
<CustomItems>
<px:PXToolBarButton Text="Complete">
<AutoCallBack Command="Complete" Target="ds">
<Behavior CommitChanges="True" ></Behavior>
</AutoCallBack>
</px:PXToolBarButton>
</CustomItems>
</ActionBar>
Since I am hanging my action off the Action menu via action.AddMenuAction(convertIt);, I do not seem to have a way to specify the behavior as described in the training guide.
Views Defined
public PXSelect<MyDAC> MyView;
public PXSelect<MyDAC, Where<MyDAC.tagID, Equal<Current<MyDAC.tagID>>>> MyCurrentView;
Action Defined - Method 1
#region convertIt Action
public PXAction<MyDAC> convertIt;
[PXUIField(DisplayName = "My DAC Label", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
[PXButton(CommitChanges = true)]
public virtual void ConvertIt()
{
this.Save.Press(); // Seems to make no difference in saving the unsaved user entry
MyDAC myDAC = MyView.Current;
MyDAC myDAC2 = MyCurrentView.Current;
** DO THE WORK OF THE ACTION HERE **
}
#endregion
Action Defined - Method 2
#region convertIt Action
public PXAction<MyDAC> convertIt;
[PXUIField(DisplayName = "My DAC Label", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
[PXButton(CommitChanges = true)]
public virtual IEnumerable ConvertIt(PXAdapter adapter)
{
MyDAC myDAC = MyView.Current;
MyDAC myDAC2 = MyCurrentView.Current;
** DO THE WORK OF THE ACTION HERE **
return adapter.Get();
}
#endregion
ASPX Datasource Defined
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
TypeName="MyGraph"
PrimaryView="MyView">
<CallbackCommands>
<px:PXDSCallbackCommand CommitChanges="True" Name="ConvertIt" ></px:PXDSCallbackCommand>
</CallbackCommands>
</px:PXDataSource>
In short, user input is lost when I complete my action. I have tried including this.Save.Press() at the beginning of my action, but I already save at the end of my action. Regardless, a Debug does not show my user entered values in the view, although I expected the commit changes on the button and in the data source to commit those changes from the client before proceeding with the action.
What have I left out of the C# code or ASPX page definition that is preventing my UI updates to be applied? Interestingly enough, UI changes in the MyView view ARE applied, but not changes in MyCurrentView unless I literally press the save button manually before selecting the action from the menu.
I ran into this problem recently as well. It’s easy to force the page to post back to server when opening a smart panel off of an action, but if there is no panel opening how do you force a post of data that was changed in fields that don’t commit on update?
The only way I’ve found to accomplish this is by editing the ASPX and adding StartNewGroup="true" and CommitChanges="true" to the PXDSCallbackCommand for the Action Folder that the action is added to.
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
TypeName="MyGraph"
PrimaryView="MyView">
<CallbackCommands>
<px:PXDSCallbackCommand CommitChanges="True" Name="ActionFolder" StartNewGroup="True" />
</CallbackCommands>
</px:PXDataSource>
For the action, you should use the second method.
public PXAction<MyDAC> convertIt;
[PXUIField(DisplayName = "My DAC Label", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
[PXButton(CommitChanges = true)]
public virtual IEnumerable ConvertIt(PXAdapter adapter)
{
MyDAC myDAC = MyView.Current;
MyDAC myDAC2 = MyCurrentView.Current;
**DO THE WORK OF THE ACTION HERE **
return adapter.Get();
}
public MyGraph()
{
actionFolder.AddMenuAction(convertIt);
}
It is not possible to save the focused field value. Value is saved when the control lose focus. However when the focus goes from an uncommitted field to an action button (clicked by user) the current field value is lost. Not sure this is the issue here but keep in mind that the user has to tab out of a control editor with uncommitted value before clicking on an action button or else the value is lost.

How to enable a hyperlink in the form text control?

I have a requirement to accept an URL on a text box and enable hyperlink on the control. Grid columns are allowing to enter a value and mark the column as hyperlink where it is not allowing to do on an editable text control. Is there a way to open the URL by clicking on the text control?
I have examined the Web entry control in Business account aspx source code and used PXLinkEdit Control for accepting the URL and allow to open the page. Even though it is not hyperlinking the text, it allows opening the URL through an action button, which is part of the control
<px:PXLinkEdit ID="edURL" runat="server" DataField="UsrURL" CommitChanges="True" />
Similarly, you could try a PXButton with optional ImageKey and navigate to your URL using Redirect4: (or Redirect0: if the URL is in same domain):
public PXAction<DAC> ViewOnWeb;
[PXUIField(DisplayName = "View On Web",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.World)]
protected virtual IEnumerable viewOnWeb;(PXAdapter adapter)
{
if (this.DAC.Current != null)
{
throw new PXException("Redirect4:" +
string.Format("http://my.site.com/search?Id={0}", DAC.code));
}
return adapter.Get();
}

How do I start a button in the disabled state on a Smart Panel?

I want to pop up a smart panel that forces input before the OK button can be pressed. I've tried setting the button itself to disabled, linking it to the BLC through a PXButton declaration and setting it to disabled there, and setting the PXUIField Enabled = false on the PXAction/PXButton declaration in the BLC, but none of it works. Every time the option popup opens, the OK button starts enabled. Here are my code segments:
ASPX:
<px:PXButton Enabled="False" AlignLeft="False" runat="server" ID="CstButton13" Text="OK" CommandSourceID="ds" CommandName="DialogOptionPopupOk" DialogResult="OK"></px:PXButton>
PXAction Declaration:
public PXAction<PMProject> dialogOptionPopupOk;
[PXUIField(DisplayName = "OK", Enabled = false)]
[PXButton]
public virtual void DialogOptionPopupOk()
{ //No logic needed, only here to handle enable/disable of option popup ok button
}
Popup DAC Row Selected:
protected void OptionPopup_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
dialogOptionPopupOk.SetEnabled(false);
}
Popup when opened:
You could add a new unbound Field of type PXBool. (EX. :IsButtonVisible )
Then you could use the Statecolumn property and the DependOnGrid property on the PXButton(ASPX):
.................
<px:PXPanel runat="server" SkinID="Buttons" ID="CstPanel11">
<px:PXButton runat="server" Text="Add" CommandName="AddRows" DialogResult="OK" CommandSourceID="ds" ID="CstButton12" DependOnGrid="CstPXGrid14" StateColumn="IsButtonVisible" ></px:PXButton>
<px:PXButton runat="server" DialogResult="Cancel" Text="Cancel" ID="CstButton13" ></px:PXButton>
</px:PXPanel>
...............
Then on your code you can modfiy this new unbound field value depending on your conditions and at the moment(event handler) you need to change.
Please find more information about these changes here on this stackoverflow article:
Is there any event triggered when highlighting a row?

Showing smartpanel after field value changes - grid remains empty

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" />

Apache Pivot: Swapping pane visibility

I'm having a problem hiding one pane and showing another in my Apache Pivot app. In my BXML file I have two BoxPanes in a window. Pane 1 starts visible and pane 2 starts hidden:
<BoxPane bxml:id="pane1" orientation="vertical" styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
<Label text="Pane 1"/>
<PushButton bxml:id="startButton" buttonData="Start"/>
</BoxPane>
<BoxPane bxml:id="pane2" orientation="vertical" visible="false" styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
<Label text="Pane 2"/>
</BoxPane>
And I have a listener added to the button that should make pane 1 hidden and pane 2 visible:
#BXML private PushButton startButton = null;
#BXML private BoxPane pane1 = null;
#BXML private BoxPane pane2 = null;
#Override
public void initialize(Map<String, Object> namespace, URL location, Resources resources)
{
startButton.getButtonPressListeners().add(new ButtonPressListener()
{
#Override
public void buttonPressed(Button button)
{
start();
}
});
}
private void start()
{
pane1.setVisible(false);
pane2.setVisible(true);
}
When I click the button though, pane 1 is hidden and pane 2 never shows up. Same thing happens when I reverse the order of the statements in start().
Interestingly enough, when I comment out pane1.setVisible(false), then pane 2 does show up when I click the button.
This is my first Pivot app, so maybe there's some fancy container that does what I want to do in a better way, but I'd still like to know what is going on here. What I'm trying to do seems pretty simple, and I'm sort of baffled why it doesn't work.
You might want to try using a CardPane to switch between your two views. The tutorial on that is here: http://pivot.apache.org/tutorials/card-panes.html
The basic idea is to have the CardPane "host" your two BoxPanes, something like this:
<CardPane bxml:id="cardPane">
<BoxPane bxml:id="pane1" ...>
<Label text="Pane 1"/>
...
</BoxPane>
<BoxPane bxml:id="pane2" ...>
<Label text="Pane 2"/>
</BoxPane>
</CardPane>
Make both BoxPanes visible. Then when you want to change between them, use cardPane.setSelectedIndex(...);

Resources