I've been able to disable the insert and delete buttons on the Employee Timecards screem (EP406000) - but the update button doesn't seem to care. Here's my code:
protected void TimecardFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
Base.create.SetEnabled(false);
Base.update.SetEnabled(false);
Base.delete.SetEnabled(false);
}
It works for the insert and delete - but not for the update. I noticed in the source code that the code for the update button is a little different in that it doesn't have a [PXUIField] attribute, along with a few others. The insert and delete buttons have a similar setup and attributes, but update is definitely different. Not sure if this is why.
Bottom line: How can I disable the update button on the Employee Timecard (EP406000) screen?
Your diagnostic that the Update action is missing the PXUIField attribute is spot on.
Some button properties functionality requires having a PXUIField attribute.:
You can redefine the Update action to add the PXUIField attribute:
using PX.Data;
namespace PX.Objects.EP
{
public class TimecardPrimary_Extension : PXGraphExtension<TimecardPrimary>
{
public PXAction<TimecardPrimary.TimecardFilter> update;
[PXButton(Tooltip = Messages.EditTimecardToolTip, ImageKey = PX.Web.UI.Sprite.Main.RecordEdit)]
[PXUIField]
protected virtual void Update()
{
EPTimeCard row = PXSelect<EPTimeCard, Where<EPTimeCard.timeCardCD, Equal<Current<TimecardWithTotals.timeCardCD>>>>.Select(Base);
if (row == null) return;
PXRedirectHelper.TryRedirect(Base, row, PXRedirectHelper.WindowMode.InlineWindow);
}
protected void TimecardFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
Base.create.SetEnabled(false);
Base.update.SetEnabled(false);
Base.delete.SetEnabled(false);
}
}
}
Adding the PXUIField attribute will make the SetEnabled method work:
If you double-click on a grid record it will invoke the Grid default action (update in this case).
When double-clicking the record it will notify the user that the action is disabled:
To prevent invoking a disabled default action, you can customize the grid action bar to remove the default action:
Related
I would like to add a custom action to the Bills and Adjustments (AP301000) screen which navigates to a report. I want to add the action to the special folder in acumatica (action menu) as shown on screenshot 1 where the red line is.
Screenshot 1: Action Menu
Below code is used to add the action to the menu
public class APInvoiceEntry_Extension : PXGraphExtension<PX.Objects.AP.APInvoiceEntry>
{
public override void Initialize()
{
base.Initialize();
//this added the report to the reports menu
Base.report.AddMenuAction(SupplierInvoice);
}
public PXAction<PX.Objects.AP.APInvoice> SupplierInvoice;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Supplier Invoice")]
protected void supplierInvoice()
{
if (Base.Document.Current.RefNbr != string.Empty)
{
//create parameters for report! Check report by editing it to see what reports are needed
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["RefNbr"] = Base.Document.Current.RefNbr.ToString();
parameters["DocType"] = Base.Document.Current.DocType;
//the report number gets set below and parameters are sent with
throw new PXReportRequiredException(parameters, "AP641500");
}
}
}
}
The error which I get is shown in below screenshot
Screenshot 2: Code error
The issue I encountered is that the report folder for the Bills and Adjustments (AP301000) screen in the screen editor of the customization does not the Layout Properties as shown in the screenshot below:
Screenshot 3: Bill and Adjustments (AP301000) Screen Editor
The Acumatica Version I am currently using is: 22.101.0085
How could I possibly fix the error in order to add the action in the action menu of the screen?
You can apply a Category to the action that should position it correctly in the category:
public override void Initialize()
{
base.Initialize();
SupplierInvoice.SetCategory("Reports");
}
I want to remove different menu options available such as Add Note, Add Phone Call, Add Work Item, etc. from Add Activity menu on Activities tab on Case screen and add it directly on the toolbar instead of it showing in dropdown.
I know I can add menu option under Actions using below command but not sure how to remove those options including the top level menu. Probably just removing from ASPX code?
Base.action.AddMenuAction()
You can refer below code snippet.
using System;
using PX.Data;
using PX.Objects.CR;
namespace PXDemoPkg
{
public class CRCaseMaintPXDemoExt : PXGraphExtension<CRCaseMaint>
{
public override void Initialize()
{
if (Base.Actions.Contains("NewActivity"))
{
PXButtonState actionsMenuState = Base.Actions["NewActivity"].GetState(null) as PXButtonState;
if (actionsMenuState != null)
{
foreach (ButtonMenu button in actionsMenuState.Menus)
{
button.Visible = false;
}
actionsMenuState.Visible = false;
}
}
}
}
}
I would like to override the standard method of the RowSelected event on the Service Orders screen. Specifically, the DocDesc field gets populated when you select a row item for the Labor tab. It will set the TranDesc to the DocDesc and I would like to keep this from happening. I am using Acumatica 6.1 which means that the Service Management Module is not standard in Acumatica during this time. I would like the method that populates this field to not run when the labor line is populated, so the DocDesc field would remain null or blank, this way the user can input their own description.
You should be able to customize the ServiceOrderEntry graph like any other graph :
protected virtual void FSServiceOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected bs)
{
...
}
See https://help.acumatica.com/(W(3))/Main?ScreenId=ShowWiki&pageid=4a05d4c2-cd8b-4131-bf3b-d05861de3ae6
You could override the method if it is virtual, like this :
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
...
baseMethod();
...
}
See https://help.acumatica.com/(W(3))/Main?ScreenId=ShowWiki&pageid=635c830e-4617-4d5c-9fa5-035952311aa9
You could also modify the base customization, but since you are not the owner it could get difficult to maintain and track the changes.
I created a ListView to show the list of documents, then created a button "Button A" to do some actions, my requirement is I would like the button status may be changed with the selected document changes.
Fox example: there are three documents in the following graphic, I want the button is enabled when I click Order-00001 or Order-00002, and it is disabled for Order-00003 due to no money in it.
I appreciate if you could give me a hint if there is any event to be raised when I click a row. Thanks a lot.
To reduce callback to the server there isn't a row selected event. Instead there is PXToolbarButton StateColumn property to control the button enabled state.
When you declare your button, you specify a Boolean DAC field that will enable/disable the button based on it's value. Note that the button needs the DependOnGrid property set to the ID of the grid to get the selected row:
<px:PXToolBarButton Text="Button A" DependOnGrid="grid" StateColumn="IsButtonVisible">
IsButtonVisible is a custom unbound Boolean DAC field (you may choose any name you want except isSelected/Selected which is reserved for checkbox):
#region IsButtonVisible
public abstract class isButtonVisible : IBqlField
{
}
protected bool? _IsButtonVisible;
[PXBool]
[PXUIField(DisplayName = "Is Button Visible", Enabled = false, Visible = false)]
public virtual bool? IsButtonVisible
{
get
{
return _IsButtonVisible;
}
set
{
_IsButtonVisible = value;
}
}
#endregion
You can set the value of IsButtonVisible in the RowSelected event based on your business logic:
protected virtual void DAC_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
DAC row = e.Row as DAC;
if (row != null)
{
bool yourCondition = ???;
row.IsButtonVisible = yourCondition;
}
}
Source:
Enable disable button of grid or PXToolBarButton, which depends from value of column in Acumatica
I have 2 Telerik's rad grids. First one is master and second one is detail. I can delete rows from both grids independently by pressing "Delete" button on toolbar above each grid. I also have "Refresh" buttons in toolbar of both grids.
The problem is with detail grid. When I delete item(s) the grid doesn't refresh. Calling Rebind method doesn't help. The only thing that helps is to press "Refresh" button in toolbar of master grid and select the row in master grid by mouse that was previously selected. After that I can see refreshed detail grid.
So, I don't need to press "Refresh" button in toolbar of master grid and select the row in master grid by mouse. I can refresh the master grid programmatically and only want to reselect the item that was originally selected also programmatically. I've tried this:
item.Selected = true;
But, it only visually selects the item in master grid and doesn't refresh the detail grid.
So, how to select the item in master grid programmatically in order to get the same effect as selecting it by mouse?
Thank you in advance.
I've just realised that your probably using different DataSource for both grids, but pointing to the same database, right? My example below uses the same datasource for both grids. However I made on a detail view versus a normal view by making some columns not visible. Maybe this strategy could fix your issue?
My first thought was to try implement the SelectionChanged event, or if not that, the SelectionChanging event. Put a refresh in there you see. But I didn't end up doing it that way.
I wrote a small program as below. It saves the edits to disk with any row change as long as its not a remove (I had trouble saving remove edits when the button was clicked it gave a null pointer exception on the remove command). It also saves changes just before closing the program (so that any delete rows are also saved then). I did find that the deleteOne and deleteTwo buttons (that delete from the first or second grid, respectively) do in fact cause the deletion to occur in both grids. So a possibility is you could use the radGridView1.Rows.Remove(row) or RemoveAt(i) command if that works in your situation?
Another possibility is that if refresh isn't working you could set the DataSource to null and then set it to the data source again, after deleting the row. This is a bit drastic but if it's the only thing that works? I'm talking about the data source for both grids.
My code is below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.Data;
using Telerik.WinControls.UI;
namespace RadControlsWinFormsApp1
{
public partial class RadForm1 : Telerik.WinControls.UI.RadForm
{
public RadForm1()
{
InitializeComponent();
}
private void RadForm1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'testdbDataSet.Customers' table. You can move, or remove it, as needed.
this.customersTableAdapter.Fill(this.testdbDataSet.Customers);
radGridView1.Columns["Address"].IsVisible = false;
}
private void radGridView1_RowsChanged(object sender, Telerik.WinControls.UI.GridViewCollectionChangedEventArgs e)
{
// if removing don't update, because if my delete button is pressed this
// will otherwise cause all sorts of problems and freezes the grid
if (e.Action != NotifyCollectionChangedAction.Remove)
{
try
{
customersTableAdapter.Update(testdbDataSet);
}
catch (DBConcurrencyException ex)
{
// unable to save right now, don't worry about it
}
}
radGridView2.Refresh();
}
private void butDeleteOne_Click(object sender, EventArgs e)
{
bool haveRemoved = false;
for (int i = 0; i < radGridView1.Rows.Count && !haveRemoved; ++i)
{
GridViewRowInfo row = radGridView1.Rows[i];
if (row.IsSelected)
{
haveRemoved = true;
radGridView1.Rows.RemoveAt(i);
}
}
}
private void butDeleteTwo_Click(object sender, EventArgs e)
{
bool haveRemoved = false;
for (int i = 0; i < radGridView2.Rows.Count && !haveRemoved; ++i)
{
GridViewRowInfo row = radGridView2.Rows[i];
if (row.IsSelected)
{
haveRemoved = true;
radGridView2.Rows.RemoveAt(i);
}
}
}
private void radGridView2_RowsChanged(object sender, GridViewCollectionChangedEventArgs e)
{
// if removing don't update, because if my delete button is pressed this
// will otherwise cause all sorts of problems and freezes the grid
if (e.Action != NotifyCollectionChangedAction.Remove)
{
try
{
customersTableAdapter.Update(testdbDataSet);
}
catch (DBConcurrencyException ex)
{
// unable to save right now, don't worry about it
}
}
radGridView1.Refresh();
}
private void RadForm1_FormClosing(object sender, FormClosingEventArgs e)
{
// ensure all data is saved back into database on close
customersTableAdapter.Update(testdbDataSet);
}
//private void radGridView1_CellEndEdit(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
//{
//}
}
}