Skip to content

Commit 126abfa

Browse files
authored
Empty value (#1654)
* Empty value fix * Empty value fix * Adding test cases * Fixing package info
1 parent 4e714b3 commit 126abfa

File tree

7 files changed

+167
-2
lines changed

7 files changed

+167
-2
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_EMPTY_VALUE = "fd:emptyValue";
7778
public static final String PN_MULTI_DEFAULT_VALUES = "fd:multiDefaultValues";
7879
public static final String PN_FORMAT = "format";
7980
public static final String PN_DISPLAY_FORMAT = "displayFormat";

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ default Object[] getDefault() {
9898
return null;
9999
}
100100

101+
/**
102+
* The value that represents an empty state for the field.
103+
* This can be used to distinguish between null, empty string, or undefined values.
104+
*
105+
* Valid values for this property are:
106+
* - "null" - represents null value
107+
* - "undefined" - represents undefined value
108+
* - "" - represents empty string
109+
*
110+
*
111+
* @return empty value representation for the field
112+
* @since com.adobe.cq.forms.core.components.models.form 5.12.1
113+
*/
114+
@Nullable
115+
default String getEmptyValue() {
116+
return null;
117+
}
118+
101119
/**
102120
* The expression that when evaluated would determine what the displayValue of a field would be
103121
*

bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* </p>
3636
*/
3737

38-
@Version("5.12.0")
38+
@Version("5.12.1")
3939
package com.adobe.cq.forms.core.components.models.form;
4040

4141
import org.osgi.annotation.versioning.Version;

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,42 @@
3838
*/
3939
public abstract class AbstractFieldImpl extends AbstractBaseImpl implements Field {
4040

41+
/**
42+
* Enum representing the possible values for emptyValue property.
43+
*/
44+
public static enum EmptyValue {
45+
NULL("null"),
46+
UNDEFINED("undefined"),
47+
EMPTY_STRING("");
48+
49+
private final String value;
50+
51+
EmptyValue(String value) {
52+
this.value = value;
53+
}
54+
55+
public String getValue() {
56+
return value;
57+
}
58+
59+
/**
60+
* Converts a string value to EmptyValue enum.
61+
* Returns EMPTY_STRING for any unrecognized values.
62+
*/
63+
public static EmptyValue fromString(String value) {
64+
if (value == null) {
65+
return null;
66+
}
67+
for (EmptyValue emptyValue : EmptyValue.values()) {
68+
if (emptyValue.getValue().equals(value)) {
69+
return emptyValue;
70+
}
71+
}
72+
// Default to empty string for any unrecognized values
73+
return EMPTY_STRING;
74+
}
75+
}
76+
4177
private static final Logger logger = LoggerFactory.getLogger(AbstractFieldImpl.class);
4278

4379
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_READ_ONLY)
@@ -49,6 +85,11 @@ public abstract class AbstractFieldImpl extends AbstractBaseImpl implements Fiel
4985
@Nullable
5086
protected Object[] defaultValue;
5187

88+
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_EMPTY_VALUE)
89+
@Nullable
90+
@JsonInclude(JsonInclude.Include.NON_NULL)
91+
protected String emptyValue;
92+
5293
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_PLACEHOLDER)
5394
@Nullable
5495
protected String placeholder;
@@ -160,6 +201,16 @@ public Object[] getDefault() {
160201
return null;
161202
}
162203

204+
@Override
205+
@Nullable
206+
public String getEmptyValue() {
207+
if (emptyValue == null) {
208+
return null;
209+
}
210+
EmptyValue enumValue = EmptyValue.fromString(emptyValue);
211+
return enumValue != null ? enumValue.getValue() : EmptyValue.EMPTY_STRING.getValue();
212+
}
213+
163214
@Override
164215
@Nullable
165216
public String getPlaceHolder() {

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.adobe.cq.forms.core.components.datalayer.FormComponentData;
3333
import com.adobe.cq.forms.core.components.internal.form.FormConstants;
3434
import com.adobe.cq.forms.core.components.models.form.*;
35+
import com.adobe.cq.forms.core.components.util.AbstractFieldImpl;
3536
import com.adobe.cq.forms.core.components.util.AbstractFormComponentImpl;
3637
import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext;
3738
import com.adobe.cq.wcm.style.ComponentStyleInfo;
@@ -64,6 +65,11 @@ public class TextInputImplTest {
6465
private static final String PATH_TEXTINPUT_PLACEHOLDER_AUTOCOMPLETE = CONTENT_ROOT + "/textinput-placeholder-autocomplete";
6566
private static final String PATH_TEXTINPUT_WITH_VIEWTYPE = CONTENT_ROOT + "/textinput-with-viewtype";
6667
private static final String PATH_TEXTINPUT_WITHOUT_FIELDTYPE = CONTENT_ROOT + "/textinput-without-fieldtype";
68+
private static final String PATH_TEXTINPUT_EMPTYVALUE_NULL = CONTENT_ROOT + "/textinput-emptyvalue-null";
69+
private static final String PATH_TEXTINPUT_EMPTYVALUE_UNDEFINED = CONTENT_ROOT + "/textinput-emptyvalue-undefined";
70+
private static final String PATH_TEXTINPUT_EMPTYVALUE_EMPTY_STRING = CONTENT_ROOT + "/textinput-emptyvalue-empty-string";
71+
private static final String PATH_TEXTINPUT_EMPTYVALUE_INVALID = CONTENT_ROOT + "/textinput-emptyvalue-invalid";
72+
private static final String PATH_TEXTINPUT_EMPTYVALUE_NOT_SET = CONTENT_ROOT + "/textinput-emptyvalue-not-set";
6773

6874
private final AemContext context = FormsCoreComponentTestContext.newAemContext();
6975

@@ -517,4 +523,57 @@ void testNoFieldType() {
517523
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_WITHOUT_FIELDTYPE, TextInput.class, context);
518524
assertEquals(FieldType.TEXT_INPUT.getValue(), textInput.getFieldType());
519525
}
526+
527+
@Test
528+
void testEmptyValueNull() {
529+
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_EMPTYVALUE_NULL, TextInput.class, context);
530+
assertEquals("null", textInput.getEmptyValue());
531+
}
532+
533+
@Test
534+
void testEmptyValueUndefined() {
535+
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_EMPTYVALUE_UNDEFINED, TextInput.class, context);
536+
assertEquals("undefined", textInput.getEmptyValue());
537+
}
538+
539+
@Test
540+
void testEmptyValueEmptyString() {
541+
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_EMPTYVALUE_EMPTY_STRING, TextInput.class, context);
542+
assertEquals("", textInput.getEmptyValue());
543+
}
544+
545+
@Test
546+
void testEmptyValueInvalidDefaultsToEmptyString() {
547+
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_EMPTYVALUE_INVALID, TextInput.class, context);
548+
assertEquals("", textInput.getEmptyValue()); // Should default to empty string for invalid values
549+
}
550+
551+
@Test
552+
void testEmptyValueNotSet() {
553+
TextInput textInput = Utils.getComponentUnderTest(PATH_TEXTINPUT_EMPTYVALUE_NOT_SET, TextInput.class, context);
554+
assertEquals(null, textInput.getEmptyValue()); // Should return null when property is not set
555+
}
556+
557+
@Test
558+
void testEmptyValueEnumFromString() {
559+
// Test the enum's fromString method directly
560+
assertEquals(AbstractFieldImpl.EmptyValue.NULL,
561+
AbstractFieldImpl.EmptyValue.fromString("null"));
562+
assertEquals(AbstractFieldImpl.EmptyValue.UNDEFINED,
563+
AbstractFieldImpl.EmptyValue.fromString("undefined"));
564+
assertEquals(AbstractFieldImpl.EmptyValue.EMPTY_STRING,
565+
AbstractFieldImpl.EmptyValue.fromString(""));
566+
assertEquals(AbstractFieldImpl.EmptyValue.EMPTY_STRING,
567+
AbstractFieldImpl.EmptyValue.fromString("invalid-value"));
568+
assertEquals(null,
569+
AbstractFieldImpl.EmptyValue.fromString(null));
570+
}
571+
572+
@Test
573+
void testEmptyValueEnumGetValue() {
574+
// Test the enum's getValue method
575+
assertEquals("null", AbstractFieldImpl.EmptyValue.NULL.getValue());
576+
assertEquals("undefined", AbstractFieldImpl.EmptyValue.UNDEFINED.getValue());
577+
assertEquals("", AbstractFieldImpl.EmptyValue.EMPTY_STRING.getValue());
578+
}
520579
}

bundles/af-core/src/test/resources/form/textinput/exporter-textinput-format.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"constraintMessages": {
1212
"type": "incorrect type"
1313
},
14+
"emptyValue": "null",
1415
"readOnly": false,
1516
"format": "email",
1617
"default": "abc",

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@
111111
"fieldType": "text-input",
112112
"readOnly": false,
113113
"enabled": true,
114-
"format" : "email"
114+
"format" : "email",
115+
"fd:emptyValue" : "null"
115116
},
116117
"textinput-datalayer" : {
117118
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
@@ -202,5 +203,39 @@
202203
"jcr:title" : "def",
203204
"placeholder": "test-placeholder",
204205
"fd:viewType": "some/custom/value"
206+
},
207+
"textinput-emptyvalue-null" : {
208+
"jcr:primaryType": "nt:unstructured",
209+
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
210+
"name" : "abc",
211+
"jcr:title" : "def",
212+
"fd:emptyValue": "null"
213+
},
214+
"textinput-emptyvalue-undefined" : {
215+
"jcr:primaryType": "nt:unstructured",
216+
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
217+
"name" : "abc",
218+
"jcr:title" : "def",
219+
"fd:emptyValue": "undefined"
220+
},
221+
"textinput-emptyvalue-empty-string" : {
222+
"jcr:primaryType": "nt:unstructured",
223+
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
224+
"name" : "abc",
225+
"jcr:title" : "def",
226+
"fd:emptyValue": ""
227+
},
228+
"textinput-emptyvalue-invalid" : {
229+
"jcr:primaryType": "nt:unstructured",
230+
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
231+
"name" : "abc",
232+
"jcr:title" : "def",
233+
"fd:emptyValue": "invalid-value"
234+
},
235+
"textinput-emptyvalue-not-set" : {
236+
"jcr:primaryType": "nt:unstructured",
237+
"sling:resourceType" : "core/fd/components/form/textinput/v1/textinput",
238+
"name" : "abc",
239+
"jcr:title" : "def"
205240
}
206241
}

0 commit comments

Comments
 (0)