TransWikia.com

how to display input using button in right to left order?

Stack Overflow Asked by Mr Josh on December 16, 2021

I want to display the text in the display section where the input via the buttons are aligned to the right and when the text exceeds the width of the display div it gets overflowed to the left,ie the most most recent inputs should be displayed.

but the problem occurs when i start inputting special characters. In the console input appears correctly, in order but on the display the order starts getting jumble when other characters are inputted.

is it because of the direction property?

const display = document.getElementById('display');
const numbers = document.getElementsByClassName('nums');


for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i].value)
  numbers[i].addEventListener('click', () => {
    console.log(display.innerText + `${numbers[i].value}`)
    display.innerText = display.innerText + `${String(numbers[i].value)}`;
  })
}
* {
  box-sizing: border-box;
}

body {
  margin: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

button {
  padding: 10px 18px
}

.operations button {
  margin-top: 5px;
  padding: 10px 15px;
}

.numbers {
  width: 80%;
  display: block;
  /* flex-direction; */
  /* justify-content: space-evenly; */
  align-items: center;
}

.container {
  border: 1px solid black;
  padding: 20px;
}

.row {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  /* align-items: center; */
  margin: 7px 0;
}

.display {
  border: 1px solid black;
  width: 200px;
  height: 30px;
  margin: 10px;
  text-align: right;
  overflow: hidden;
  direction: rtl;
}

.butts {
  display: flex;
}

.operations {
  display: flex;
  margin-top: 2px;
  flex-direction: column;
  margin-left: 5px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

</head>

<body>
  <div class="container">
    <div class="display" id='display'></div>
    <div class="butts">
      <div class="numbers">
        <div class="row">

          <button class="nums" value="1">1</button>
          <button class="nums" value="2">2</button>
          <button class="nums" value="3">3</button>
        </div>
        <div class="row">
          <button class="nums" value="4">4</button>
          <button class="nums" value='5'>5</button>
          <button class="nums" value='6'>6</button>
        </div>
        <div class="row">
          <button class="nums" value="7">7</button>
          <button class="nums" value="8">8</button>
          <button class="nums" value="9">9</button>
        </div>

        <div class="row">
          <button class="nums" value="0" style='width:55%'>0</button>
          <button classs="eqs" value="=" style='width:35%'>=</button>
        </div>
      </div>
      <div class="operations">



        <button class="nums" value="+">+</button>
        <button class="nums" value="a">a</button>


        <button class="nums" value="*">*</button>
        <button class="nums" value="/">/</button>




      </div>
    </div>
  </div>


</body>

</html>

5 Answers

const display = document.getElementById('display');
const numbers = document.getElementsByClassName('nums');


for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i].value)
  numbers[i].addEventListener('click', () => {
    console.log(display.innerText + `${numbers[i].value}`)
    display.innerText = display.innerText + `${String(numbers[i].value)}`;
  })
}
* {
  box-sizing: border-box;
}

body {
  margin: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

button {
  padding: 10px 18px
}

.operations button {
  margin-top: 5px;
  padding: 10px 15px;
}

.numbers {
  width: 80%;
  display: block;
  /* flex-direction; */
  /* justify-content: space-evenly; */
  align-items: center;
}

.container {
  border: 1px solid black;
  padding: 20px;
}

.row {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  /* align-items: center; */
  margin: 7px 0;
}

.display {
  border: 1px solid black;
  width: 200px;
  height: 30px;
  margin: 10px;
  text-align:right;
  overflow: hidden;
  direction: ltr;
}

.butts {
  display: flex;
}

.operations {
  display: flex;
  margin-top: 2px;
  flex-direction: column;
  margin-left: 5px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

</head>

<body>
  <div class="container">
    <div class="display" id='display'>
    </div>
    <div class="butts">
      <div class="numbers">
        <div class="row">

          <button class="nums" value="1">1</button>
          <button class="nums" value="2">2</button>
          <button class="nums" value="3">3</button>
        </div>
        <div class="row">
          <button class="nums" value="4">4</button>
          <button class="nums" value='5'>5</button>
          <button class="nums" value='6'>6</button>
        </div>
        <div class="row">
          <button class="nums" value="7">7</button>
          <button class="nums" value="8">8</button>
          <button class="nums" value="9">9</button>
        </div>

        <div class="row">
          <button class="nums" value="0" style='width:55%'>0</button>
          <button classs="eqs" value="=" style='width:35%'>=</button>
        </div>
      </div>
      <div class="operations">



        <button class="nums" value="+">+</button>
        <button class="nums" value="a">a</button>


        <button class="nums" value="*">*</button>
        <button class="nums" value="/">/</button>




      </div>
    </div>
  </div>


</body>

</html>

const display = document.getElementById('display');
const numbers = document.getElementsByClassName('nums');


for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i].value)
  numbers[i].addEventListener('click', () => {
    console.log(display.innerText + `${numbers[i].value}`)
    display.innerText = display.innerText + `${String(numbers[i].value)}`;
  })
}
* {
  box-sizing: border-box;
}

