Tuesday, 3 May 2016

Dynamically changing an attribute property for a given data record

Hi Everyone,

Suppose you need to change a particular property of a PXSomeAttribute residing on a Field of your data record.

Way 1
A straightforward way of doing it:
foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes<Field>(dataRecord))
{
    PXSomeAttribute someAttribute = attribute as PXSomeAttribute;
    if (someAttribute != null
    {
        someAttribute.Property = someValue;
    }
}

Way 2
A less verbose / arguably more readable way of achieving the same goal with linq:

cache
    .GetAttributes<Field>(dataRecord)
    .OfType<PXSomeAttribute>()
    .ForEach(attribute => attribute.Property = someValue);

Remember, that for many standard Acumatica attributes you already have standard static methods for changing attribute properties. Some existing examples:
  • PXUIFieldAttribute.SetRequired<DAC.someField>(cache, true);
  • PXUIFieldAttribute.SetVisible<DAC.someField>(cache, row, true);
  • PXUIFieldAttribute.SetEnabled<DAC.someField>(cache, row, true);
  • PXDefaultAttribute.SetPersistingCheck<DAC.someField>(cache, row, PXPersistingCheck);
  • PXStringListAttribute.SetList<DAC.someField>(cache, row, labels, values);
  • ... And many others ...
Several additional notes:
Note that changing properties logic on RowSelected, calling needs to be symmetric – every call system should set the property value to any specific value. You should not assume that there will be a default value.

Also note that some operations like SetRequired always operates on the cache level (without accepting a data record), which means it will set required state for all records residing in the cache.

And the last note - some dynamic operations are also required some additional configurations on user interfaces. Sometimes it can be not entirely self-evident.
For example to use SetRequired from PXUIFeildAttribute you also  need to to open the corresponding ASPX page and set the MarkRequired property to "Dynamic" on the field's container object:
<px:PXFormView runat="server" DataMember="Method" MarkRequired="Dynamic">
    ...
    <px:PXTextEdit ID="edSomeRelatedField" />
    ...

Thanks to Acumatica Development team for this example.
Have a nice development!

No comments: