Skip to content

Commit 18df3a9

Browse files
authored
UE: Supporting a new CRX property for multi select dropdown's default values (#1454)
* UE: Supporting a new CRX property for multi select dropdown's default values * Added test case * format file * Updated name property with fd prefix * Added comment with context * Typo * Multiselect type inference in model * Lint fix * Improved test cov
1 parent a59c898 commit 18df3a9

File tree

6 files changed

+121
-32
lines changed

6 files changed

+121
-32
lines changed

bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ private ReservedProperties() {
7474
public static final String PN_PLACEHOLDER = "placeholder";
7575
public static final String PN_READ_ONLY = "readOnly";
7676
public static final String PN_DEFAULT_VALUE = "default";
77+
public static final String PN_MULTI_DEFAULT_VALUES = "fd:multiDefaultValues";
7778
public static final String PN_FORMAT = "format";
7879
public static final String PN_DISPLAY_FORMAT = "displayFormat";
7980
public static final String PN_EDIT_FORMAT = "editFormat";

bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DropDownImpl.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.adobe.cq.export.json.ExporterConstants;
2828
import com.adobe.cq.forms.core.components.internal.form.FormConstants;
2929
import com.adobe.cq.forms.core.components.internal.form.ReservedProperties;
30+
import com.adobe.cq.forms.core.components.models.form.BaseConstraint.Type;
3031
import com.adobe.cq.forms.core.components.models.form.DropDown;
3132
import com.adobe.cq.forms.core.components.models.form.FieldType;
3233
import com.adobe.cq.forms.core.components.util.AbstractOptionsFieldImpl;
@@ -58,6 +59,30 @@ public Boolean isMultiSelect() {
5859
return multiSelect;
5960
}
6061

62+
@Override
63+
public Type getType() {
64+
Type baseType = super.getType();
65+
if (baseType == null) {
66+
return null;
67+
}
68+
69+
String typeValue = baseType.getValue();
70+
71+
// Handle multiSelect logic: append [] if multiSelect is true and not already array type
72+
// or remove [] if multiSelect is false and it's currently array type
73+
if (isMultiSelect()) {
74+
if (!typeValue.endsWith("[]")) {
75+
typeValue += "[]";
76+
}
77+
} else {
78+
if (typeValue.endsWith("[]")) {
79+
typeValue = typeValue.substring(0, typeValue.length() - 2);
80+
}
81+
}
82+
83+
return Type.fromString(typeValue);
84+
}
85+
6186
@Override
6287
public String getFieldType() {
6388
return super.getFieldType(FieldType.DROP_DOWN);

bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/util/AbstractOptionsFieldImpl.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ public abstract class AbstractOptionsFieldImpl extends AbstractFieldImpl impleme
5151
@Nullable
5252
protected String[] enumNames;
5353

54+
/**
55+
* Default for single and multivalued fields used the same 'default' crx property.
56+
* This was not compatible with Universal Editor's Property Rail Configuration.
57+
* Therefore, adding this property as an additional way of defining default values.
58+
**/
59+
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_MULTI_DEFAULT_VALUES)
60+
@Nullable
61+
protected Object[] multiDefaultValues;
62+
5463
@Override
5564
public boolean isEnforceEnum() {
5665
return enforceEnum;
@@ -117,7 +126,9 @@ public String[] getEnumNames() {
117126
public Object[] getDefault() {
118127
Object[] typedDefaultValue = null;
119128
try {
120-
if (defaultValue != null) {
129+
if (multiDefaultValues != null) {
130+
typedDefaultValue = ComponentUtils.coerce(type, multiDefaultValues);
131+
} else if (defaultValue != null) {
121132
typedDefaultValue = ComponentUtils.coerce(type, defaultValue);
122133
}
123134
} catch (Exception exception) {

bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DropDownImplTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class DropDownImplTest {
5454
private static final String CONTENT_ROOT = "/content";
5555
private static final String PATH_DROPDOWN_1 = CONTENT_ROOT + "/dropdown-1";
5656
private static final String PATH_MULTISELECT_DROPDOWN = CONTENT_ROOT + "/multiselect-dropdown";
57+
private static final String PATH_MULTISELECT_DROPDOWN_WITH_VARIANT_PROPERTY = CONTENT_ROOT + "/multiselect-dropdown-2";
5758
private static final String PATH_DROPDOWN2 = CONTENT_ROOT + "/dropdown2";
5859

5960
private static final String PATH_DROPDOWN = CONTENT_ROOT + "/dropdown";
@@ -354,6 +355,12 @@ void testGetMultiSelectDefault() {
354355
assertArrayEquals(new Long[] { 0L, 1L }, dropdown.getDefault());
355356
}
356357

358+
@Test
359+
void testGetMultiSelectDefault_WithDiffProperty() {
360+
DropDown dropdown = Utils.getComponentUnderTest(PATH_MULTISELECT_DROPDOWN_WITH_VARIANT_PROPERTY, DropDown.class, context);
361+
assertArrayEquals(new Long[] { 0L, 1L }, dropdown.getDefault());
362+
}
363+
357364
@Test
358365
void testGetMultiSelectDefault_InvalidType() throws IllegalAccessException {
359366
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN2, DropDown.class, context);
@@ -472,4 +479,56 @@ void testNoFieldType() {
472479
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_WITHOUT_FIELDTYPE, DropDown.class, context);
473480
Utils.testJSONExport(dropdown, Utils.getTestExporterJSONPath(BASE, PATH_DROPDOWN_WITHOUT_FIELDTYPE));
474481
}
482+
483+
@Test
484+
void testGetTypeWithNullBaseType() throws IllegalAccessException {
485+
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_1, DropDown.class, context);
486+
FieldUtils.writeField(dropdown, "type", null, true);
487+
assertNull(dropdown.getType());
488+
}
489+
490+
@Test
491+
void testGetTypeWithStringType() throws IllegalAccessException {
492+
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_1, DropDown.class, context);
493+
FieldUtils.writeField(dropdown, "type", Type.STRING, true);
494+
assertEquals(Type.STRING, dropdown.getType());
495+
496+
// Test multi-select with string type
497+
FieldUtils.writeField(dropdown, "multiSelect", true, true);
498+
assertEquals(Type.STRING_ARRAY, dropdown.getType());
499+
}
500+
501+
@Test
502+
void testGetTypeWithNumberType() throws IllegalAccessException {
503+
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_1, DropDown.class, context);
504+
FieldUtils.writeField(dropdown, "type", Type.NUMBER, true);
505+
assertEquals(Type.NUMBER, dropdown.getType());
506+
507+
// Test multi-select with number type
508+
FieldUtils.writeField(dropdown, "multiSelect", true, true);
509+
assertEquals(Type.NUMBER_ARRAY, dropdown.getType());
510+
}
511+
512+
@Test
513+
void testGetTypeWithBooleanType() throws IllegalAccessException {
514+
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_1, DropDown.class, context);
515+
FieldUtils.writeField(dropdown, "type", Type.BOOLEAN, true);
516+
assertEquals(Type.BOOLEAN, dropdown.getType());
517+
518+
// Test multi-select with boolean type
519+
FieldUtils.writeField(dropdown, "multiSelect", true, true);
520+
assertEquals(Type.BOOLEAN_ARRAY, dropdown.getType());
521+
}
522+
523+
@Test
524+
void testGetTypeWithExistingArrayType() throws IllegalAccessException {
525+
DropDown dropdown = Utils.getComponentUnderTest(PATH_DROPDOWN_1, DropDown.class, context);
526+
FieldUtils.writeField(dropdown, "multiSelect", true, true);
527+
FieldUtils.writeField(dropdown, "type", Type.STRING_ARRAY, true);
528+
assertEquals(Type.STRING_ARRAY, dropdown.getType());
529+
530+
// Test single-select with array type (should remove array suffix)
531+
FieldUtils.writeField(dropdown, "multiSelect", false, true);
532+
assertEquals(Type.STRING, dropdown.getType());
533+
}
475534
}

bundles/af-core/src/test/resources/form/dropdown/test-content.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,29 @@
6868
"minItems" : 1,
6969
"maxItems" : 2
7070
},
71+
"multiselect-dropdown-2" : {
72+
"jcr:primaryType": "nt:unstructured",
73+
"sling:resourceType" : "core/fd/components/form/dropdown/v1/dropdown",
74+
"name" : "abc",
75+
"jcr:title" : "def",
76+
"hideTitle" : true,
77+
"description" : "dummy",
78+
"visible" : false,
79+
"assistPriority" : "custom",
80+
"fieldType": "drop-down",
81+
"dataRef" : "a.b",
82+
"custom" : "Custom screen reader text",
83+
"typeMessage" : "incorrect type",
84+
"tooltip": "test-short-description",
85+
"type" : "number[]",
86+
"multiSelect" : true,
87+
"fd:multiDefaultValues" : [0, 1],
88+
"enum" : [0, 1, 2],
89+
"enumNames" : ["m", "f", "o"],
90+
"minItems" : 1,
91+
"maxItems" : 2,
92+
"required": true
93+
},
7194
"dropdown-datalayer": {
7295
"id": "dropdown-bb1c9e883e",
7396
"sling:resourceType": "core/fd/components/form/dropdown/v1/dropdown",

ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/clientlibs/editor/js/editDialog.js

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,40 +21,10 @@
2121
DROPDOWN_DEFAULTVALUEMULTISELCET = EDIT_DIALOG + " .cmp-adaptiveform-dropdown__defaultvaluemultiselect",
2222
DROPDOWN_SAVEVALUE = EDIT_DIALOG + " .cmp-adaptiveform-dropdown__savevaluetype",
2323
DROPDOWN_ENUM = EDIT_DIALOG + " .cmp-adaptiveform-base__enum",
24-
TYPE = EDIT_DIALOG + " input[name='./type']",
2524
DEFAULTINPUT = DROPDOWN_DEFAULTVALUE + " input",
2625
DEFAULTMUTIINPUT = DROPDOWN_DEFAULTVALUEMULTISELCET + " input[type='text']",
2726
Utils = window.CQ.FormsCoreComponents.Utils.v1;
2827

29-
30-
/**
31-
* Updates the save value types to their array equivalents when multi-select is toggled.
32-
* @param {HTMLElement} dialog The dialog on which the operation is to be performed.
33-
*/
34-
function handleSaveValueDropDown(dialog) {
35-
var multiSelect = dialog.find(DROPDOWN_ALLOWMULTISELECT)[0],
36-
saveValueDropdown = dialog.find(DROPDOWN_SAVEVALUE),
37-
type = dialog.find(TYPE),
38-
saveTypes = ['string', 'number', 'boolean'];
39-
40-
var updateSaveValueType = function() {
41-
var index = parseInt(saveValueDropdown.val());
42-
if(multiSelect.checked) {
43-
type.val(saveTypes[index] + '[]');
44-
} else {
45-
type.val(saveTypes[index]);
46-
}
47-
}
48-
// triggered when dialog is launched
49-
updateSaveValueType();
50-
saveValueDropdown.on("change", function() {
51-
updateSaveValueType();
52-
});
53-
multiSelect.on("change", function() {
54-
updateSaveValueType();
55-
});
56-
}
57-
5828
/**
5929
* Handles the default value field in the dialog appropriately when multi-select is toggled.
6030
* @param {HTMLElement} dialog The dialog on which the operation is to be performed.
@@ -124,5 +94,5 @@
12494
}
12595
);
12696

127-
Utils.initializeEditDialog(EDIT_DIALOG)(handleSaveValueDropDown, handleDefaultValue, registerDialogValidator);
97+
Utils.initializeEditDialog(EDIT_DIALOG)(handleDefaultValue, registerDialogValidator);
12898
})(jQuery);

0 commit comments

Comments
 (0)