Build a Sorting Visualizer - Build a Sorting Visualizer

if you want help you need to share your updated code

Heres my updated js code

/* file: script.js */

/

/******************************************/

//***

//***

//*** Functions

//***

//***

//******************************************/




function generateElement() {

let random = Math.floor(Math.random() * 100) + 1;

return random;

}




function generateArray() {

const arr = [];

while (arr.length < 5) {

arr.push(generateElement());

  }

return arr;

}




function generateSpanContainer() {

const span = document.createElement('span');

span.innerHTML = ``;

return span;

}




function generateContainer() {

const div = document.createElement('div');

div.innerHTML = ``;

return div;

}




function fillArrContainer(el, arr) {

for (let i = 0; i < 5; i++) {

let span = generateSpanContainer();

span.innerHTML = `${arr[i]}`;

el.appendChild(span);

  }

}




function isOrdered(int1, int2) {

return int1 <= int2 ? true : false;

}




function swapElements(arr, index) {

if (!isOrdered(arr[index], arr[index + 1])) {

let int1 = arr[index];

let int2 = arr[index + 1];

arr[index] = int2;

arr[index + 1] = int1;

  }

}




function highlightCurrentEls(el, index) {

const childEl1 = el.children[index];

const childEl2 = el.children[index + 1];

const children = [childEl1, childEl2];

children.forEach((child) => {

child.style.borderColor = "red";

child.style.borderWidth = "2px";

child.style.borderStyle = "dashed";

  })

}




//******************************************/

//***

//***

//*** DOM and Variable

//***

//***

//******************************************/




let array = [];




const generateBtn = document.getElementById("generate-btn");

const sortBtn = document.getElementById("sort-btn");

const arrayContainer = document.getElementById("array-container");

const startingArrayEl = document.getElementById("starting-array");




sortBtn.setAttribute('hidden', '');




//******************************************/

//***

//***

//*** Event Listeners

//***

//***

//******************************************/




generateBtn.addEventListener("click", () => {

// Remove all children except the starting-array

while (arrayContainer.children.length > 1) {

arrayContainer.removeChild(arrayContainer.lastElementChild);

  }

// Clear the starting array

startingArrayEl.innerHTML = ``;

// Generate new array

array = generateArray();

// Fill the starting array with new numbers

fillArrContainer(startingArrayEl, array);

// Show the sort button

sortBtn.removeAttribute('hidden');

})




sortBtn.addEventListener("click", () => {

// Highlight the first two elements in starting array (Test 21)

highlightCurrentEls(startingArrayEl, 0);

// Implement Bubble Sort with visualization

let n = array.length;

// Bubble sort algorithm

for (let i = 0; i < n - 1; i++) {

for (let j = 0; j < n - i - 1; j++) {

// Perform the swap (if needed)

swapElements(array, j);

// Create a new div showing the current state AFTER the swap

let div = generateContainer();

fillArrContainer(div, array);

// Highlight the elements that will be compared next

// (unless this is the last comparison)

if (j + 1 < n - i - 1) {

highlightCurrentEls(div, j + 1);

      }

// Add this step to the container

arrayContainer.appendChild(div);

    }

  }

// Hide the sort button

sortBtn.setAttribute('hidden', '');

})

Congrats on getting the sortBtn handled.

What’s the maximum number of times your outer loop should cycle? Look carefully at this code. Does this loop the number of times expected? Use console.log() to look at how your loop variable is incrementing.

How many pairs of numbers in the array should be checked in each cycle to see if they need to be swapped? Does this loop run the number of times expected? Again, use console.log() to look at your loop variable.

I’m ever so close I need to validate this div element to pass.

Please assist me on this last step

always post your updated code when asking for further help…we are not mind readers…well, i mean, maybe ILM is. :slight_smile:

Ok lol! I’ve only got steps 18 and 19 to complete as shown here,

Here’s my updated code from a reset

// --------------------

// Required Functions

// --------------------




function generateElement() {

return Math.floor(Math.random() * 100) + 1;

}




function generateArray() {

const array = [];

for (let i = 0; i < 5; i++) {

array.push(generateElement());

  }

return array;

}




function generateContainer() {

return document.createElement('div');

}




function fillArrContainer(container, arr) {

container.innerHTML = '';

arr.forEach(num => {

const span = document.createElement('span');

span.textContent = num;

container.appendChild(span);

  });

}




function isOrdered(a, b) {

return a <= b;

}




