Frameworks.suFrameworks.su Шпаргалка вебмастера

  • Главная
  • Framework Kohana
  • PHP
  • Javascript
  • CSS
  • Сервисы
    • Генератор паролей
  • Контакты
Главная / Javascript / Javascript — сумма прописью

Javascript — сумма прописью

07.07.2014 10 23090

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

HTML

Для начала создадим наше поле в которое будем вводить число:

<input type="text" class="num" />

И область для вывода результата

<span class="result"></span>

Javascript

Также нам понадобится функция которая будет преобразовывать строку в массив, аналог функции в PHP str_split:

/**
 * Преобразует строку в массив
 */
function str_split(string, length) {
    var chunks, len, pos;
    
    string = (string == null) ? "" : string;
    length =  (length == null) ? 1 : length;
    
    var chunks = [];
    var pos = 0;
    var len = string.length;
    while (pos < len) {
        chunks.push(string.slice(pos, pos += length));
    }
    
    return chunks;
};

И функцию для склонения словоформ:

/**
 * Склоняем словоформу
 */
function morph(number, titles) {
    var cases = [2, 0, 1, 1, 1, 2];
    return titles[ (number0>4 && number0<20)? 2 : cases[Math.min(number, 5)] ];
};

И теперь функция для преобразования числа в сумму прописью

/**
 * Возвращает сумму прописью
 */
function number_to_string (num) {
        var def_translite = {
            null: 'ноль',
            a1: ['один','два','три','четыре','пять','шесть','семь','восемь','девять'],
            a2: ['одна','две','три','четыре','пять','шесть','семь','восемь','девять'],
            a10: ['десять','одиннадцать','двенадцать','тринадцать','четырнадцать','пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать'],
            a20: ['двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят','восемьдесят','девяносто'],
            a100: ['сто','двести','триста','четыреста','пятьсот','шестьсот','семьсот','восемьсот','девятьсот'],
            uc: ['копейка', 'копейки', 'копеек'],
            ur: ['рубль', 'рубля', 'рублей'],
            u3: ['тысяча', 'тысячи', 'тысяч'],
            u2: ['миллион', 'миллиона', 'миллионов'],
            u1: ['миллиард', 'миллиарда', 'миллиардов'],
        }
    var i1, i2, i3, kop, out, rub, v, zeros, _ref, _ref1, _ref2, ax;
    
    _ref = parseFloat(num).toFixed(2).split('.'), rub = _ref[0], kop = _ref[1];
    var leading_zeros = 12 - rub.length;
    if (leading_zeros < 0) {
        return false;
    }
    
    var zeros = [];
    while (leading_zeros--) {
        zeros.push('0');
    }
    rub = zeros.join('') + rub;
    var out = [];
    if (rub > 0) {
        // Разбиваем число по три символа
        _ref1 = str_split(rub, 3);
        for (var i = -1; i < _ref1.length;i++) {
            v = _ref1[i];
            if (!(v > 0)) continue;
            _ref2 = str_split(v, 1), i1 = parseInt(_ref2[0]), i2 = parseInt(_ref2[1]), i3 = parseInt(_ref2[2]);
            out.push(def_translite.a100[i1-1]); // 1xx-9xx
            ax = (i+1 == 3) ? 'a2' : 'a1';
            if (i2 > 1) {
                out.push(def_translite.a20[i2-2] + (i3 > 0 ?  ' ' + def_translite[ax][i3-1] : '')); // 20-99
            } else {
                out.push(i2 > 0 ? def_translite.a10[i3] : def_translite[ax][i3-1]); // 10-19 | 1-9
            }
            
            if (_ref1.length > i+1){
                var name = def_translite['u'+(i+1)];
                out.push(morph(v,name));
            }
        }
    } else {
        out.push(def_translite.null);
    }
    // Дописываем название "рубли"
    out.push(morph(rub, def_translite.ur));
    // Дописываем название "копейка"
    out.push(kop + ' ' + morph(kop, def_translite.uc));
    
    // Объединяем маcсив в строку, удаляем лишние пробелы и возвращаем результат
    return out.join(' ').replace(RegExp(' {2,}', 'g'), ' ').trimLeft();
};

