I've added one button in Case page to try to redirect to external site and passing out CASEID, this is the button generated:
<px:PXButton runat="server" ID="CstButton1" Text="Send CASE" Target="_blank" NavigateUrl="http://mycase.com/load.htm?caseid=#####" />
but where/how should I modify BLC to get current CaseID and modify the URL?
This should be done in a graph extension using something like the following:
public PXAction<MyPrimaryDac> OpenCaseButton;
[PXUIField(DisplayName = "View Ext Case")]
[PXButton]
protected virtual void openCaseButton()
{
string myCaseNbr = "123";
throw new PXRedirectToUrlException(
string.Format("http://mycase.com/load.htm?caseid={0}", myCaseNbr),
PXBaseRedirectException.WindowMode.NewWindow,
"");
}
The graph extension code example above will add a button to the page (no need to add a button on the page). Most likely you will want to add your button within the standard page's action menu buttons. I think the Acumatica training material covers this (T100,T200,T300). View the Acumatica source to find examples using PXButtons (or other button attributes).
Related
I have added a Global Button with the following code.
public override void Initialize()
{
if (!String.IsNullOrEmpty(Base.PrimaryView))
{
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
PXAction action = PXNamedAction.AddAction(Base, primaryViewItemType, "SubmitTicket", "Submit Ticket", TestClick);
}
}
public IEnumerable TestClick(PXAdapter adapter)
{
throw new PXException("Button clicked from graph" + Base.GetType().Name);
}
And it renders the button like this in each of the pages.
Now, I would like to display a popup panel, on button's click. I know I can create a popup panel on screen section. But, is there some way that I can have a general popup panel created in one place and can be displayed on each of the pages on the button's click?
Thank you.
As #HB_ACUMATICA mentioned there is no good easy way.
Providing another alternative to his post, you can create a graph and use it as a reusable popup by calling:
throw new PXPopupRedirectException(graph, string.Empty, true)
One thing I ran into was a sizing issue on the popup...
Changing the height/width when calling another graph as an in-page popup using PXPopupRedirectException
If you do copy and paste the PXSmartPanel you can create re-usable business logic by implementing the reusable business logic pattern found in this help as a starting point:
Reusing Business Logic
If I understand correctly you want to share the same PXSmartPanel control in different pages without having to copy/paste it in every screen.
In Acumatica Framework this is achieve by custom container controls like 'PXUploadDialog' which derives functionality from other controls like 'PXSmartPanel'. This is the control that is used when you attach files in all screen.
Unfortunately there seems to be no documentation on how to achieve this.
The closest I found is this SO question which is essentially unanswered:
Create custom User Control for Acumatica
Considering this, you may want to copy/paste the same smart panel in all screen.
To ease copying you can use the 'Edit ASPX' feature, make sure you backup the project before.
Edit ASPX to get to the code:
Copy paste your smart panel in the page and click 'GENERATE CUSTOMIZATION SCRIPT' to package the changes in the project:
I have created a new CREATE QUOTE button on Requisition screen that replace the standard button which located at Action menu. After trying to hide it on RQRequisition_RowSelected event, the button still appear and able to click when the requisition is on Pending Quote Status. Kindly need advice how to hide it.
Customized Requisition Screen
To hide or show an action button, you should redefine the Visible parameter of the PXUIField attribute for the button.
You can change attributes of an action button by using one of the following approaches:
Dynamically at run time, in the Initialize() method of the graph
extension
Statically, by overriding the action attributes in the
graph extension
To Hide an Action Button at Run Time
In the graph extension, add the following code.
public override void Initialize()
{
base.Initialize();
Base.MyAction.SetVisible(false);
}
In the added code, replace MyAction with the action name.
To Hide or Show an Action Button Statically
To override action attributes in a graph extension statically, you should declare both the graph member of the PXAction type and the delegate. You should attach a new set of attributes to the action delegate, declared within the graph extension. Also, you need to invoke the Press() method on the base graph action. Having redeclared the member of PXAction, you prevent the action delegate execution from infinite loops.
Explore the original action declaration and copy the declaration to the graph extension.
In the action declaration, set to false the Visible parameter of the PXUIField attribute, as the following code snippet shows.
...
[PXUIField(…, Visible = false)]
...
Replace the action delegate with the following code template.
public virtual IEnumerable myAction(PXAdapter adapter)
{
return Base.MyAction.Press(adapter);
}
In the code template, replace myAction and MyAction with the appropriate names.
In the template, redefine the action delegate arguments and return type according to the signature of the base action delegate.
If you have a customization that replaces an original action
declaration statically, after upgrading Acumatica ERP to a new
version, a new functionality of the same action may became
unavailable.
Also, if a callback command for the button is declared in the PXDataSource control, you can hide the button by customizing the ASPX code. To do this, in the Layout Editor, expand the PXDataSource control, select the appropriate PXDSCallbackCommand element, and set to False the Visible property of the element.
CREATE QUOTE button on the Requisition screen is implemented like a normal action in the RQRequisitionEntry BLC:
public class RQRequisitionEntry : PXGraph<RQRequisitionEntry>
{
...
public PXAction<RQRequisition> createQTOrder;
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
[PXUIField(DisplayName = Messages.CreateQuotation)]
public virtual IEnumerable CreateQTOrder(PXAdapter adapter)
{
...
}
...
}
However, CREATE QUOTE button is added into the Actions drop down via Automation Steps:
With that said, the best way to customize the CREATE QUOTE button is by re-declaring the action within the RQRequisitionEntry BLC extension following sample below. I would be happy to come up with a more specific sample, if you provide additional details regarding your request.
public class RQRequisitionEntryExt : PXGraphExtension<RQRequisitionEntry>
{
public PXAction<RQRequisition> createQTOrder;
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
[PXUIField(DisplayName = RQ.Messages.CreateQuotation)]
public virtual IEnumerable CreateQTOrder(PXAdapter adapter)
{
return Base.createQTOrder.Press(adapter);
}
}
We have a need to play a sound file on grid cell, for this we have used the below control <audio> similar to how the default Acumatica used in some of the screens for Barcode scanning, etc. We did the same, but when we register the script and control code is changing to <PXControl> and the methods for Play etc., are not not accessible. This is happening only when we try to insert this audio control inside a customization package. On the ASPX all the functionality works fine.
Before Generating Script in the package
<audio id="audiobeep" preload="auto" src="http://www.soundjay.com/button/beep-07.wav" style="visibility: hidden" />
After Generating Script in the package
<px:Control runat="server" ID="audiobeep" />
As “audio” tag is converting into “px: control” tag, it doesn’t support properties like as Preload, Src, Style.
Can you please guide us on this approach?
When using the Aspx Editor with the "Generate Customization Script" button, the only supported way to embed arbitrary HTML tags like <audio> is to use the PXLiteral control. Here's an example of how you would use the PXLiteral control if typing directly into the Aspx Editor:
<px:PXLiteral runat="server" Text="<h1>Test!</h1>" />
Once the script has been generated, it becomes possible to edit the properties of the control from the layout editor.
For this specific scenario, I would suggest a slightly different approach, involving only the use of JavaScript code connected to the PXDataSource control. The first step is creating a PXAction in your graph that will be invoked when you click on your button:
public PXAction<Customer> test;
[PXUIField(DisplayName = "Test", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select, Enabled = false)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.Process)]
public virtual IEnumerable Test(PXAdapter adapter)
{
//TODO: Do something useful
return adapter.Get();
}
For simplicity, let's assume that you're ok having the button in the main screen toolbar - but you could also map it to a PXButton control somewhere on your page.
Then, using the layout editor, we're going to add a JavaScript control by dragging it to the form.
After the JavaScript control has been added, head over to the properties section and set the script. The script needs to be set as a single-line, but for readability here's a nicely formatted version of the script we're going to use:
function commandResult(ds, context)
{
if (context.command == 'Test') // Test is the name of the PXAction we created earlier
{
var audio = new Audio('../../Sounds/Ding.wav');
audio.play();
}
}
Note: The Ding.wav file is shipped with Acumatica, but you are free to use a sound from another URL, or ship one with your customization. If using an external URL, make sure to use the right protocol, HTTP/HTTPS.
The last step is hooking the data source to your JavaScript function. To do that, click on the DataSource section of the layout editor, open the Client Events group from the property editor, and set the CommandPerformed event to commandResult which is the name of the JavaScript function we created.
After publishing, you'll see the Test button in the toolbar of the form. If you click on it, you'll hear a nice ding!
The sound will be played unconditionally, no matter what happens in your PXAction delegate. If you wanted to play the sound under specific conditions only, one way to achieve that would be to read the content of a field on the screen that is set by your delegate, similar to what is done in the IN305000 page:
var description = px_alls["edDescriptionPnl"];
if (description != null && description.getValue() != null)
{
var audio = new Audio('../../Sounds/Ding.wav');
audio.play();
}
I have a user field which displays the ARRegister.RefNbr. This user field is contained in the APTran grid. The user actually creates an AR invoice with a custom action, and the new AR document ref nbr is saved to the APTran grid. I wish to craft the user field as a hyperlink (similar to the inventory receipt reference number, in the SO shipment order tab). Should I use a PXSelector control? What are the proper attributes? The goal is to open the AR invoice screen, when the user click on the user field.
There is a generic approach that allows you to add links to the grid cells and isn't based on selectors or anything else. To implement it you have to do the following steps:
1.Define an action in your graph that handles redirects. Something like this:
public PXAction<YourMainDAC> ViewInvoice;
[PXButton]
protected virtual void viewInvoice()
{
ARTran row = Transactions.Current;
string docType = //get Doc Type from the tran record
string refNbr = //get Ref Nbr from the tran record
ARInvoice invoice = PXSelect<ARInvoice,
Where<ARInvoice.docType, Equal<Required<ARInvoice.docType>>,
And<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>>>>
.Select(this, row.YourDocTypeField, row.YourRefNbrField);
// Create the instance of the destination graph
ARInvoiceEntry graph = PXGraph.CreateInstance<ARInvoiceEntry>();
graph.Document.Current = invoice;
// If the invoice is found, throw an exception to open
// a new window (tab) in the browser
if (graph.Document.Current != null)
{
throw new PXRedirectRequiredException(graph, true, "AR Invoice");
}
}
2.In the .aspx page definition add a callback command that corresponds to the new action (substitute grid with the ID of the ARTrans grid on your page):
<px:PXDataSource ID="ds" ... >
<CallbackCommands>
<px:PXDSCallbackCommand Name="ViewInvoice"
Visible="False"
DependOnGrid="grid">
</px:PXDSCallbackCommand>
</CallbackCommands>
</px:PXDataSource>
3.In the grid column where you want to add a link specify link command to point to the above PXDSCallbackCommand:
<px:PXGridColumn DataField="InvoiceNbrOrSomething"
LinkCommand="ViewInvoice">
</px:PXGridColumn>
This is a bit lengthy way of defining a link but, first, it does not impose any constraints on the field where you add a link and it also gives you full control over which graph to open and what to show there.
Note: you may also need to set SyncPosition="true" on the grid control in the aspx.
The example is adapted from the Example 3.4 in the Acumatica T200 training guide. You may want to check it out for some thorough explanations and more info.
If you have a selector linked to a standard Acumatica table such as adding a custom field that contains a selector against InventoryItem or ARInvoice you can set the AllowEdit=True on your field in the page containing your custom field. This will automatically add the hyperlink. If your field does not contain the selector it will not work unless maybe setup for segments.
We have custom tables we added to our project where we wanted hyperlinks. As long as you add the PXPrimaryGraph attribute on your DAC you should be able to do the same for a complete custom page/dac.
We started off using the LinkCommand but the AllowEdit approach keeps the code simple without the need for custom logic to support the link. More complex logic than going to the fields primary graph would require a linkcommand.
I have a user control in the code behind and I get SPListItem (which is a specific item from one SharePoint list). And I need place on my user control buttons to manage this item (edit and delete). Can I use any patterns, which repeat behaviour of standard SharePoint list command (edit in modal dialog, delete with prompt?)
By example, I can add in ascx file html code:
<img src="/_layouts/images/fgimg.png" alt="" style="left:-0px !important;top:-128px !important;position:absolute;" /></span>
<a class="ms-addnew" id="idHomePageNewItem" href=".../_layouts/listform.aspx?PageType=8&ListId={03C30976-7C6C-4815-8EB2-2793A97D2EC}&RootFolder="
onclick="javascript:NewItem2(event, ".../_layouts/listform.aspx?PageType=8&ListId={03C30976-7C6C-4815-8EB2-72793A97D2EC}&RootFolder=");javascript:return false;"
target="_self">Add Item</a>
And this link work same as link button in standart sharepoint list view.
And I need add also "Delete Item" link and "Edit Item" link. (I know ItemID, list GUID and etc).
You can add the "delete" functionality by just adding the code for deletion in the code behind of the control, so this shouldn't be an issue.
To retrieve the url for the edit form you can use following code:
/// <summary>
/// Gets the edit form URL of the current item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
public static string GetEditFormUrl(SPListItem item)
{
return string.Format("{0}/{1}?id={2}&ContentTypeID={3}", item.Web.Url, item.ParentList.Forms[PAGETYPE.PAGE_EDITFORM].Url, item.ID, item.ContentTypeId);
}
This allows you to navigate to the edit form. If you want it to display in a popup you can use the "SP.UI.ModalDialog.showModalDialog" functionality.