John Wiles
John Wiles

Reputation: 11

Acumatica dynamic dropdown in custom field based on current record status field

I have added a custom field to the BAccount table called UsrSubStatus with a PXStringList of six values. If the BAccount Status field is "Inactive" (value of I) then the UsrSubStatus dropdown list should only allow selection of 3 of the list values. If the Status field is other than Inactive then the dropdown list should only allow selection of the other 3 list values.

I found an article: Acumtica dynamic dropdown that looks very similar to what I am trying to accomplish but it bases the dynamic change based on the current company the user is logged into.

 var company = PX.Data.Update.PXInstanceHelper.CurrentCompany;

My issue in the following code is how to reference the BAccount Status field in my var status line.

 public class DynamicDropdownAttribute : PXStringListAttribute
 {
   #region Event Handlers
   private string[] Values2 = { "A1", "A2", "A3" };
   private string[] Labels2 = { "On-Plan", "Off-Plan", "Services Only" };

   private string[] Values3 = { "I1", "I2", "I3" };
   private string[] Labels3 = { "ROR - Same Product", "ROR - New Product", "Out of Business" };

   public DynamicDropdownAttribute()
       : base()
   {
   }

   public override void CacheAttached(PXCache sender)
   {
       base.CacheAttached(sender);
       var status = sender.CR.Status;
       if (status != "I")
       {
           this._AllowedValues = Values2;
           this._AllowedLabels = Labels2;
       }
       else 
       {
           this._AllowedValues = Values3;
           this._AllowedLabels = Labels3;
       }
   }
}

Upvotes: 0

Views: 480

Answers (2)

John Wiles
John Wiles

Reputation: 11

I really liked the first solution and was able to get some help from Acumatica. The first step was to define the DAC:

[PXDBString(25, IsUnicode=true)]
[PXUIField(DisplayName="Sub-Status", Required = true)]
[PXDefault()]
[PXDependsOnFields(typeof(BAccount.status))]
[PXStringList(
new string[]
{ "A1", "A2", "A3", "I1", "I2", "I3" },
new string[]
{ "On-Plan", "Off-Plan", "Services Only", "ROR - Same Product", "ROR - New Product", "Out of Business" })]

Then in the BusinessAccountMaint_Extension graph do the following:

private string[] Values2 = { "A1", "A2", "A3" };
private string[] Labels2 = { "On-Plan", "Off-Plan", "Services Only" };
private string[] Values3 = { "I1", "I2", "I3" };
private string[] Labels3 = { "ROR - Same Product", "ROR - New Product", "Out of Business" };

protected void BAccount_Status_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated del)
{
  if(del != null)
    del(cache, e);

  var row = (BAccount)e.Row;
  if(row == null) return;

  BAccountExt rowExt = PXCache<BAccount>.GetExtension<BAccountExt>(row);
  if (row.Status != "I")
      PXStringListAttribute.SetList<BAccountExt.usrSubStatus>(cache, row, Values2, Labels2);
  else
      PXStringListAttribute.SetList<BAccountExt.usrSubStatus>(cache, row, Values3, Labels3 );
}

protected void BAccount_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
  if (del != null)
    del(cache, e);

  var row = (BAccount)e.Row;
  if (row == null) return;

  if (row.Status != "I")
    PXStringListAttribute.SetList<BAccountExt.usrSubStatus>(cache, row, Values2, Labels2);
  else
    PXStringListAttribute.SetList<BAccountExt.usrSubStatus>(cache, row, Values3, Labels3);
}

Upvotes: 0

Vardan Vardanyan
Vardan Vardanyan

Reputation: 669

Modify the source code following this, where statusField is your custom field. On the Customization Project Editorscreen, you should be set the CommitChanges=true for the custom field.

 public class DynamicDropdown001Attribute : PXStringListAttribute
{
    public const string A1 = "On-Plan";
    public const string A2 = "Off-Plan";
    public const string A3 = "Services Only";

    public DynamicDropdown001Attribute() : base(new string[] { A1,A2,A3 }, new string[] { "On-Plan", "Off-Plan", "Services Only" }) { }
}
public class DynamicDropdown002Attribute : DynamicDropdown001Attribute
{
    public const string I1 = "ROR - Same Product";
    public const string I2 = "ROR - New Product";
    public const string I3 = "Out of Business";
    public DynamicDropdown002Attribute() 
    {
        Array.Resize(ref _AllowedValues, _AllowedValues.Length - 3);
        Array.Resize(ref _AllowedValues, _AllowedValues.Length + 3);
        _AllowedValues[_AllowedValues.Length - 3] = I1;
        _AllowedValues[_AllowedValues.Length - 2] = I2;
        _AllowedValues[_AllowedValues.Length - 1] = I3;
        Array.Resize(ref _AllowedLabels, _AllowedLabels.Length - 3);
        Array.Resize(ref _AllowedLabels, _AllowedLabels.Length + 3);
        _AllowedLabels[_AllowedLabels.Length - 3] = DynamicDropdown002Attribute.I1;
        _AllowedLabels[_AllowedLabels.Length - 2] = DynamicDropdown002Attribute.I2;
        _AllowedLabels[_AllowedLabels.Length - 1] = DynamicDropdown002Attribute.I3;
    }
}
public class DynamicDropdownAttribute : PXStringListAttribute, IPXRowSelectedSubscriber
{
    public Type _StatusField;
    public DynamicDropdownAttribute(Type statusField)
    {
        _StatusField = statusField;
    }
    public void RowSelected(PXCache sender, PXRowSelectedEventArgs e)
    {
        object row = e.Row as object;
        if (row != null)
        {
            bool? filter = (bool?)((string)sender.GetValue(e.Row, _StatusField.Name) == "I");
            PXStringListAttribute.SetList(sender, row, _FieldName, (filter.HasValue && filter.Value ? new DynamicDropdown001Attribute() : new DynamicDropdown002Attribute()));
        }
    }
}

Upvotes: 1

Related Questions