1+ // app/filters/form-attributes.js
2+
3+ const _ = require ( 'lodash' )
4+
5+ /**
6+ * Decorate attributes
7+ * Add name, value, id, idPrefix and checked attributes to NHSUK form components
8+ * Generate the attributes based on the application ID and the section they're in
9+ *
10+ * @param {Object } originalObject - The original component configuration
11+ * @param {Object } data - The data object to extract values from
12+ * @param {string } path - Path to the data property (e.g. "data.nationality")
13+ * @returns {Object } The decorated component configuration
14+ *
15+ * @example
16+ * {{ nhsukCheckboxes({
17+ * fieldset: {
18+ * legend: {
19+ * text: "Nationality",
20+ * classes: "nhsuk-fieldset__legend--s"
21+ * }
22+ * },
23+ * items: [
24+ * {
25+ * text: "British"
26+ * },
27+ * {
28+ * text: "Irish"
29+ * },
30+ * {
31+ * text: "Other"
32+ * }
33+ * ]
34+ * } | decorateAttributes(data, "data.nationality")) }}
35+ */
36+ const decorateAttributes = ( originalObject , data , path ) => {
37+ // Deep clone to avoid modifying the original object
38+ const obj = _ . cloneDeep ( originalObject )
39+
40+ // Map dot or bracket notation to path parts
41+ const pathParts = _ . toPath ( path )
42+
43+ // Strip 'data' prefix if present
44+ let dataPath = [ ...pathParts ]
45+ if ( pathParts [ 0 ] === 'data' ) {
46+ dataPath = dataPath . slice ( 1 )
47+ }
48+
49+ // Get the stored value from data
50+ const storedValue = _ . get ( data , dataPath )
51+
52+ if ( obj . items !== undefined ) {
53+ obj . items = obj . items . map ( item => {
54+ // Skip dividers
55+ if ( item . divider ) return item
56+
57+ // Set default value to text if not provided
58+ if ( typeof item . value === 'undefined' ) {
59+ item . value = item . text
60+ }
61+
62+ // Default checked/selected states when no data exists
63+ let checked = item . checked
64+ let selected = item . selected
65+
66+ // Only process if we have a stored value to compare against
67+ if ( storedValue !== undefined ) {
68+ // For array values (like checkboxes)
69+ if ( Array . isArray ( storedValue ) ) {
70+ if ( storedValue . includes ( item . value ) ) {
71+ checked = 'checked'
72+ selected = 'selected'
73+ } else {
74+ // Clear any default checked state when we have data
75+ checked = ''
76+ selected = ''
77+ }
78+ } else {
79+ // For single values (like radios)
80+ if ( storedValue === item . value ) {
81+ checked = 'checked'
82+ selected = 'selected'
83+ } else {
84+ // Clear any default checked state when we have data
85+ checked = ''
86+ selected = ''
87+ }
88+ }
89+ }
90+
91+ // Assign the computed values
92+ item . checked = checked
93+ item . selected = selected
94+
95+ return item
96+ } )
97+
98+ // Set idPrefix if not already defined
99+ obj . idPrefix = obj . idPrefix || pathParts . join ( '-' )
100+ } else {
101+ // For non-array components (like text inputs),
102+ // set the value if not already defined
103+ if ( typeof obj . value === 'undefined' ) {
104+ obj . value = storedValue
105+ }
106+ }
107+
108+ // Set id and name attributes if not already defined
109+ obj . id = obj . id || pathParts . join ( '-' )
110+ obj . name = obj . name || pathParts . map ( s => `[${ s } ]` ) . join ( '' )
111+ console . log ( "Object name:" , obj . name )
112+ return obj
113+ }
114+
115+ module . exports = {
116+ decorateAttributes
117+ }
0 commit comments