@@ -177,4 +177,138 @@ Qualtrics.SurveyEngine.addOnReady(function () {
177177 matrix .addEventListener (" input" , validateRows);
178178 matrix .addEventListener (" change" , validateRows);
179179});
180- ```
180+ ```
181+
182+ ## Script to grey out Next button
183+ ``` javascript
184+ Qualtrics .SurveyEngine .addOnReady (function () {
185+ console .log (" ✅ SBS script running for" , this .questionId );
186+
187+ /* ------------------------------------------------------------------
188+ 1. === your original per-row formatting + checkbox-hide logic ===
189+ (unchanged except for one comment line to show where it ends)
190+ ------------------------------------------------------------------ */
191+
192+ var matrix = this .getQuestionContainer ();
193+ var rows = matrix .querySelectorAll (" tr.Choice" ); // works in your SBS
194+ var that = this ;
195+
196+ var headerCell = matrix .querySelector (" th" );
197+ if (headerCell) headerCell .style .width = " 300px" ;
198+
199+ for (var r = 0 ; r < rows .length ; r++ ) {
200+ (function (row ) {
201+ var cells = row .querySelectorAll (" td" );
202+ if (cells .length < 9 ) return ;
203+
204+ var textCell = cells[2 ]; // text input
205+ var dropdownCell = cells[5 ]; // dropdown
206+ var checkboxCell = cells[8 ]; // checkbox
207+ var checkbox = checkboxCell .querySelector (" input[type='checkbox']" );
208+ var inputField = textCell .querySelector (" input[type='text']" );
209+ var dropdownFld = dropdownCell .querySelector (" select" );
210+
211+ var labelCell = row .querySelector (" td:first-child" );
212+ if (labelCell) labelCell .style .width = " 300px" ;
213+
214+ textCell .style .width = " 100px" ;
215+ dropdownCell .style .width = " 160px" ;
216+ checkboxCell .style .width = " 120px" ;
217+ checkboxCell .style .textAlign = " center" ;
218+ textCell .style .borderRight = " none" ;
219+ dropdownCell .style .borderRight = " none" ;
220+
221+ for (var i = 0 ; i < cells .length ; i++ ) {
222+ if (cells[i].className .indexOf (" Separator" ) !== - 1 ) {
223+ cells[i].style .display = " " ;
224+ cells[i].style .minWidth = " 1px" ;
225+ cells[i].style .width = " 1px" ;
226+ cells[i].style .borderRight = " 1px solid #ccc" ;
227+ cells[i].style .borderLeft = " none" ;
228+ if (cells[i].innerHTML .trim () === " " ) cells[i].innerHTML = " " ;
229+ }
230+ }
231+
232+ // -- initial hide if checkbox pre-checked
233+ if (checkbox && checkbox .checked ) {
234+ textCell .style .visibility = " hidden" ;
235+ dropdownCell .style .visibility = " hidden" ;
236+ textCell .style .border = " none" ;
237+ dropdownCell .style .border = " none" ;
238+ if (inputField) inputField .value = " " ;
239+ if (dropdownFld) dropdownFld .selectedIndex = 0 ;
240+ }
241+
242+ // -- live hide/show when checkbox toggled
243+ if (checkbox) {
244+ checkbox .addEventListener (" change" , function () {
245+ var hide = checkbox .checked ;
246+
247+ textCell .style .visibility = hide ? " hidden" : " visible" ;
248+ dropdownCell .style .visibility = hide ? " hidden" : " visible" ;
249+ textCell .style .border = hide ? " none" : " " ;
250+ dropdownCell .style .border = hide ? " none" : " " ;
251+
252+ if (hide) {
253+ if (inputField) inputField .value = " " ;
254+ if (dropdownFld) dropdownFld .selectedIndex = 0 ;
255+ }
256+ });
257+ }
258+ })(rows[r]);
259+ }
260+ /* ------------------------ end original section ------------------- */
261+
262+
263+ /* ------------------------------------------------------------------
264+ 2. === global “all 3 blocks must be complete” validation =========
265+ ------------------------------------------------------------------ */
266+
267+ /* create the shared tracker once (first time any block loads) */
268+ if (! window .SBSCompletion ) {
269+ window .SBSCompletion = { " QID1" : false , " QID10" : false , " QID12" : false };
270+ }
271+
272+ function rowIsValid (cells ) {
273+ var textInput = cells[2 ].querySelector (" input[type='text']" );
274+ var dropdown = cells[5 ].querySelector (" select" );
275+ var checkbox = cells[8 ].querySelector (" input[type='checkbox']" );
276+
277+ var inputHas = textInput && textInput .value .trim () !== " " ;
278+ var dropHas = dropdown && dropdown .value .trim () !== " " ;
279+ var checkHas = checkbox && checkbox .checked ;
280+
281+ return (inputHas && dropHas) || checkHas;
282+ }
283+
284+ function validateThisBlock () {
285+ var everyRowValid = true ;
286+ for (var r = 0 ; r < rows .length ; r++ ) {
287+ var cells = rows[r].querySelectorAll (" td" );
288+ if (cells .length < 9 ) continue ;
289+ if (! rowIsValid (cells)) { everyRowValid = false ; }
290+ }
291+
292+ /* store this block’s status */
293+ window .SBSCompletion [that .questionId ] = everyRowValid;
294+
295+ /* check all three blocks */
296+ var allDone = window .SBSCompletion [" QID1" ] &&
297+ window .SBSCompletion [" QID10" ] &&
298+ window .SBSCompletion [" QID12" ];
299+
300+ if (allDone) { that .enableNextButton (); }
301+ else { that .disableNextButton (); }
302+ }
303+
304+ /* disable Next on first load */
305+ that .disableNextButton ();
306+
307+ /* delay initial validation slightly to ensure elements are rendered */
308+ setTimeout (validateThisBlock, 100 ); // 100ms delay ensures all DOM elements are accessible
309+
310+ /* attach listeners */
311+ matrix .addEventListener (" input" , validateThisBlock);
312+ matrix .addEventListener (" change" , validateThisBlock);
313+ });
314+ ```
0 commit comments