function swapElements(arr, index) {

if (index < arr.length - 1 && arr[index] > arr[index + 1]) {

    [arr[index], arr[index + 1]] = [arr[index + 1], arr[index]];

  }

}




function highlightCurrentEls(container, index) {

const spans = container.children;

if (spans[index]) spans[index].style.border = '2px dashed red';

if (spans[index + 1]) spans[index + 1].style.border = '2px dashed red';

}




// --------------------

// Main Script

// --------------------




document.addEventListener('DOMContentLoaded', () => {




const generateBtn = document.getElementById('generate-btn');

const sortBtn = document.getElementById('sort-btn');

const arrayContainer = document.getElementById('array-container');




// ----------------------

// STEP 17: Generate Array

// ----------------------

generateBtn.addEventListener('click', () => {




// Clear everything

arrayContainer.innerHTML = '';




// Create a NEW starting-array div

const startingContainer = document.createElement('div');

startingContainer.id = 'starting-array';




// Generate 5 numbers

const startingArray = generateArray();

fillArrContainer(startingContainer, startingArray);




// Only the starting array should exist now

arrayContainer.appendChild(startingContainer);

  });




// ----------------------

// Bubble Sort Steps

// ----------------------

sortBtn.addEventListener('click', () => {




const startingContainer = document.getElementById('starting-array');

if (!startingContainer) return;




const arrayContainer = document.getElementById('array-container');




// Read numbers from starting <span>

const initialArr = Array.from(startingContainer.children)

      .map(span => parseInt(span.textContent));




// Clear container for new steps

arrayContainer.innerHTML = '';




// STEP 21: highlight first two numbers in starting array

highlightCurrentEls(startingContainer, 0);




// Add highlighted starting array as FIRST STEP

arrayContainer.appendChild(startingContainer.cloneNode(true));




// Bubble sort

const arr = initialArr.slice();

let steps = [];




for (let i = 0; i < arr.length - 1; i++) {

for (let j = 0; j < arr.length - 1 - i; j++) {




// Create step BEFORE swap

const stepDiv = generateContainer();

fillArrContainer(stepDiv, arr);




// STEP 20: highlight compared indices

highlightCurrentEls(stepDiv, j);




// Save step

steps.push(stepDiv);




// Perform swap

swapElements(arr, j);

      }

    }




// Append all comparison steps

steps.forEach(step => arrayContainer.appendChild(step));




// Final sorted step

const finalDiv = generateContainer();

fillArrContainer(finalDiv, arr);

arrayContainer.appendChild(finalDiv);

  });




});

You should be testing your code in the preview window and checking against how the example app behaves. Forget about what tests are not passing and focus on that!

Your sortBtn is borked again. I see the sort button before I interact with the page, then if I click it, I see this:

Please bear me the burden by providing the correct solutions otheriwse it might be a lengthy debugging process thanks.

No way. You are not putting out enough effort. A lengthy debugging process is exactly what you need to learn how to do. Your objective should be to learn how to code, not pass the tests.

Someone please end my misery for debugging this assignment.

if you are asking people to fix the code for you, that is not something that can happen

are you able to see what’s different between the two apps when testing your app and testing the example app?

Hmmm I dont know if. theres a bug from your side heres my code

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width,initial-scale=1" />

<title>Sorting Visualizer</title>

<style>

body { font-family: system-ui, Arial, sans-serif; margin: 20px; }

#btns { display: flex; gap: .5rem; margin-bottom: 1rem; }

button { padding: .5rem .75rem; }

#array-container { display: flex; flex-direction: column; gap: .5rem; }

#array-container > div { display: flex; gap: .25rem; padding: .25rem; border: 1px solid #ccc; border-radius: .25rem; }

#starting-array { border: 2px solid #335eea; }

#array-container span { padding: .15rem .35rem; border: 1px solid #ddd; border-radius: .2rem; }

</style>

</head>

<body>

<div id="btns">

<button id="generate-btn" type="button">Generate Array</button>

<button id="sort-btn" type="button">Sort Array</button>

</div>




<div id="array-container">

<!-- IMPORTANT: starting-array is a child of array-container and is the starting step -->

<div id="starting-array"></div>

</div>




<script src="script.js"></script>

</body>

</html>





* {

    box-sizing: border-box;

}




main {

height: 100vh;

display: flex;

justify-content: center;

flex-direction: column;

align-items: center;

}




#array-container {

