I like to limit the results by value in my field in backoffice config file. To mention is that my grouptype field is an ENUM. Is it possible to do this? I tried already this in mybackoffice-config.xml:
<editorArea:attribute qualifier="disableGroups">
<editorArea:editor-parameter>
<editorArea:name>referenceSearchCondition_grouptype</editorArea:name>
<editorArea:value>DISABLE_GROUP</editorArea:value>
</editorArea:editor-parameter>
</editorArea:attribute>
but I get this ERROR:
ERROR [hybrisHTTP30] [UiEngineImpl]
de.hybris.platform.servicelayer.exceptions.UnknownIdentifierException: No attribute with qualifier grouptype found.
at de.hybris.platform.servicelayer.type.impl.DefaultTypeService.getAttributeDescriptor(DefaultTypeService.java:195) ~[coreserver.jar:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.adjustCondition(DefaultPlatformFieldSearchFacadeStrategy.java:214) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.adjustConditionRecursively(DefaultPlatformFieldSearchFacadeStrategy.java:205) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.adjustConditionRecursively(DefaultPlatformFieldSearchFacadeStrategy.java:198) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.parseSearchQueryAttributes(DefaultPlatformFieldSearchFacadeStrategy.java:183) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.createSearchQueryDataBuilderWithAttributes(DefaultPlatformFieldSearchFacadeStrategy.java:173) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.adjustSearchQuery(DefaultPlatformFieldSearchFacadeStrategy.java:161) ~[classes/:?]
at com.hybris.backoffice.cockpitng.dataaccess.facades.search.DefaultPlatformFieldSearchFacadeStrategy.searchInternal(DefaultPlatformFieldSearchFacadeStrategy.java:104) ~[classes/:?]
Second try:
I tried also with the sequence number of my ENUM value like this:
<editorArea:attribute qualifier="disableGroups">
<editorArea:editor-parameter>
<editorArea:name>referenceSearchCondition_grouptype</editorArea:name>
<editorArea:value>3</editorArea:value>
</editorArea:editor-parameter>
I get no errors but it doesn't work either. It does nothing.
Related
I create a custom view to use in layouts and need to set a default value for its properties.
My view actually works almost perfect, but need default properties for better usability.
<declare-styleable name="ExpandableView">
...
<attr name="expanded" format="boolean"/>
</declare-styleable>
How to make something like:
<attr name="expanded" format="boolean" default="true"/>
As I understand tag attr do not support "default".
You could do it in your implementation of ExpandableView as below;
val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.ExpandableView)
val expanded = typedArray.getBoolean(R.styleable.ExpandableView_expanded, true)
I know it isn't quite what you're looking, but it should produce the same results.
I'm not talking about boolean attributes, attributes like class if you don't want to add an empty class attribute if there's no CSS class.
html`<span class=${hasClass ? 'my-class' : ''}></span>`
There is an ifDefined directive that does what you want. If the value is undefined the attribute won't be rendered.
import {ifDefined} from 'lit-html/directives/if-defined';
html`<span class=${ifDefined(hasClass ? 'my-class' : undefined)}></span>`
I have added a custom field to a screen and want to have a Selector to choose values from the Description of a specific attribute called BASEITEM.
[PXDBString(50, IsUnicode = true)]
[PXUIField(DisplayName = "Document Number", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<CSAttributeDetail.Description,
Where<CSAttributeDetail.AttributeID.StartsWith("BASEITEM")>,
OrderBy<Asc<CSAttributeDetail.Description>>>),
DescriptionField = typeof(CSAttributeDetail.Description)]
However, when I try to publish this I get errors.
Building directory '/WebSiteValidationDomain/App_RuntimeCode/'.
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1003: Syntax error, '>' expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1525: Invalid expression term ','
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1026: ) expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1003: Syntax error, ']' expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(28): error CS1519: Invalid token '>' in class, struct, or interface member declaration
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(29): error CS1519: Invalid token '=' in class, struct, or interface member declaration
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(29): error CS1519: Invalid token ')' in class, struct, or interface member declaration
Compiler time, seconds: 0.8243028
Validation failed.
There are a couple of strange things in your attributes, so let's try if fixing them will resolve your problem. Here is the complete snippet that should work :
[PXDBString(50, IsUnicode = true)]
[PXUIField(DisplayName = "Document Number", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<CSAttributeDetail.description,
Where<CSAttributeDetail.attributeID, Like<string_BASEITEMPCT>>,
OrderBy<Asc<CSAttributeDetail.description>>>),
DescriptionField = typeof(CSAttributeDetail.description))]
Here is the constant class used in the PXSelector attribute
public class string_BASEITEMPCT : Constant<string>
{
public string_BASEITEMPCT()
: base("BASEITEM%")
{
}
}
You were missing a parenthesis at the end of the PXSelector attribute which prevented build and publish.
You need to use the classes inheriting IBqlField instead of specific field i.e. use the lowercase class instead of the uppercase field when doing BQL.
To compare a field value to a string, use the Like<> operator and a string constant. To create that constant, create a class and specify the string value as the argument of the base constructor. The % at the end of "BASEITEM%" has the same purpose as the SQL wildcard %
I am using <p:selectCheckboxMenu> on a List<Long>:
<p:selectCheckboxMenu value="#{bean.selectedItems}">
<f:selectItems value="#{bean.availableItems}" />
</p:selectCheckboxMenu>
private List<Long> selectedItems;
private Map<String, Long> availableItems;
When submitting the form and looping over the selected items as below,
for (int i = 0; i < selectedItems.size(); i++) {
Long id = selectedItems.get(i);
// ...
}
Then I get a class cast exception:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.example.Bean.submit(Bean.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 27 more
The same problem occurs with <p:selectManyCheckbox>, <p:selectManyMenu>, <h:selectManyMenu>, etc. All multiple-selection components basically. It works fine in <p:selectOneMenu> and all other single-selection components on a single value Long property.
How is this caused and how can I solve it?
Your problem is caused by the following facts:
Java generics are compiletime syntactic sugar and completely absent during runtime.
EL expressions runs during runtime and not during compiletime.
HTTP request parameters are obtained as Strings.
Logical consequence is: EL doesn't see any generic type information. EL doesn't see a List<Long>, but a List. So, when you don't explicitly specify a converter, EL will after obtaining the submitted value as String set it unmodified in the List by reflection means. When you attempt to cast it to Long afterwards during runtime, you'll obviously face a ClassCastException.
The solution is simple: explicitly specify a converter for String to Long. You can use the JSF builtin LongConverter for this which has the converter ID javax.faces.Long. Other builtin converters are listed here.
<p:selectCheckboxMenu ... converter="javax.faces.Long">
Another solution without the need to explicitly specify the converter is to change List<T> type to a T[]. This way the EL will see the Long typed array and thus perform automatic conversion. But this possibly requires changes elsewhere in the model which may not be desirable.
private Long[] selectedItems;
In case you're using a complex object (javabean, entity, POJO, etc) as select item value instead of a standard type like Long for which JSF has builtin converters, then the same rules also apply. You only need to create a custom Converter and explicitly specify it in input component's converter attribute, or rely on forClass if you can use T[]. How to create such a converter is elaborated in Conversion Error setting value for 'null Converter'.
I am using <p:selectCheckboxMenu> on a List<Long>:
<p:selectCheckboxMenu value="#{bean.selectedItems}">
<f:selectItems value="#{bean.availableItems}" />
</p:selectCheckboxMenu>
private List<Long> selectedItems;
private Map<String, Long> availableItems;
When submitting the form and looping over the selected items as below,
for (int i = 0; i < selectedItems.size(); i++) {
Long id = selectedItems.get(i);
// ...
}
Then I get a class cast exception:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.example.Bean.submit(Bean.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 27 more
The same problem occurs with <p:selectManyCheckbox>, <p:selectManyMenu>, <h:selectManyMenu>, etc. All multiple-selection components basically. It works fine in <p:selectOneMenu> and all other single-selection components on a single value Long property.
How is this caused and how can I solve it?
Your problem is caused by the following facts:
Java generics are compiletime syntactic sugar and completely absent during runtime.
EL expressions runs during runtime and not during compiletime.
HTTP request parameters are obtained as Strings.
Logical consequence is: EL doesn't see any generic type information. EL doesn't see a List<Long>, but a List. So, when you don't explicitly specify a converter, EL will after obtaining the submitted value as String set it unmodified in the List by reflection means. When you attempt to cast it to Long afterwards during runtime, you'll obviously face a ClassCastException.
The solution is simple: explicitly specify a converter for String to Long. You can use the JSF builtin LongConverter for this which has the converter ID javax.faces.Long. Other builtin converters are listed here.
<p:selectCheckboxMenu ... converter="javax.faces.Long">
Another solution without the need to explicitly specify the converter is to change List<T> type to a T[]. This way the EL will see the Long typed array and thus perform automatic conversion. But this possibly requires changes elsewhere in the model which may not be desirable.
private Long[] selectedItems;
In case you're using a complex object (javabean, entity, POJO, etc) as select item value instead of a standard type like Long for which JSF has builtin converters, then the same rules also apply. You only need to create a custom Converter and explicitly specify it in input component's converter attribute, or rely on forClass if you can use T[]. How to create such a converter is elaborated in Conversion Error setting value for 'null Converter'.