Skip to main content
Answer

How to Conditionally Hide a Tab in a Form Based on a Custom Field in Another Form

  • December 13, 2024
  • 10 replies
  • 322 views

Forum|alt.badge.img

I want to conditionally hide a tab in the Production Order Maintenance form. To achieve this, I followed Option 1 in the following Acumatica Community Portal article.

https://community.acumatica.com/customization-tools-and-framework-245/how-to-conditionally-hide-a-tab-on-the-entry-form-4310

First, I created an unbound DAC in the AMProdItemExt DAC as follows.

 #region UsrCustomField01
    [PXBool()]
    [PXUIField(DisplayName="Custom Field", Visible = false)]
    [PXDefault(false)]
                
    public virtual bool? UsrCustomField01 { get; set; }
    public abstract class usrCustomField01 : PX.Data.BQL.BqlString.Field<usrCustomField01> { }


Now, I want to change the value of the UsrcustomField01 based on a field in the Stock Items screen. This field is also custom field in the InventoryItemExt DAC.

I tried using event handlers, PXFormula, and PXDefault, but it didn't work.

We can create a connection between the AMProdItem and InventoryItem DACs using the InventoryID fields of both DACs.

Best answer by aiwan

HI ​@RKarunarathne51 

 

You could add a view to your graph extension for the InventoryItem DAC and reference this in the RowSelected handler to configure the visibility of the tab you want to set visible, 

 

protected virtual void _(Events.RowSelected<ISORecord> e)
{
ISORecord row = e.Row;

NCRs.Cache.AllowSelect /*Select the View in the cache*/ =
row.DocType != "ECN"; //Control the visibility of NCRs view based on a condition

ECNs.Cache.AllowSelect /*Select the View in the cache*/ =
row.DocType != "NCR"; //Control the visibility of ECNs view based on a condition


}

This is a snippet of mine that works.

 

Aleks

10 replies

Forum|alt.badge.img+1
  • Jr Varsity III
  • December 13, 2024

Hi ​@RKarunarathne51 ,
Try with RowSelecting or RowSelected event. If you need to handle changes to the InventoryID field then try below code on FieldUpdated event.

public class AMProdOrderEntryExt : PXGraphExtension<AMProdOrderEntry>
{
    protected virtual void _(Events.RowSelecting<AMProdItem> e)
    {
        if (e.Row == null) return;
        
        var prodItemExt = PXCache<AMProdItem>.GetExtension<AMProdItemExt>(e.Row);
        if (prodItemExt == null) return;

        // Query the InventoryItem record
        InventoryItem inventoryItem = PXSelect<InventoryItem,
            Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>
            .Select(Base, e.Row.InventoryID);
        
        if (inventoryItem != null)
        {
            // Get the extension for InventoryItem
            var inventoryItemExt = PXCache<InventoryItem>.GetExtension<InventoryItemExt>(inventoryItem);
            if (inventoryItemExt != null)
            {
                // Set your custom field based on the InventoryItem's custom field
                prodItemExt.UsrCustomField01 = inventoryItemExt.UsrYourStockItemField;
            }
        }
    }
}

Hope it will work .


Forum|alt.badge.img
  • Author
  • Freshman I
  • December 13, 2024

Hi ​@noorula77 ,

I tried using the RowSelecting and RowSelected event handlers, but they were not suitable. Then I tried using the FieldUpdated event handler, but it was not invoked. I need to show or hide a tab for different production orders. When the user changes the prodOrdID (by using a selector or by clicking Next and Previous), this event handler should be triggered. What event handler is suitable for this?


Forum|alt.badge.img+1
  • Jr Varsity III
  • December 13, 2024

Hi ​@RKarunarathne51 ,

The key points about this solution:

  1. RowSelected is the right event because it:
    • Fires whenever a row is selected, including when changing records via selectors or Next/Previous buttons
    • Used SelectSingle instead of Select for better performance since we only need one record
    • Replace "YourTabName" with your actual tab name from the ASPX page
    • Replace UsrYourStockItemField with your actual custom field name from InventoryItemExt