body {
  margin: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

button {
  padding: 10px 18px
}

.operations button {
  margin-top: 5px;
  padding: 10px 15px;
}

.numbers {
  width: 80%;
  display: block;
  /* flex-direction; */
  /* justify-content: space-evenly; */
  align-items: center;
}

.container {
  border: 1px solid black;
  padding: 20px;
}

.row {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  /* align-items: center; */
  margin: 7px 0;
}

.display {
  border: 1px solid black;
  width: 200px;
  height: 30px;
  margin: 10px;
  text-align: right;
  overflow: hidden;
  direction: rtl;
}

.butts {
  display: flex;
}

.operations {
  display: flex;
  margin-top: 2px;
  flex-direction: column;
  margin-left: 5px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

</head>

<body>
  <div class="container">
    <div class="display" id='display'></div>
    <div class="butts">
      <div class="numbers">
        <div class="row">

          <button class="nums" value="1">1</button>
          <button class="nums" value="2">2</button>
          <button class="nums" value="3">3</button>
        </div>
        <div class="row">
          <button class="nums" value="4">4</button>
          <button class="nums" value='5'>5</button>
          <button class="nums" value='6'>6</button>
        </div>
        <div class="row">
          <button class="nums" value="7">7</button>
          <button class="nums" value="8">8</button>
          <button class="nums" value="9">9</button>
        </div>

        <div class="row">
          <button class="nums" value="0" style='width:55%'>0</button>
          <button classs="eqs" value="=" style='width:35%'>=</button>
        </div>
      </div>
      <div class="operations">



        <button class="nums" value="+">+</button>
        <button class="nums" value="a">a</button>


        <button class="nums" value="*">*</button>
        <button class="nums" value="/">/</button>




      </div>
    </div>
  </div>


</body>

</html>

Answered by user13986534 on December 16, 2021

Apart from removing the direction: rtl, how about using a hidden overflow container and a CustomEvent listener that will shift the oldest character from the display into the container out of view upon reaching a certain threshold of characters or width (can be whatever you want)?

This way you will get a fine-grained control over the overflow (note that this is not a non-standard "overflow" event, if you are worried about collisions, just name it differently) and the ability to perform other actions.

The approach has an additional benefit of being easily extendable with a "backspace" feature, as all overflow characters can be pushed back into the display by inverting the operation.

const display = document.getElementById('display');
const numbers = document.getElementsByClassName('nums');

const overflow = document.querySelector("#overflow");

display.addEventListener("overflow", ({
  detail: {
    oldest
  }
}) => {
  overflow.innerText += oldest
});

for (let i = 0; i < numbers.length; i++) {
  numbers[i].addEventListener('click', () => {
    const {
      innerText
    } = display;

    const chars = innerText.split(""); //allowed as you use a strict subset of characters;

    chars.push(numbers[i].value);

    if (chars.length > 23) { //configure length to your liking
      const eventInit = {
        detail: {
          oldest: chars.shift()
        }
      };

      const overEvent = new CustomEvent("overflow", eventInit);

      display.dispatchEvent(overEvent);
    }

    display.innerText = chars.join("");
  });
}
* {
  box-sizing: border-box;
}

body {
  margin: 0px;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

button {
  padding: 10px 18px
}

.operations button {
  margin-top: 5px;
  padding: 10px 15px;
}

.numbers {
  width: 80%;
  display: block;
  align-items: center;
}

.container {
  border: 1px solid black;
  padding: 20px;
}

.row {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  margin: 7px 0;
}

.overflow {
  display: none;
}

.display {
  border: 1px solid black;
  width: 200px;
  height: 30px;
  margin: 10px;
  padding: 6px;
  text-align: right;
  overflow: hidden;
}

.butts {
  display: flex;
}

.operations {
  display: flex;
  margin-top: 2px;
  flex-direction: column;
  margin-left: 5px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

</head>

<body>
  <div class="container">
    <div class="overflow" id="overflow"></div>
    <div class="display" id='display'></div>
    <div class="butts">
      <div class="numbers">
        <div class="row">

          <button class="nums" value="1">1</button>
          <button class="nums" value="2">2</button>
          <button class="nums" value="3">3</button>
        </div>
        <div class="row">
          <button class="nums" value="4">4</button>
          <button class="nums" value='5'>5</button>
          <button class="nums" value='6'>6</button>
        </div>
        <div class="row">
          <button class="nums" value="7">7</button>
          <button class="nums" value="8">8</button>
          <button class="nums" value="9">9</button>
        </div>

        <div class="row">
          <button class="nums" value="0" style='width:55%'>0</button>
          <button classs="eqs" value="=" style='width:35%'>=</button>
        </div>
      </div>
      <div class="operations">
        <button class="nums" value="+">+</button>
        <button class="nums" value="a">a</button>
        <button class="nums" value="*">*</button>
        <button class="nums" value="/">/</button>
      </div>
    </div>
  </div>
</body>

</html>

Answered by Oleg Valter on December 16, 2021

You can change the text direction with LTR & RTL source

Answered by Hassan Raza on December 16, 2021

Hi you need to put a container with direction: rtl; and display with direction: ltr. Working code in sandbox attached

 .display-container{
      direction: rtl; 
      border: 1px solid black; 
      width: 200px;
      height: 30px;
      margin: 10px;
      overflow: hidden;
    }
    .display{
      white-space: nowrap; 
      direction: ltr; 
      display: inline-block;
      padding: 4px;
    }



 <div class="display-container">
    <span class="display" id="display"><span>
  </div>

https://codesandbox.io/s/stack-overflow-calculator-rtl-vs-ltf-cwhzi

enter image description here

Answered by Velu S Gautam on December 16, 2021

The issue should be as simple as removing the direction: rtl; from you CSS.

Codesandbox link

Answered by Robert Cooper on December 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP