PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
← All changes | includes/Frontend/Form/View/InputWrapper.php +175 -86 2.10.13.3.1 View file →
@@ -15,8 +15,11 @@
15 15 private $_fieldHelpers;
16 16
17 17 public function __construct($field, $rowID, $field_name, $form_atomic_Cls_map, $formID, $error = null, $value = null)
18 18 {
19 + // Corrupt/partial form JSON can hand us a null field; normalize so
20 + // property_exists() calls never receive null (PHP 8 TypeError).
21 + $field = is_object($field) ? $field : new \stdClass();
19 22 $this->_fieldData = $field;
20 23 $this->_fieldKey = $rowID;
21 24 $this->_fieldName = $field_name;
22 25 $this->_formID = $formID;
@@ -29,26 +32,31 @@
29 32 {
30 33 $labelWrapper = !$noLabel ? $this->labelWrapper() : '';
31 34 $helperText = $this->helperText();
32 35 $error = !$noErrMsg ? $this->errorMessages() : '';
33 - $inputWrapper = <<<INPUTWRAPPER
34 - <div
35 - {$this->_fieldHelpers->getCustomAttributes('fld-wrp')}
36 - class="{$this->_fieldHelpers->getAtomicCls('fld-wrp')} {$this->_fieldHelpers->getCustomClasses('fld-wrp')}"
37 - >
38 - {$labelWrapper}
39 - <div
40 - {$this->_fieldHelpers->getCustomAttributes('inp-wrp')}
41 - class="{$this->_fieldHelpers->getAtomicCls('inp-wrp')} {$this->_fieldHelpers->getCustomClasses('inp-wrp')}"
42 - >
43 - {$field}
44 - {$helperText}
45 - {$error}
46 - </div>
47 - </div>
48 -INPUTWRAPPER;
36 + $fieldTypeClass = empty($this->_fieldData->typ) ? 'bf-default-field' : 'bf-' . $this->_fieldData->typ . '-field';
49 37
50 - return $inputWrapper;
38 + return sprintf(
39 + '<div %1$s class="%2$s %3$s %4$s">
40 + %5$s
41 + <div %6$s class="%7$s %8$s">
42 + %9$s
43 + %10$s
44 + %11$s
45 + </div>
46 + </div>',
47 + $this->_fieldHelpers->getCustomAttributes('fld-wrp'),
48 + $fieldTypeClass,
49 + $this->_fieldHelpers->getAtomicCls('fld-wrp'),
50 + $this->_fieldHelpers->getCustomClasses('fld-wrp'),
51 + $labelWrapper,
52 + $this->_fieldHelpers->getCustomAttributes('inp-wrp'),
53 + $this->_fieldHelpers->getAtomicCls('inp-wrp'),
54 + $this->_fieldHelpers->getCustomClasses('inp-wrp'),
55 + $field,
56 + $helperText,
57 + $error
58 + );
51 59 }
52 60
53 61 private function labelWrapper()
54 62 {
@@ -72,36 +80,37 @@
72 80 $_subtitleText = wp_kses_post($this->_fieldHelpers->renderHTMR($replaceToBackSlash));
73 81 }
74 82
75 83 // for pre required icon
84 + // aria-hidden="true" is used because the asterisk is purely decorative/visual.
85 + // Screen readers will announce the field as required via aria-required="true" on the input element.
86 + // This prevents redundant "asterisk" or "star" announcements.
76 87 if (
77 88 $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->req')
78 89 && $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->reqShow', true)
79 90 && $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->reqPos', 'before')
80 91 ) {
81 - $_reqPre = <<<REQPRE
82 - <span
83 - {$this->_fieldHelpers->getCustomAttributes('req-smbl')}
84 - class="{$this->_fieldHelpers->getAtomicCls('req-smbl')} {$this->_fieldHelpers->getCustomClasses('req-smbl')}"
85 - >
86 - *
87 - </span>
88 -REQPRE;
92 + $_reqPre = sprintf(
93 + '<span %1$s class="%2$s %3$s" aria-hidden="true">*</span>',
94 + $this->_fieldHelpers->getCustomAttributes('req-smbl'),
95 + $this->_fieldHelpers->getAtomicCls('req-smbl'),
96 + $this->_fieldHelpers->getCustomClasses('req-smbl')
97 + );
89 98 }
90 99 // for post required icon
100 + // Same accessibility reasoning as pre required icon - hide from screen readers
101 + // to avoid redundant announcements since aria-required is on the input.
91 102 if (
92 103 $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->req')
93 104 && $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->reqShow', true)
94 105 && $this->_fieldHelpers->property_exists_nested($this->_fieldData, 'valid->reqPos', 'before', 1)
95 106 ) {
96 - $_reqPost = <<<REQPOST
97 - <span
98 - {$this->_fieldHelpers->getCustomAttributes('req-smbl')}
99 - class="{$this->_fieldHelpers->getAtomicCls('req-smbl')} {$this->_fieldHelpers->getCustomClasses('req-smbl')}"
100 - >
101 - *
102 - </span>
103 -REQPOST;
107 + $_reqPost = sprintf(
108 + '<span %1$s class="%2$s %3$s" aria-hidden="true">*</span>',
109 + $this->_fieldHelpers->getCustomAttributes('req-smbl'),
110 + $this->_fieldHelpers->getAtomicCls('req-smbl'),
111 + $this->_fieldHelpers->getCustomClasses('req-smbl')
112 + );
104 113 }
105 114
106 115 // for Label
107 116 if (
@@ -110,44 +119,56 @@
110 119 // && $this->_fieldData->valid->hideLbl !== true
111 120 ) {
112 121 $bfFrontendFormIds = FrontendHelpers::$bfFrontendFormIds;
113 122 $contentCount = count($bfFrontendFormIds);
114 - $_label = <<<LABEL
115 - <label
116 - {$this->_fieldHelpers->getCustomAttributes('lbl')}
117 - class="{$this->_fieldHelpers->getAtomicCls('lbl')} {$this->_fieldHelpers->getCustomClasses('lbl')}"
118 - for="{$this->_fieldKey}-{$contentCount}">
119 - {$_reqPre}
120 - {$_lblPreIcn}
121 - {$_lbl}
122 - {$_lblSufIcn}
123 - {$_reqPost}
124 - </label>
125 -LABEL;
123 + $labelId = $this->_fieldHelpers->getLabelId();
124 + $_label = sprintf(
125 + '<label
126 + id="%1$s"
127 + %2$s
128 + class="%3$s %4$s"
129 + for="%5$s-%6$d">
130 + %7$s
131 + %8$s
132 + %9$s
133 + %10$s
134 + %11$s
135 + </label>',
136 + $labelId,
137 + $this->_fieldHelpers->getCustomAttributes('lbl'),
138 + $this->_fieldHelpers->getAtomicCls('lbl'),
139 + $this->_fieldHelpers->getCustomClasses('lbl'),
140 + $this->_fieldKey,
141 + $contentCount,
142 + $_reqPre,
143 + $_lblPreIcn,
144 + $_lbl,
145 + $_lblSufIcn,
146 + $_reqPost
147 + );
126 148 }
127 149
128 150 // for subtitle
129 - if (property_exists($this->_fieldData, 'subtitle') && $this->_fieldData->subtitleHide) {
130 - $_subtitle = <<<SUBTITLE
131 - <div
132 - {$this->_fieldHelpers->getCustomAttributes('sub-titl')}
133 - class="{$this->_fieldHelpers->getAtomicCls('sub-titl')} {$this->_fieldHelpers->getCustomClasses('sub-titl')}"
134 - >
135 - {$_subtitlePreIcn}
136 - {$_subtitleText}
137 - {$_subtitlePostIcn}
138 - </div>
139 -SUBTITLE;
151 + if (property_exists($this->_fieldData, 'subtitle') && !empty($this->_fieldData->subtitleHide)) {
152 + $_subtitle = sprintf(
153 + '<div %1$s class="%2$s %3$s">%4$s%5$s%6$s</div>',
154 + $this->_fieldHelpers->getCustomAttributes('sub-titl'),
155 + $this->_fieldHelpers->getAtomicCls('sub-titl'),
156 + $this->_fieldHelpers->getCustomClasses('sub-titl'),
157 + $_subtitlePreIcn,
158 + $_subtitleText,
159 + $_subtitlePostIcn
160 + );
140 161 }
141 - return <<<LABELWRAPPER
142 - <div
143 - {$this->_fieldHelpers->getCustomAttributes('lbl-wrp')}
144 - class="{$this->_fieldHelpers->getAtomicCls('lbl-wrp')} {$this->_fieldHelpers->getCustomClasses('lbl-wrp')}"
145 - >
146 - {$_label}
147 - {$_subtitle}
148 - </div>
149 -LABELWRAPPER;
162 +
163 + return sprintf(
164 + '<div %1$s class="%2$s %3$s">%4$s%5$s</div>',
165 + $this->_fieldHelpers->getCustomAttributes('lbl-wrp'),
166 + $this->_fieldHelpers->getAtomicCls('lbl-wrp'),
167 + $this->_fieldHelpers->getCustomClasses('lbl-wrp'),
168 + $_label,
169 + $_subtitle
170 + );
150 171 }
151 172
152 173 private function helperText()
153 174 {
@@ -159,18 +180,27 @@
159 180 $_helperTxt = wp_kses_post($this->_fieldHelpers->renderHTMR($this->_fieldData->helperTxt));
160 181 }
161 182
162 183 if (property_exists($this->_fieldData, 'helperTxt') && $this->_fieldData->helperTxt) {
163 - $_helperTxt = <<<HELPERTEXT
164 - <div
165 - {$this->_fieldHelpers->getCustomAttributes('hlp-txt')}
166 - class="{$this->_fieldHelpers->getAtomicCls('hlp-txt')} {$this->_fieldHelpers->getCustomClasses('hlp-txt')}"
167 - >
168 - {$_helperTxtPreIcn}
169 - {$_helperTxt}
170 - {$_helperTxtSufIcn}
171 - </div>
172 -HELPERTEXT;
184 + $helperTextId = $this->_fieldHelpers->getHelperTextId();
185 + $_helperTxt = sprintf(
186 + '<div
187 + id="%1$s"
188 + %2$s
189 + class="%3$s %4$s"
190 + >
191 + %5$s
192 + %6$s
193 + %7$s
194 + </div>',
195 + $helperTextId,
196 + $this->_fieldHelpers->getCustomAttributes('hlp-txt'),
197 + $this->_fieldHelpers->getAtomicCls('hlp-txt'),
198 + $this->_fieldHelpers->getCustomClasses('hlp-txt'),
199 + $_helperTxtPreIcn,
200 + $_helperTxt,
201 + $_helperTxtSufIcn
202 + );
173 203 }
174 204
175 205 // for helper text
176 206 return $_helperTxt;
@@ -187,8 +217,9 @@
187 217 $_error = wp_kses_post($this->_error);
188 218 $_style = 'margin-top: 5px !important; height: 9px !important;';
189 219 }
190 220
221 + $errorId = $this->_fieldHelpers->getErrorId();
191 222 $errMsgStart = '';
192 223 $errMsgEnd = '';
193 224 $msgStyle = "style='display: none !important;'";
194 225 $errMsgAtomicCls = $this->_fieldHelpers->getAtomicCls('err-msg');
@@ -202,17 +233,75 @@
202 233 $errMsgCustomCls = '';
203 234 $errMsgCustomAttr = '';
204 235 }
205 236
206 - return <<<ERRORMESSAGES
207 - <div class='{$this->_fieldHelpers->getAtomicCls('err-wrp')}' style="{$_style}">
208 - <div class='{$this->_fieldHelpers->getAtomicCls('err-inner')}'>
209 - {$errMsgStart}
210 - {$_errorPreIcn}
211 - <div {$this->_fieldHelpers->getCustomAttributes('err-txt')} {$errMsgCustomAttr} class="{$errMsgAtomicCls} {$errMsgCustomCls} {$this->_fieldHelpers->getAtomicCls('err-txt')} {$this->_fieldHelpers->getCustomClasses('err-txt')}" {$msgStyle}>{$_error}</div>
212 - {$_errorSufIcn}
213 - {$errMsgEnd}
214 - </div>
215 - </div>
216 -ERRORMESSAGES;
237 + return sprintf(
238 + '<div class="%1$s" role="alert" aria-atomic="true" aria-live="assertive" style="%2$s">
239 + <div class="%3$s">
240 + %4$s
241 + %5$s
242 + <div
243 + id="%6$s"
244 + %7$s
245 + %8$s
246 + class="%9$s %10$s %11$s %12$s "
247 + %13$s
248 + >
249 + %14$s
250 + </div>
251 + %15$s
252 + %16$s
253 + </div>
254 + </div>',
255 + $this->_fieldHelpers->getAtomicCls('err-wrp'), // 1
256 + $_style, // 2
257 + $this->_fieldHelpers->getAtomicCls('err-inner'), // 3
258 + $errMsgStart, // 4
259 + $_errorPreIcn, // 5
260 + $errorId, // 6
261 + $this->_fieldHelpers->getCustomAttributes('err-txt'), // 7
262 + $errMsgCustomAttr, // 8
263 + $errMsgAtomicCls, // 9
264 + $errMsgCustomCls, // 10
265 + $this->_fieldHelpers->getAtomicCls('err-txt'), // 11
266 + $this->_fieldHelpers->getCustomClasses('err-txt'), // 12
267 + $msgStyle, // 13
268 + $_error, // 14
269 + $_errorSufIcn, // 15
270 + $errMsgEnd // 16
271 + );
272 + }
273 +
274 + /**
275 + * Get the field helpers instance for external access
276 + * @return FieldHelpers
277 + */
278 + public function getFieldHelpers()
279 + {
280 + return $this->_fieldHelpers;
281 + }
282 +
283 + public function parentFieldWrapper($childFieldsInput)
284 + {
285 + return '<div '
286 + . $this->_fieldHelpers->getCustomAttributes('parent-fld-wrp')
287 + . ' class="' . $this->_fieldHelpers->getAtomicCls('parent-fld-wrp') . ' ' . $this->_fieldHelpers->getCustomClasses('parent-fld-wrp') . '">'
288 + . $childFieldsInput
289 + . '</div>';
290 + }
291 +
292 + public function childFieldWrapper($fieldInput, $subFieldName = '', $colSpan = null, $childKey = '')
293 + {
294 + $dataAttr = $subFieldName ? ' data-bf-subfield="' . esc_attr($subFieldName) . '"' : '';
295 + $styleAttr = null !== $colSpan ? ' style="--bfv-addr-col:' . (int) $colSpan . '"' : '';
296 + // Per-child class so conditional actions (show/hide) can collapse the whole column.
297 + $childKeyCls = $childKey ? ' ' . esc_attr($childKey) . '-sub-fld-wrp' : '';
298 + return '<div'
299 + . $dataAttr
300 + . $styleAttr
301 + . ' '
302 + . $this->_fieldHelpers->getCustomAttributes('child-fld-wrp')
303 + . ' class="' . $this->_fieldHelpers->getAtomicCls('child-fld-wrp') . ' ' . $this->_fieldHelpers->getCustomClasses('child-fld-wrp') . $childKeyCls . '">'
304 + . $fieldInput
305 + . '</div>';
217 306 }
218 307 }