max-height: 95vh;

display: flex;

flex-direction: column;

flex-wrap: wrap;

gap: 2px;




}




#array-container>div {

min-width: 8rem;

height: 2rem;

box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;

border-radius: 10px;

margin-bottom: 0.2rem;

border: 2px solid darkgray;

display: flex;

justify-content: space-evenly;

align-items: center;

}




#starting-array {

border: 4px solid darkblue !important;

}




#btn-container {

display: flex;

justify-content: space-around;

}




button {

padding: 2px;

margin: 5px;

}




span {

border-radius: 2px;

padding: 0.5px;

margin: 0

}




@media (min-width: 430px) {

  #array-container>div {

min-width: 12rem;    

  }

span {

padding: 1px;

margin: 1px;

  }

}




function highlightCurrentEls(container, index) {

  const children = container.children;

  if (children[index]) {

    children[index].style.border = "3px dashed red";

  }

if (children[index + 1]) {

    children[index + 1].style.border = "3px dashed red";

  }

}



// ===== Required functions for FCC =====




/** Return a random integer between 1 and 100 inclusive */

function generateElement() {

return Math.floor(Math.random() * 100) + 1;

}




/** Build an array using generateElement() */

function generateArray(len = 5) {

const arr = [];

for (let i = 0; i < len; i++) arr.push(generateElement());

return arr;

}




/** Return an empty <div> element */

function generateContainer() {

return document.createElement('div');

}




/** Return true if a <= b */

function isOrdered(a, b) {

return a <= b;

}




/** Swap arr[idx] and arr[idx+1] in place if arr[idx] > arr[idx+1] */

function swapElements(arr, idx) {

if (!Array.isArray(arr)) return;

if (typeof idx !== 'number') return;

if (idx < 0 || idx >= arr.length - 1) return;




if (!isOrdered(arr[idx], arr[idx + 1])) {

    [arr[idx], arr[idx + 1]] = [arr[idx + 1], arr[idx]];

  }

}




// ===== DOM helpers =====

const arrayContainer = document.getElementById('array-container');

const startingArrayEl = document.getElementById('starting-array');

const genBtn = document.getElementById('generate-btn');

const sortBtn = document.getElementById('sort-btn');




function fillArrContainer(el, arr) {

el.innerHTML = '';

arr.forEach(n => {

const s = document.createElement('span');

s.textContent = String(n);

el.appendChild(s);

  });

}




/** Optional: visually mark the compared pair inside a container */

function highlightCurrentEls(container, idx) {

const kids = container.children;

if (kids[idx]) kids[idx].style.border = '2px dashed red';

if (kids[idx + 1]) kids[idx + 1].style.border = '2px dashed red';

}




// ===== Generate button =====

genBtn.addEventListener('click', () => {

// Remove all step divs but keep #starting-array

Array.from(arrayContainer.children).forEach(child => {

if (child !== startingArrayEl) child.remove();

  });




fillArrContainer(startingArrayEl, generateArray(5));

});




// ===== Sort button (fulfills step 18) =====

sortBtn.addEventListener('click', () => {

// Ensure starting array exists

if (startingArrayEl.children.length !== 5) {

fillArrContainer(startingArrayEl, generateArray(5));

  }




// Remove prior steps (keep starting step)

Array.from(arrayContainer.children).forEach(child => {

if (child !== startingArrayEl) child.remove();

  });




const start = Array.from(startingArrayEl.children).map(s => parseInt(s.textContent, 10));

const n = start.length;

const working = start.slice();




// (Optional) Highlight first comparison on the starting step

highlightCurrentEls(startingArrayEl, 0);




// Append exactly one step div per comparison (n*(n-1)/2), state AFTER comparison

for (let i = 0; i < n - 1; i++) {

for (let j = 0; j < n - i - 1; j++) {

swapElements(working, j);




const stepDiv = generateContainer();          // empty div

fillArrContainer(stepDiv, working.slice());   // five spans

highlightCurrentEls(stepDiv, j);              // show compared pair

arrayContainer.appendChild(stepDiv);

    }

  }




// Final sorted state

const finalDiv = generateContainer();

fillArrContainer(finalDiv, working);

finalDiv.style.border = '2px solid green';

arrayContainer.appendChild(finalDiv);




// Now #array-container has:

// 1 (starting-array) + n*(n-1)/2 (step divs) + 1 (final)  => exact Bubble Sort steps incl. start & end

});