Skip to main content
Answer

How do I access a custom field from a PXSelector in another field?

  • July 18, 2022
  • 5 replies
  • 684 views

Forum|alt.badge.img+1

Specifically we are trying to customize the Attributes screen to add an Attribute Type/Category field (combobox).  Then we can categorise attributes by Customer, Item, Other etc.

I have created the custom field (usrAttributeType) as a PXDBString with PXStringList for the combo values.

I have modified the PXSelector for the Attribute ID field.  We want to have the Selector for the AttributeID use the value from the custom field to limit the attributes to ones with the category selected instead of the constant it uses currently.

 

The field is called usrAttributeType and I have added the following so far:

namespace PX.Objects.CS
{
public class CSAttributeMaint_Extension : PXGraphExtension<CSAttributeMaint>
{
#region Event Handlers

public class attribType: PX.Data.Constant<string> {
public attribType() : base("I") { }
}

[PXDBString(10, IsUnicode = true, IsKey = true, InputMask = ">aaaaaaaaaa")]
[PXDefault()]
[PXUIField(DisplayName = "Attribute ID", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<CSAttribute.attributeID,
Where<
CSAttribute.attributeID, NotEqual<MatrixAttributeSelectorAttribute.dummyAttributeName>
,
And<
CSAttributeExt.usrAttributeType, Equal<attribType>
>>
>))]
protected virtual void CSAttribute_AttributeID_CacheAttached(PXCache cache)
{

}



#endregion
}
}

I’m not sure how to refer to the custom field and get the value it’s set to.

Any help would be much appreciated.

 

Thanks,

 

Phil

Best answer by Marco Villasenor

I just realized my note would make more sense if my sample code was in one of the graphs I recommend using, so here is the update with the sample for the Item Class screen (IN201000):

using PX.Objects.CS;

namespace PX.Objects.IN
{

[PXLocalizable()]
public static class CustomMessages
{
public const string AttributeNotFound = "Attribute not found with required type";
}

// Use a graph that requires you to pick an attribute, not the CSAttributeMaint graph.
public class INItemClassMaint_Extension : PXGraphExtension<INItemClassMaint>
{
#region Event Handlers

// Switched to updated recommended class, other format is deprecated
// I imagine "I" is used in the custom field to indicate attribute type for "Items"
public class attribType : PX.Data.BQL.BqlString.Constant<attribType>
{
public attribType() : base("I") { }
}

// MergeAttributes keeps original attributes and let's us add new ones
// PXRestrictor adds condition to existing PXSelector, but requires an error message
// for cases where value does not meet the condition.
[PXMergeAttributes(Method = MergeMethod.Merge)]
[PXRestrictor(typeof(Where<CSAttributeExt.usrAttributeType, Equal<attribType>>), CustomMessages.AttributeNotFound)]
protected virtual void _(Events.CacheAttached<CSAttributeGroup.attributeID> e){}

#endregion
}
}

 

5 replies

Dioris Aguilar
Jr Varsity I
Forum|alt.badge.img+2

@ppowell Your sintax looks good to me, is there any error you are getting?
In a BQL statement, like the one used in a PXSelectorAttribute, a custom field is accessed by referencing the DAC extension as you did.


Marco Villasenor
Jr Varsity II
Forum|alt.badge.img+2


What release of Acumatica are you targeting?

If you are only adding a condition based on fields from the same DAC in the selector (or extensions for those DACs) you can use the PXRestrictor attribute.

Here is an article with more information.

To add it without replacing existing attributes you use the PXMergeAttributes attribute.

Here is an article with more information.

Finally, I imagine you plan to add the constant and the CacheAttached method to every Graph extension where you need to use the filter, so you would use it in a graph that allows you to pick attributes, like the CustomerMaint graph and not the CSAttributeMaint graph.

I also switched your attribType definition with the new way to declare constant values:

namespace PX.Objects.CS
{

[PXLocalizable()]
public static class CustomMessages
{
public const string AttributeNotFound = "Attribute not found with required type";
}

// Use a graph that requires you to pick an attribute, not the CSAttributeMaint graph.
public class CSAttributeMaint_Extension : PXGraphExtension<CSAttributeMaint>
{
#region Event Handlers

// Switched to updated recommended class, other format is deprecated
public class attribType : PX.Data.BQL.BqlString.Constant<attribType>
{
public attribType() : base("I") { }
}

// MergeAttributes keeps original attributes and let's us add new ones
// PXRestrictor adds condition to existing PXSelector, but requires an error message
// for cases where value does not meet the condition.
[PXMergeAttributes(Method = MergeMethod.Merge)]
[PXRestrictor(typeof(Where<CSAttribute.attributeID, NotEqual<MatrixAttributeSelectorAttribute.dummyAttributeName>,
And<CSAttributeExt.usrAttributeType, Equal<attribType>>>), CustomMessages.AttributeNotFound)]
protected virtual void CSAttribute_AttributeID_CacheAttached(PXCache cache){}

#endregion
}
}

 


Forum|alt.badge.img+1
  • Author
  • Semi-Pro I
  • July 19, 2022

@Dioris Aguilar Sorry.  I don’t think I explained very well.  Instead of the constant I have defined I wanted to refer to the current value of the combobox on the screen so the PXSelector for Attribute ID would only list IDs that match the usrAttributeType.  I guess it would be in the cache somewhere but I’m not sure how to access it.

 

Thanks,

 

Phil


Forum|alt.badge.img+1
  • Author
  • Semi-Pro I
  • July 19, 2022

@Marco Villasenor Thanks for the detailed description. I’ll have a read of that and see what I can come up with..

Phil


Marco Villasenor
Jr Varsity II
Forum|alt.badge.img+2

I just realized my note would make more sense if my sample code was in one of the graphs I recommend using, so here is the update with the sample for the Item Class screen (IN201000):

using PX.Objects.CS;

namespace PX.Objects.IN
{

[PXLocalizable()]
public static class CustomMessages
{
public const string AttributeNotFound = "Attribute not found with required type";
}

// Use a graph that requires you to pick an attribute, not the CSAttributeMaint graph.
public class INItemClassMaint_Extension : PXGraphExtension<INItemClassMaint>
{
#region Event Handlers

// Switched to updated recommended class, other format is deprecated
// I imagine "I" is used in the custom field to indicate attribute type for "Items"
public class attribType : PX.Data.BQL.BqlString.Constant<attribType>
{
public attribType() : base("I") { }
}

// MergeAttributes keeps original attributes and let's us add new ones
// PXRestrictor adds condition to existing PXSelector, but requires an error message
// for cases where value does not meet the condition.
[PXMergeAttributes(Method = MergeMethod.Merge)]
[PXRestrictor(typeof(Where<CSAttributeExt.usrAttributeType, Equal<attribType>>), CustomMessages.AttributeNotFound)]
protected virtual void _(Events.CacheAttached<CSAttributeGroup.attributeID> e){}

#endregion
}
}