Search code examples
javascriptloopsforeach

Is there a way I can write my js code in fewer lines to make it cleaner?


I'm trying to create a border radius reviewer where the border radius of the four sides of a rectangle changes, based on the values entered into the four text boxes linked to each edge. This is my code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Border-radius previewer</title>
  <style>
    body,
    .outer-square {
      background-color: white;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .inner-square {
      border: 1px solid #000;
      width: 400px;
      height: 200px;
      background-color: rgb(255, 255, 255);
    }
    
    .outer-square {
      border: 1px solid #000000;
      width: 500px;
      height: 300px;
      background-color: rgb(211, 200, 200);
      border-top-left-radius: 0px;
      border-top-right-radius: 0px;
      border-bottom-left-radius: 0px;
      border-bottom-right-radius: 0px;
      margin-top: 100px;
    }
    
    input {
      width: 10px;
    }
    
    p {
      margin-left: 10px;
    }
  </style>
</head>

<body>
  <div class="outer-square" id="outer-square">
    <div class="inner-square" id="inner-square">
      <p id="top-left-output"></p>
      <p id="top-right-output"></p>
      <p id="bottom-left-output"></p>
      <p id="bottom-right-output"></p>
    </div>
  </div>
  <input type="text" id="top-left-border-radius" value="0">
  <input type="text" id="top-right-border-radius" value="0">
  <input type="text" id="bottom-left-border-radius" value="0">
  <input type="text" id="bottom-right-border-radius" value="0">
  <script>
    const innerSquare = document.getElementById('inner-square')
    const outerSquare = document.getElementById('outer-square')

    //Inputs
    const topLeftInput = document.getElementById('top-left-border-radius')
    const topRightInput = document.getElementById('top-right-border-radius')
    const bottomLeftInput = document.getElementById('bottom-left-border-radius')
    const bottomRightInput = document.getElementById('bottom-right-border-radius')

    //This section contains declaration of output
    const top_left_output = document.getElementById('top-left-output')
    const top_right_output = document.getElementById('top-right-output')
    const bottom_left_output = document.getElementById('bottom-left-output')
    const bottom_right_output = document.getElementById('bottom-right-output')


    //Adding event listeners
    topLeftInput.addEventListener('input', function(e) {
      top_left_output.textContent = `border-top-left-radius: ${topLeftInput.value}px;`
      outerSquare.style.borderTopLeftRadius = `${topLeftInput.value}px`
    })

    topRightInput.addEventListener('input', function(e) {
      top_right_output.textContent = `border-top-right-radius: ${topRightInput.value}px;`
      outerSquare.style.borderTopRightRadius = `${topRightInput.value}px`
    })

    bottomLeftInput.addEventListener('input', function(e) {
      bottom_left_output.textContent = `border-bottom-left-radius: ${bottomLeftInput.value}px;`
      outerSquare.style.borderBottomLeftRadius = `${bottomLeftInput.value}px`
    })

    bottomRightInput.addEventListener('input', function(e) {
      bottom_right_output.textContent = `border-bottom-right-radius: ${bottomRightInput.value}px;`
      outerSquare.style.borderBottomRightRadius = `${bottomRightInput.value}px`
    })
  </script>
</body>

</html>

This code roughly does what I want. But I believe I should be able to do this in fewer lines of code. I was able to come up with this. However I was not able to add the texts within the div with the data attribute "output".

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Border-radius previewer</title>
  <style>
    body,
    .outer-square {
      background-color: white;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .inner-square {
      border: 1px solid #000;
      width: 400px;
      height: 200px;
      background-color: rgb(255, 255, 255);
    }
    
    .outer-square {
      border: 1px solid #000000;
      width: 500px;
      height: 300px;
      background-color: rgb(211, 200, 200);
      border-top-left-radius: 0px;
      border-top-right-radius: 0px;
      border-bottom-left-radius: 0px;
      border-bottom-right-radius: 0px;
      margin-top: 100px;
    }
    
    input {
      width: 10px;
    }
    
    div {
      margin-left: 10px;
    }
  </style>
</head>

<body>
  <input type="text" data-border-radius="top-left-border-radius" value="0">
  <input type="text" data-border-radius="top-right-border-radius" value="0">
  <input type="text" data-border-radius="bottom-left-border-radius" value="0">
  <input type="text" data-border-radius="bottom-right-border-radius" value="0">

  <div class="outer-square" data-outer-square>
    <div class="inner-square" data-inner-square>
      <div data-output="top-left-border-radius"></div>
      <div data-output="top-right-border-radius"></div>
      <div data-output="bottom-left-border-radius"></div>
      <div data-output="bottom-right-border-radius"></div>
    </div>
  </div>

  <script>
    const innerSquare = document.querySelector("[data-inner-square]")
    const outerSquare = document.querySelector("[data-outer-square]")
    const inputs = document.querySelectorAll("[data-border-radius]")
    const outputs = document.querySelectorAll("[data-output]")

    inputs.forEach(input => {
      input.addEventListener('input', (e) => {
        const borderRadius = input.dataset.borderRadius

        if (borderRadius == 'top-left-border-radius') {
          outerSquare.style.borderTopLeftRadius = `${input.value}px`
        } else if (borderRadius == 'top-right-border-radius') {
          outerSquare.style.borderTopRightRadius = `${input.value}px`
        } else if (borderRadius == 'bottom-right-border-radius') {
          outerSquare.style.borderBottomRightRadius = `${input.value}px`
        } else outerSquare.style.borderBottomLeftRadius = `${input.value}px`
      })
    })
  </script>
</body>

</html>

Any help will be appreciated.


Solution

  • To make code cleanly name every variables, attributes more seriously.

    -html

     <div class="inner-square" data-inner-square>
      <div id="borderTopLeftRadiusOutput"></div>
      <div id="borderTopRightRadiusOutput"></div>
      <div id="borderBottomLeftRadiusOutput"></div>
      <div id="borderBottomRightRadiusOutput"></div>
    </div>
    ...
    <input type="text" data-border-radius="borderTopLeftRadius" value="0">
    <input type="text" data-border-radius="borderTopRightRadius" value="0">
    <input type="text" data-border-radius="borderBottomLeftRadius" value="0">
    <input type="text" data-border-radius="borderBottomRightRadius" value="0">
    

    -javascript

    inputs.forEach((input) => 
      input.addEventListener("input", (e) => {
        const field = input.dataset.borderRadius;
        document.getElementById(`${field}Output`).textContent =
          `${field}: ${input.value}px;`;
        outerSquare.style[field] = `${input.value}px`;
      })
    );
    

    I only changed id from each input and output div.

    I think my answer'll help you.