Build a RegEx Sandbox - Build a RegEx Sandbox

Tell us what’s happening:

Hi, I’ve completed all the steps in this freeCodeCamp lab before.
Today, I tried to re-implement it in a different way to make things clearer.
However, I’m stuck on steps 13, 14, 15, 18, 19, and 20.
I’d really appreciate any pointers or explanations that could shed some light on this part of the code.

  1. When the inner HTML of stringToTest is Gu1n34 P1g5, the value of regexPattern is \d+, and the global flag is checked, stringToTest.innerHTML should become Gu<span class="highlight">1</span>n<span class="highlight">34</span> P<span class="highlight">1</span>g<span class="highlight">5</span> by clicking the testButton button.
  1. When the inner HTML of stringToTest is Gu1n34 P1g5, the value of regexPattern is G, and both the global and case insensitive flags are checked, stringToTest.innerHTML should become <span class="highlight">G</span>u1n34 P1<span class="highlight">g</span>5 by clicking the testButton button.
  1. When you click the testButton button, if the regex pattern matches the test string, the matched text should be surrounded by a span element with the class of highlight.
  1. When the inner HTML of stringToTest is Gu1n34 P1g5, the value of regexPattern is \d+, and the global flag is checked, the inner text of #result should become 1, 34, 1, 5 by clicking the testButton button.
  1. When there’s a match, the matched text should be displayed inside #result.
  1. When there’s no match, the text no match should be displayed inside #result.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Regex Sandbox</title>

</head>

<body>
    <h1>Regex Sandbox</h1>
    <main>
        <div id="regex-container">
            <label for="pattern">Regex Pattern:
                <div id="pattern-container">/<input type="text" id="pattern" name="pattern"
                        placeholder="Enter your regex pattern">/</div>
            </label>
            <div id="flags-container">
                <p>Flags: </p>
                <label for="i">
                    <input type="checkbox" name="flags" id="i"> i
                </label>
                <label for="g">
                    <input type="checkbox" name="flags" id="g"> g
                </label>
            </div>
        </div>
        <div id="test-container">
            <p>Test String:</p>
            <div id="test-string" placeholder="Enter your test string" contenteditable="true"></div>
        </div>
        <button class="btn" id="test-btn" type="button">Test Regex</button>
        <div id="result-container">
            <h2>Result:</h2>
            <p id="result">
            </p>
        </div>

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

</html>
/* file: styles.css */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    --dark-grey: #1b1b32;
    --light-grey: #f5f6f7;
    --golden-yellow: #fecc4c;
    --yellow: #ffcc4c;
    --gold: #feac32;
    --orange: #ffac33;
    --dark-orange: #f89808;
    --border: 0.2rem solid darkgrey;
    --padding: 0.3rem;
}

body {
    background-color: var(--dark-grey);
    color: var(--light-grey);
    font-size: 20px;
    font-family: "Lato", Helvetica, Arial, sans-serif;
    padding: 5px;
}

h1 {
    margin: 5rem auto 2rem;
    text-align: center;
}

p {
    padding: var(--padding);
}

#regex-container {
    max-width: 680px;
    margin: 20px auto;
    display: flex;
    justify-content: center;
    align-items: center;
    border: var(--border);
}

#regex-container>label {
    padding: var(--padding);
    flex: 1 1 auto;
}

#pattern-container {
    display: inline-block;
    color: var(--dark-grey);
    background-color: var(--light-grey);
    margin: 5px;
    border: var(--border);
}

#pattern {
    margin: 0.2rem;
    border: 0;
    font-size: 1rem;
    width: calc(100% - 1.2rem);
}

#pattern:focus {
    outline: none;
}

#flags-container {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
}

#flags-container>label {
    padding: var(--padding);
    margin-right: 0.3rem;
}

#test-container {
    max-width: 680px;
    margin: 20px auto;
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    border: var(--border);
}

#test-string {
    background-color: var(--light-grey);
    min-height: 5rem;
    color: var(--dark-grey);
    border-top: var(--border);
    font-size: 1.2rem;
}

[contenteditable=true]:empty:before {
    content: attr(placeholder);
    pointer-events: none;
    color: var(--dark-grey);
}

::placeholder {
    color: var(--dark-grey);
}


button {
    display: block;
    cursor: pointer;
    width: 8rem;
    margin: 0.2rem auto;
    color: var(--dark-grey);
    background-color: var(--gold);
    background-image: linear-gradient(var(--golden-yellow), var(--orange));
    border-color: var(--gold);
    border-width: 0.2rem;
    font-size: 1.1rem;
}

.btn:hover {
    background-image: linear-gradient(var(--yellow), var(--dark-orange));
}

#result-container {
    max-width: 680px;
    margin: 20px auto;
    display: flex;
    justify-content: center;
    align-items: center;
}

h2 {
    align-self: flex-start;
    margin: 0.4rem 0.2rem 0.2rem;
    flex: 0 1 auto;
}

#result {
    color: var(--dark-grey);
    background-color: var(--light-grey);
    font-size: 1.5rem;
    flex: 1 1 auto;
    margin: 0.2rem;
    border: var(--border);
    min-height: 3rem;
}

.highlight {
    background-color: lightgreen;
}
/* file: script.js */
const regexPattern = document.getElementById("pattern");
const caseInsensitiveFlag = document.getElementById("i");
const globalFlag = document.getElementById("g");
const stringToTest = document.getElementById("test-string");
const testButton = document.getElementById("test-btn");
const testResult = document.getElementById("result");

const getFlags = () => {
  let flagString = "";
  if (caseInsensitiveFlag.checked) {
    flagString += "i";
  }
  if (globalFlag.checked) {
    flagString += "g";
  }

  return flagString;
};

const updatedString = (rx, str) => {
  const matched = str.match(rx);
  if (matched === null) {
    testResult.innerHTML = "no match";
  } else {
    const subString = `<span class="highlight">` + "$&" + `</span>`;
    const replaced = str.replace(rx, subString);
    stringToTest.innerHTML = replaced;
    console.log(stringToTest.innerHTML);
    const expandedString = matched.join(", ");
    testResult.innerHTML = expandedString;
  }
};

regexPattern.addEventListener("input", () => {});

let flagString = "";

let previousTextString = "";
let currentTextString = "";
testButton.addEventListener("click", () => {
  currentTextString = stringToTest.textContent;

  if (currentTextString !== previousTextString) {
    if (regexPattern.value !== null) {
      if (getFlags() === "") {
        const regex = new RegExp(regexPattern.value);
        updatedString(regex, currentTextString);
      } else {
        const regex = new RegExp(regexPattern.value, getFlags());
        updatedString(regex, currentTextString);
      }
    }
  } 
  previousTextString = currentTextString;
});

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:147.0) Gecko/20100101 Firefox/147.0

Challenge Information:

Build a RegEx Sandbox - Build a RegEx Sandbox

Can you explain how you are stuck? What happens when you test, do you get the correct result?

Just focus on the first test 13

@pkdvalis

In the function

I tried to insert a console.log and compared the result with test 13

like this one.


const updatedString = (rx, str) => {
  const matched = str.match(rx);
  if (matched === null) {
    testResult.innerHTML = "no match";
  } else {
    const subString = `<span class="highlight">` + "$&" + `</span>`;
    const replaced = str.replace(rx, subString);
    stringToTest.innerHTML = replaced;
    console.log(stringToTest.innerHTML);
    const expandedString = matched.join(", ");
    testResult.innerHTML = expandedString;
  }
};

They both give me the same output

Gu<span class="highlight">1</span>n<span class="highlight">34</span> P<span class="highlight">1</span>g<span class="highlight">5</span>

It was quite confusing.

Many times this is related to global variables which do not get reset when the tests call a function repeatedly.

I would try putting your variables into the click listener.

Yes.
I moved this code inside testButton.addEventListener():

let previousTextString = "";
let currentTextString = "";

It works, but previousTextString seems unnecessary.
The two variables aren’t actually being compared after stringToTest.textContent is updated, so previousTextString doesn’t seem to serve any real purpose.

1 Like