Суммируйте десятичные дроби от $ .each l oop с функцией приращения - PullRequest
0 голосов
/ 09 апреля 2020

Я получил код, где JS суммирует значения из входных данных из таблицы, используя функцию $ .each, все нормально, но не десятичные дроби. Значения во входных данных идут десятичными, но результаты - только целые числа Это работает без функции увеличения

Вот мой код:

    var summaryNetto = 0;
    var summaryVat = 0;
    var summary = 0;



    $('#products > tbody  > tr').each(function() {

        summaryNetto += parseFloat($(this).find('input[name="singlePriceSummaryNetto"]').val());
        summaryVat += parseFloat($(this).find('input[name="singleVatSummary"]').val());
        summary += parseFloat($(this).find('input[name="singleSummaryBrutto"]').val());

    })

        console.log('summaryNetto: '+summaryNetto);
        console.log('summaryVat: '+summaryVat);
        console.log('summary: '+summary);

А вот результат

summaryNetto: 1333
summaryVat: 0
summary: 1333

Я положил во входные значения значение = 1333,33.

Я проверил это без функции приращения, конечно принимая значения от входов до JS, и это работает. Если я использую функцию приращения ранее установленной переменной, например, var summary = 0; к сожалению, не добавляет десятичное значение.

 $(document).on("keyup click", 'td > input', function() {

        const format = (num, decimals) => num.toLocaleString('pl-PL', {
            minimumFractionDigits: 2,      
            maximumFractionDigits: 2,
                    });

          var row = $(this).closest("tr");

        var quantity = row.find("input[name='quantity']").val();
        var singlePriceNetto = row.find("input[name='singlePriceNetto']").val();
        var singlePriceSummaryNetto = quantity * singlePriceNetto;
        row.find('input[name="singlePriceSummaryNetto"]').val(format(singlePriceSummaryNetto));

        var singleVat = row.find("input[name='singleVat']").val();
        var singleVatSummary = (singlePriceSummaryNetto * singleVat.replace('%', '')) / 100;
        row.find('input[name="singleVatSummary"]').val(format(singleVatSummary));

        var singleSummaryBrutto = singlePriceSummaryNetto + singleVatSummary;
        row.find('input[name="singleSummaryBrutto"]').val(format(singleSummaryBrutto));

        var summaryNetto = 0;
        var summaryVat = 0;
        var summary = 0;



        $('#products > tbody  > tr').each(function() {

            summaryNetto += parseFloat($(this).find('input[name="singlePriceSummaryNetto"]').val());
            summaryVat += parseFloat($(this).find('input[name="singleVatSummary"]').val());
            summary += parseFloat($(this).find('input[name="singleSummaryBrutto"]').val());

        })

            console.log('summaryNetto: '+summaryNetto);
            console.log('summaryVat: '+summaryVat);
            console.log('summary: '+summary);

        $('span#summaryNetto').empty();
        $('span#summaryNetto').append(format(summaryNetto) + 'zł');
        $('span#summaryVat').empty();
        $('span#summaryVat').append(format(summaryVat) + 'zł');
        $('span#summary').empty();
        $('span#summary').append(format(summary) + 'zł');

    })

*************** OK ТАК ПРАВИЛЬНЫЙ КОД ************ **********

var summaryNetto = 0;
var summaryVat = 0;
var summary = 0;



$('#products > tbody  > tr').each(function() {

    summaryNetto += parseFloat($(this).find('input[name="singlePriceSummaryNetto"]').val().replace(',', '.'));
    summaryVat += parseFloat($(this).find('input[name="singleVatSummary"]').val().replace(',', '.'));
    summary += parseFloat($(this).find('input[name="singleSummaryBrutto"]').val().replace(',', '.'));

})

    console.log('summaryNetto: '+summaryNetto);
    console.log('summaryVat: '+summaryVat);
    console.log('summary: '+summary);

************* КОД С Очищенными белыми пространствами для Польши ************ ******

var summaryNetto = 0;
var summaryVat = 0;
var summary = 0;



$('#products > tbody  > tr').each(function() {
    singlePriceSummaryNetto = $(this).find('input[name="singlePriceSummaryNetto"]').val().replace(/\s+/g, '');
    summaryNetto += parseFloat(singlePriceSummaryNetto.replace(',','.'));
    singleVatSummary = $(this).find('input[name="singleVatSummary"]').val().replace(/\s+/g, '');
    summaryVat += parseFloat(singleVatSummary.replace(',', '.'));
    singleSummaryBrutto = $(this).find('input[name="singleSummaryBrutto"]').val().replace(/\s+/g, '');
    summary += parseFloat(singleSummaryBrutto.replace(',', '.'));

})


$('span#summaryNetto').empty();
$('span#summaryNetto').append(format(summaryNetto) + 'zł');
$('span#summaryVat').empty();
$('span#summaryVat').append(format(summaryVat) + 'zł');
$('span#summary').empty();
$('span#summary').append(format(summary) + 'zł');

Ответы [ 3 ]

1 голос
/ 09 апреля 2020

Причина в том, что вы используете toLocaleString() для языка Poli sh. В Польше символ разделителя дроби - это запятая, а не точка.

Следовательно, parseFloat('1333,33') равно 1333. Загадка решена.

Если вы заинтересованы в дальнейшем улучшении, вы можете запустить следующий код, чтобы увидеть, каковы действительные форматы:

const languages = ['ar-SA', 'bn-BD', 'bn-IN', 'cs-CZ', 'da-DK', 'de-AT', 'de-CH', 'de-DE', 'el-GR', 'en-AU', 'en-CA', 'en-GB', 'en-IE', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'es-AR', 'es-CL', 'es-CO', 'es-ES', 'es-MX', 'es-US', 'fi-FI', 'fr-BE', 'fr-CA', 'fr-CH', 'fr-FR', 'he-IL', 'hi-IN', 'hu-HU', 'id-ID', 'it-CH', 'it-IT', 'jp-JP', 'ko-KR', 'nl-BE', 'nl-NL', 'no-NO', 'pl-PL', 'pt-BR', 'pt-PT', 'ro-RO', 'ru-RU', 'sk-SK', 'sv-SE', 'ta-IN', 'ta-LK', 'th-TH', 'tr-TR', 'zh-CN', 'zh-HK', 'zh-TW'];

console.log(languages.reduce((result, language) => ({...result, [language]: (12345.6789).toLocaleString(language, {maximumFractionDigits: 20})}), {}));

Результат:

{
    "ar-SA": "١٢٬٣٤٥٫٦٧٨٩",
    "bn-BD": "১২,৩৪৫.৬৭৮৯",
    "bn-IN": "১২,৩৪৫.৬৭৮৯",
    "cs-CZ": "12 345,6789",
    "da-DK": "12.345,6789",
    "de-AT": "12 345,6789",
    "de-CH": "12’345.6789",
    "de-DE": "12.345,6789",
    "el-GR": "12.345,6789",
    "en-AU": "12,345.6789",
    "en-CA": "12,345.6789",
    "en-GB": "12,345.6789",
    "en-IE": "12,345.6789",
    "en-IN": "12,345.6789",
    "en-NZ": "12,345.6789",
    "en-US": "12,345.6789",
    "en-ZA": "12 345,6789",
    "es-AR": "12.345,6789",
    "es-CL": "12.345,6789",
    "es-CO": "12.345,6789",
    "es-ES": "12.345,6789",
    "es-MX": "12,345.6789",
    "es-US": "12,345.6789",
    "fi-FI": "12 345,6789",
    "fr-BE": "12 345,6789",
    "fr-CA": "12 345,6789",
    "fr-CH": "12 345,6789",
    "fr-FR": "12 345,6789",
    "he-IL": "12,345.6789",
    "hi-IN": "12,345.6789",
    "hu-HU": "12 345,6789",
    "id-ID": "12.345,6789",
    "it-CH": "12’345.6789",
    "it-IT": "12.345,6789",
    "jp-JP": "12 345,6789",
    "ko-KR": "12,345.6789",
    "nl-BE": "12.345,6789",
    "nl-NL": "12.345,6789",
    "no-NO": "12 345,6789",
    "pl-PL": "12 345,6789",
    "pt-BR": "12.345,6789",
    "pt-PT": "12 345,6789",
    "ro-RO": "12.345,6789",
    "ru-RU": "12 345,6789",
    "sk-SK": "12 345,6789",
    "sv-SE": "12 345,6789",
    "ta-IN": "12,345.6789",
    "ta-LK": "12,345.6789",
    "th-TH": "12,345.6789",
    "tr-TR": "12.345,6789",
    "zh-CN": "12,345.6789",
    "zh-HK": "12,345.6789",
    "zh-TW": "12,345.6789"
}

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

Я написал функцию, которая преобразует любой номер строки локали (локаль клиента по умолчанию) в фактическое число. Другими словами, это обратное значение toLocaleString().

function numberFromLocaleString(localeString, locale = undefined) {
    const [, thousandSeparator, fractionSeparator] = (12345.6).toLocaleString(locale).match(/12(.*)345(.*)6/);

    return parseFloat([...String(localeString.replace(/\s+/g, ''))].map(character => character.replace(thousandSeparator, '')).join('').replace(fractionSeparator, '.'));
}

Тесты:

numberFromLocaleString('1') // 1, uses client's locale
numberFromLocaleString('12.34', 'en-US') // 12.34
numberFromLocaleString('12 345,6789', 'pl-PL') // 12345.6789
numberFromLocaleString('-12 345,6789', 'pl-PL') // -12345.6789
numberFromLocaleString('-12’345.6789', 'de-CH') // -12345.6789
numberFromLocaleString('123.456', 'en-US') // 123.456
numberFromLocaleString('123,456', 'en-US') // 123456

Имейте в виду, что я просто удаляю все пробелы из числа ввода перед анализом локаль одна. Это потому, что разделитель пробелов, который существует в некоторых языках (включая Poli sh), не является обычным пробелом. Это неразрывный пробел, и я не вижу, чтобы кто-то его печатал.

1 голос
/ 09 апреля 2020

Вот пример кода

var totalValue = 0;

$('div').each(function() {
    var inputEl = $(this).find('input[type="text"]');
    var rawInputElValue = inputEl.val();
    // replace invalid charaacters like whitespaces
    rawInputElValue = rawInputElValue.replace(/\s+/g, '');
    var inputElValue = parseFloat(rawInputElValue);
    totalValue += inputElValue;
});

$('#total').val(totalValue)
<html>
<body>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<div>
  <input type="text" id="input1" value="10 000.1">
</div>
<div>
  <input type="text" id="input2" value="20 000 200.2">
</div>
<div>
  <input type="text" id="input3" value="3.3">
</div>
total: <input type="text" id="total">
</body>
</html>
0 голосов
/ 09 апреля 2020

Хорошо, спасибо вам обоим.

Все отлично работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...