При вводе значения после каждого третьего знака с конца поставить запятую

Рейтинг: 2Ответов: 1Опубликовано: 30.04.2023

Вот HTML

<input class="rangeInput" type="number" name="range_min" id="range_min" />

При загрузки страницы в инпуте с type="number" запятая не отображает число. Нужно чтобы пользователь мог вводить только числа и запятую. Пытался через JS это сделать.

Вот JS

$(".rangeInput").each(function() {
  str = $(this).val();
  res = format(str);
  $(this).val(res);
});

function format(str) {
    const s = str.length;
    const chars = str.split('');
    const strWithSpaces = chars.reduceRight((acc, char, i) => {
        const spaceOrNothing = ((((s - i) % 3) === 0) ? ',' : '');
        return (spaceOrNothing + char + acc);
    }, '');
    return ((strWithSpaces[0] === ',') ? strWithSpaces.slice(1) : strWithSpaces);
}

Но значение в инпутах все равно не отображается. Как это сделать?

Ответы

▲ 2Принят

Я сделал так, что человек может вводить только цифру, а не цифру и запятую. Запятая ставится и убирается автоматически:

  • Если последний символ в строке НЕ цифра, то убираю этот символ

  • Если последний символ в строке цифра, то разделя. его посимвольно и убираю запятые, потому что их буду вставлять вручную заново

  • Далее циклом иду по этим символам с конца, но т.к. я мутирую этот массив, то следить за i трудно, потому завёл счётчик k, который следит за тем, сколько символов я прошёл и если прошёл 3 штучки, то ставлю запятую, там где щас i:

const input = document.querySelector('#range_min');

input.addEventListener('input', () => {  
  const value = input.value;
  const lastSymbol = value.at(-1);
  const onlyNumberRegExp = /\d/;
  const delimeter = ',';
  
  if (!onlyNumberRegExp.test(lastSymbol)) {
    input.value = value.slice(0, value.length - 1);
    
    return;
  }
  
  let digitsWithoutComma = value.split('').filter(x => x !== delimeter);
  
  for(let i = digitsWithoutComma.length - 1, k = -2; i > 0; --i, ++k) {
    
    if (k % 3 === 0)
      digitsWithoutComma.splice(i, 0, delimeter);
  }
  
  input.value = digitsWithoutComma.join('');
})
<input id="range_min" />

Предложил эту идею Oliver Patterson

Так же можно решить эту задачу с помощью Intl.NumberFormat

Отличие от предыдущего алгоритма - отсутсвие цикла:

const input = document.querySelector('#range_min');

input.addEventListener('input', () => {  
  const value = input.value;
  const lastSymbol = value.at(-1);
  const onlyNumberRegExp = /\d/;
  const delimeter = ',';
  
  if (!onlyNumberRegExp.test(lastSymbol)) {
    input.value = value.slice(0, value.length - 1);
    
    return;
  }
  
  let numberWithoutComma = value.split('').filter(x => x !== delimeter).join('');  
  
  input.value = new Intl.NumberFormat().format(numberWithoutComma);
})
<input id="range_min" />