Пример использования:

$(document).ready(function(){
    $(".num").change(function(){
        var value = $(this).val();
        if(value){
            $(".result").html(number_to_string(value));
        }
    });
});

На этом все.

Скачать рабочий пример

Теги:
  • jQuery
  • Пример

Комментарии

  1. sega057
    sega057
    16.09.2020 16:44

    Украинский вариант до миллиона на typescript

    type Values = [number, number, string] | [number, number, string, string];

    interface MapNumbers {
    [k: string]: Values
    }

    const mapNumbers: MapNumbers = {
    0: [2, 1, "нуль"],
    1: [0, 2, "один", "одна"],
    2: [1, 2, "два", "дві"],
    3: [1, 1, "три"],
    4: [1, 1, "чотири"],
    5: [2, 1, "п'ять"],
    6: [2, 1, "шість"],
    7: [2, 1, "сім"],
    8: [2, 1, "вісім"],
    9: [2, 1, "дев'ять"],
    10: [2, 1, "десять"],
    11: [2, 1, "одинадцять"],
    12: [2, 1, "дванадцять"],
    13: [2, 1, "тринадцять"],
    14: [2, 1, "чотирнадцять"],
    15: [2, 1, "п'ятнадцять"],
    16: [2, 1, "шістнадцять"],
    17: [2, 1, "сімнадцять"],
    18: [2, 1, "вісімнадцять"],
    19: [2, 1, "дев'ятнадцять"],
    20: [2, 1, "двадцять"],
    30: [2, 1, "тридцять"],
    40: [2, 1, "сорок"],
    50: [2, 1, "п'ятдесят"],
    60: [2, 1, "шістдесят"],
    70: [2, 1, "сімдесят"],
    80: [2, 1, "вісімдесят"],
    90: [2, 1, "дев'яносто"],
    100: [2, 1, "сто"],
    200: [2, 1, "двісті"],
    300: [2, 1, "триста"],
    400: [2, 1, "чотириста"],
    500: [2, 1, "п'ятсот"],
    600: [2, 1, "шістсот"],
    700: [2, 1, "сімсот"],
    800: [2, 1, "вісімсот"],
    900: [2, 1, "дев'ятсот"]
    };

    type PluralAmount = [string, string, string];

    const mapOrders: PluralAmount[] = [
    ["гривня", "гривні", "гривень"],
    ["тисяча", "тисячі", "тисяч"],
    ];

    const objKop: PluralAmount = ["копійка", "копійки", "копійок"];

    function Value(dVal: number): string | undefined {
    const xVal: Values = mapNumbers[dVal];

    if (xVal[1] === 1) {
    return xVal[2];
    } else {
    return xVal[3];
    }
    }

    function From0To999(fValue: number, oObjDesc: PluralAmount, fnAddDesc: (kop: string) => void, fnAddNum?: (val: any) => void) {
    let nCurrState: number = 2;

    if (Math.floor(fValue / 100) > 0) {
    const fCurr: number = Math.floor(fValue / 100) * 100;
    fnAddNum && fnAddNum(Value(fCurr));
    nCurrState = mapNumbers[fCurr][0];
    fValue -= fCurr;
    }

    if (fValue < 20) {
    if (Math.floor(fValue) > 0) {
    fnAddNum && fnAddNum(Value(fValue));
    nCurrState = mapNumbers[fValue][0];
    }
    } else {
    const fCurr: number = Math.floor(fValue / 10) * 10;
    fnAddNum && fnAddNum(Value(fCurr));
    nCurrState = mapNumbers[fCurr][0];
    fValue -= fCurr;

    if (Math.floor(fValue) > 0) {
    fnAddNum && fnAddNum(Value(fValue));
    nCurrState = mapNumbers[fValue][0];
    }
    }

    fnAddDesc(oObjDesc[nCurrState]);
    }

    export function amountToWords(fAmount: number): string {
    let fInt: number = Math.floor(fAmount + 0.005);
    const fDec: number = Math.floor(((fAmount - fInt) * 100) + 0.5);

    const arrRet: string[] = [];
    const arrThousands: number[] = [];

    for (; fInt > 0.9999; fInt /= 1000) {
    arrThousands.push(Math.floor(fInt % 1000));
    }

    if (arrThousands.length == 0) {
    arrThousands.push(0);
    }

    function PushToRes(strVal: any) {
    arrRet.push(strVal);
    }

    for (let iSouth = arrThousands.length - 1; iSouth >= 0; --iSouth) {
    if (arrThousands[iSouth] == 0) {
    continue;
    }
    From0To999(arrThousands[iSouth], mapOrders[iSouth], PushToRes, PushToRes);
    }

    if (arrThousands[0] == 0) {
    // Handle zero amount
    if (arrThousands.length == 1) {
    PushToRes(Value(0));
    }

    const nCurrState = 2;
    PushToRes(mapOrders[0][nCurrState]);
    }

    if (arrRet.length > 0) {
    // Capitalize first letter
    arrRet[0] = arrRet[0][0].toUpperCase() + arrRet[0].substr(1);
    }

    arrRet.push(fDec.toString().padStart(2, "0"));

    From0To999(fDec, objKop, PushToRes);

    return arrRet.join(" ");
    }

    Ответить
  2. oleg
    oleg
    22.03.2020 12:52

    за javascript = Большое СПАСИБО Вам !

    Ответить
  3. Сергей
    Сергей
    13.09.2018 08:23

    Подскажите, пожалуйста, как реализовать тоже самое, но цифру брать, например, из тега <span class="num">456</span> (<span class="result"></span>)Т.е. Значение в спан с классом num вставляется из базы, и рядом выводится прописью.
    За ранее спасибо.

    Ответить
  4. Денис
    Денис
    24.08.2017 15:06

    что значат эти строки
    string = (string == null) ? "" : string;
    length = (length == null) ? 1 : length;

    Ответить
  5. jass
    jass
    14.10.2016 16:25

    Так, с keyup разобались.
    Проблема: скрипт выводит undefined при 20000, 30000 и так далее:
    двадцать undefined тысяч сто один рубль 00 копеек

    Ответить
    • Администратор
      Администратор
      14.10.2016 16:38

      Поправил ошибку, смотрите обновленный пример

      Ответить
      • jass
        jass
        14.10.2016 17:00

        Только что написал сам то же самое, хотел отписать сюда ))
        (i3 > 0 ? def_translite[ax][i3-1] : '')); // 20-99
        Теперь код могу признать рабочим и готовым к внедрению

        Ответить
    • jass
      jass
      14.10.2016 14:08

      Как сделать, чтобы функция работала на событии keyup, не когда фокус убран с поля?

      Ответить
    • Мистер фокс
      Мистер фокс
      05.11.2015 20:53

      Самый короткий скрипт всех времен и народов для суммы прописью на русском:

      С комментариями!

      function sprop(res)
      {
      // На входе в переменной res должна находиться строка в формате "12345.67" (пример: 18102412990.42)
      var h000=[" миллиард", "", "а", "ов", " миллион", "", "а", "ов", " тысяч", "а", "и", "", " рубл", "ь", "я", "ей"];
      // Первым идет корень слова, затем окончание для цифры 1, затем для цифер 2-4, затем для всего больше 4 и нуля
      var h100=["", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"];
      var h010=["", "", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"];
      var h011=["", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"];
      var pattern="000000000000";
      var result=" "+res.substr(res.length-2)+" коп.";// Копируем хвост с копейками в результат "как есть"
      res=res.slice(0,res.length-3); // Выкидываем дробную часть с точкой из исходника
      res=pattern.substr(res.length-12)+res; // Добавляем в исходник лидирующие нули из pattern
      raw = res.split(''); // Разбиваем строку на подстроки, в каждой из которых пока по одной цифре
      var p=0, i=0, k=0, t=0; // Переменные
      for (var group=0; group<4; group++) { // Цикл по группам из трех цифр - триадам (12 знаков pattern = 4 триады)
      p=group*3; // Индекс нулевого элемента группы относительно начала массива RAW
      t=+raw[p+2]; // В raw[p] у нас сотни, p+1 - десятки, p+2 - единицы очередной нашей группы
      if(+raw[p+1]==1){t=0} // Высчитываем окончание подписи (-а, -ов, -ей...), если десятки=1 то на единицы даже не смотрим
      if(t>1&&t<5){t=2} // Если единицы = 2,3,4, то добавка к индексу базы подписей +2 (м..ОВ, рублЕЙ)
      if(t>4||t==0){t=3} // Если 0 или 5+ то добавка 3 (единица так и остается добавкой 1)
      i=+raw[p]; // Собственно сама цифра (начнем с разряда сотен)
      raw[p]=h100[i]; // Заменили сотни (разряд сотен - тупо подстановка)
      i=+raw[p+1]; // Разряд десятков: если >=20 - тоже заменяем
      if (i>1){raw[p+1]=h010[i]; i=0} // Заменили десятки (двадцать и больше)
      k=i*10+(+raw[p+2]); // Считаем индекс K (для массива h011)
      if(!isNaN(raw[p+1])){raw[p+1]=""} // Пустоту в десятки если прошлой операцией не заменили на строку
      raw[p+2]=h011[k]; // Заменили 0, 1... 9, 10, 11, 12 ... 19
      if(group==2&&k==1){raw[p+2]="одна"} // В разряде тысяч один->одна)
      if(group==2&&k==2){raw[p+2]="две"} // В разряде тысяч два->две)
      if(group==3||(raw[p]+raw[p+1]+raw[p+2]).length>0){ // Если подпись вообще нужна, то... (нужна если "рублей" или непустые триады)
      raw[p+2]+=h000[group*4]; // Добавляем подпись к единицам (корень)
      raw[p+2]+=h000[group*4+t];} // Добавляем подпись к единицам (окончание)
      }
      res = raw.join(' ')+result; // Склеиваем строку обратно через пробел и пришиваем обратно дробную часть
      res = res.replace(/ +/g," ").trim(); // Убираем двойные пробелы, если вдруг появились, плюс лидирующие и замыкающие
      res = res.charAt(0).toUpperCase()+res.slice(1); // Первую букву заглавной
      return res; // Для нашего примера: Восемнадцать миллиардов сто два миллиона четыреста двенадцать тысяч девятьсот девяносто рублей 42 коп.
      }

      Ответить
      • Vlad
        Vlad
        25.05.2019 21:19

        Спасибо огромное!!!
        Но:

        var result=" "+res.substr(res.length-2)+" коп.";// Копируем хвост с копейками в результат "как есть"

        Пишет ошибку:
        Uncaught TypeError: Cannot read property 'substr' of undefined

        Ответить

      Оставить комментарий Отмена

      *

      *

      *

      *

      Категории

      • PHP
        • Framework Kohana
      • Javascript
      • CSS
      • Администрирование

      Теги

      Framework Kohana Пример jQuery Уроки CRON Установка и настройка Backup CSS3 Валидация API Bash Cache Captcha i18n Linux

      Авторизация

      • Забыли пароль?
      • Регистрация

      Популярные статьи

      • Находим расстояние до ближайших станций метро

        Находим расстояние до ближайших станций метро

        17.02.2017 102982
      • Регистрация и авторизация пользователей. Модуль Auth в Kohana 3.3.x

        Регистрация и авторизация пользователей. Модуль Auth в Kohana 3.3.x

        02.07.2014 44646
      • Собственная система лайков на PHP и JQuery

        Собственная система лайков на PHP и JQuery

        06.04.2015 33241
      • Javascript — сумма прописью

        Javascript — сумма прописью

        07.07.2014 23091
      • Cross-domain ajax с помощью jQuery

        Cross-domain ajax с помощью jQuery

        24.04.2015 19964
      Copyright © 2014-2025 Frameworks.su. Все права защищены.