public class AMProdOrderEntryExt : PXGraphExtension<AMProdOrderEntry>
{
    protected virtual void _(Events.RowSelected<AMProdItem> e)
    {
        if (e.Row == null) return;

        var prodItemExt = PXCache<AMProdItem>.GetExtension<AMProdItemExt>(e.Row);
        if (prodItemExt == null) return;

        // Query the InventoryItem record using PXSelect
        var inventoryItem = PXSelect<InventoryItem,
            Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>
            .SelectSingle(Base, e.Row.InventoryID);

        if (inventoryItem != null)
        {
            // Get the extension for InventoryItem
            var inventoryItemExt = PXCache<InventoryItem>.GetExtension<InventoryItemExt>(inventoryItem);
            if (inventoryItemExt != null)
            {
                // Set your custom field based on the InventoryItem's custom field
                prodItemExt.UsrCustomField01 = inventoryItemExt.UsrYourStockItemField;

                // Get the tab item
                var tab = Base.TabView.Items["YourTabName"];
                if (tab != null)
                {
                    // Set the tab visibility based on your condition
                    tab.Visible = prodItemExt.UsrCustomField01 == true;
                }
            }
        }
    }
Hope it will work.


Forum|alt.badge.img+8
  • Captain II
  • Answer
  • December 13, 2024

HI ​@RKarunarathne51 

 

You could add a view to your graph extension for the InventoryItem DAC and reference this in the RowSelected handler to configure the visibility of the tab you want to set visible, 

 

protected virtual void _(Events.RowSelected<ISORecord> e)
{
ISORecord row = e.Row;

NCRs.Cache.AllowSelect /*Select the View in the cache*/ =
row.DocType != "ECN"; //Control the visibility of NCRs view based on a condition

ECNs.Cache.AllowSelect /*Select the View in the cache*/ =
row.DocType != "NCR"; //Control the visibility of ECNs view based on a condition


}

This is a snippet of mine that works.

 

Aleks


Forum|alt.badge.img
  • Author
  • Freshman I
  • December 13, 2024

Hi ​@noorula77 ,
In the RowSelected event handler, modifying the value of a field directly is not allowed. Therefore, the following code line cannot be executed. This is why I mentioned that RowSelected cannot be used.

prodItemExt.UsrCustomField01 = inventoryItemExt.UsrYourStockItemField;

Do you have any suggestions for changing the value of the field using an alternative method?


Forum|alt.badge.img+1
  • Jr Varsity III
  • December 13, 2024

Hi ​@RKarunarathne51 ,
 

This solution splits the responsibilities:

  1. RowSelecting: Handles the data modification before the row is added to the cache
  2. RowSelected: Handles only the UI updates after the data is loaded

    protected virtual void _(Events.RowSelecting<AMProdItem> e)
        {
            if (e.Row == null) return;

            var prodItemExt = PXCache<AMProdItem>.GetExtension<AMProdItemExt>(e.Row);
            if (prodItemExt == null) return;

            // Query the InventoryItem record using PXSelect
            var inventoryItem = PXSelect<InventoryItem,
                Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>
                .SelectSingle(Base, e.Row.InventoryID);

            if (inventoryItem != null)
            {
                var inventoryItemExt = PXCache<InventoryItem>.GetExtension<InventoryItemExt>(inventoryItem);
                if (inventoryItemExt != null)
                {
                    // Update the field value in RowSelecting
                    prodItemExt.UsrCustomField01 = inventoryItemExt.UsrYourStockItemField;
                }
            }
        }

        // Handle UI updates in RowSelected
        protected virtual void _(Events.RowSelected<AMProdItem> e)
        {
            if (e.Row == null) return;

            var prodItemExt = PXCache<AMProdItem>.GetExtension<AMProdItemExt>(e.Row);
            if (prodItemExt == null) return;

            // Get the tab item and update visibility
            var tab = Base.TabView.Items["YourTabName"];
            if (tab != null)
            {
                tab.Visible = prodItemExt.UsrCustomField01 == true;
            }
        }
    }

Alternatively, if you need more control over when the field value changes, you could also consider:


[PXDefault(typeof(Search<InventoryItemExt.usrYourStockItemField,
    Where<InventoryItem.inventoryID, Equal<Current<AMProdItem.inventoryID>>>>))]
[PXUIField(DisplayName="Custom Field", Visible = false)]
public virtual bool? UsrCustomField01 { get; set; }

 

OR

 

[PXFormula(typeof(Selector<AMProdItem.inventoryID, InventoryItemExt.usrYourStockItemField>))]
[PXUIField(DisplayName="Custom Field", Visible = false)]
public virtual bool? UsrCustomField01 { get; set; }

If possible please share screen shot of the screens.


Forum|alt.badge.img
  • Author
  • Freshman I
  • December 13, 2024

Hi ​@noorula77,

Thank you for your help. Following code lines cannot be executed. 

var tab = Base.TabView.Items["YourTabName"];

tab.Visible = prodItemExt.UsrCustomField01 == true;

Specially the Base.TabView.Items["YourTabName"] and tab.Visible lines. 

Do you have any suggestions? Thank you


darylbowman
Captain II
Forum|alt.badge.img+15
  • December 13, 2024

The correct way to hide a tab is to set View.Cache.AllowSelect = false as ​@aiwan showed; you may be able to use the events that ​@noorula77 suggested to execute this.


Forum|alt.badge.img
  • Author
  • Freshman I
  • December 13, 2024

Hi ​@darylbowman ,

I created two tabs using two custom views. When I use the View.Cache.AllowSelect = false statement on one view, both tabs are hidden. Three out of the four DACs used in both views are the same, and only one DAC is different. Do you have any idea why this happens?


darylbowman
Captain II
Forum|alt.badge.img+15
  • December 13, 2024

...Three out of the four DACs used in both views are the same, and only one DAC is different...

I believe it is likely that you will experience inconsistencies in this case because of how Acumatica handles the cache. I can’t explain the reasons behind it because it’s not something I understand that well.

@Dmitrii Naumov - Am I right? Does he need an alias DAC or is that just for multiple joins in the same view?