Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Подсчет общей суммы на 3 и более ингредиента (https://javascript.ru/forum/css-html/52642-podschet-obshhejj-summy-na-3-i-bolee-ingredienta.html)

EviLex 28.12.2014 18:54

Подсчет общей суммы на 3 и более ингредиента
 
Привет всем, говорю сразу я только учусь JS и jQuery. Так что всем советам и замечаниям буду рад.
Мучался я долго с этим скриптом, в итоге, у меня так и не вышло сделать подсчет общей суммы для 3х и более добавленных ингредиентов (только для первых 2 осилил), при условии что все данные добавленные в любой момент могут меняться, прошу вашей помощи :thanks:

<div class="container">
    <ul id="ingred"></ul>
    <a href="#" class="add-contact">+ Добавить ингредиент</a>
    <div id="sumAll"></div>
</div>

var sakhar = [
    ['Карамель', 3.11, 0, 0.001, 0.777],
    ['Шоколад темный', 5.64, 0.054, 0.353, 0.526]
];
var orekhi = [
    ['Арахис', 5.82, 0.263, 0.452, 0.097],
    ['Грецкий орех', 6.75, 0.138, 0.613, 0.102],
    ['Миндаль', 6.78, 0.186, 0.577, 0.136],
    ['Семя подсолнечника', 6.09, 0.207, 0.529, 0.05],
    ['Фундук', 7.37, 0.161, 0.669, 0.099]
];

var cats = [
    [sakhar, 'Карамель, шоколад'],
    [orekhi, 'Орехи']
];

var sumId = [];
var sum = [];
var sumx = [];
var total = [];

$("#ingred").on("click", "span", function () {
    $(this).parent("li").remove();
    $("#ingred li").children('a').first().click();
});

$('body').on('keyup', 'input', function () {
    if ( sum[0] === 0 ){
        sum.shift();
        for ( var x in sum ){
            sumx.splice(x,1, sum[x])
        }
        sum.unshift();
        $('div#sumAll').append('<span><strong>Масса:</strong>'+sumx[0]+', <strong>кКал:</strong>'+sumx[1]+', <strong>Белки:</strong>'+sumx[2]+', <strong>Жиры:</strong>'+sumx[3]+', <strong>Углеводы</strong>:'+sumx[4]+'</span>');
    } else {
        sum.shift();
        if ( sumId.length <= 2 ){
            for ( var a in sumx ){
                console.log('sumx[a]:'+sumx+' sum[a]:'+sum);
                total.splice(a,1, sumx[a]+sum[a]);
                total[a] = Math.floor(total[a]*100)/100;
                sumx[a] = Math.floor(sumx[a]*100)/100;
                sum[a] = Math.floor(sum[a]*100)/100;
            }
            console.log('total (sumId <= 2):'+total);
        } else {
            //for ( var x in sumId ){
                console.log('total (sumId <= 2):'+total+' sum[a]:'+sum);
                for ( var c in total ){
                    total.splice(c,1, total[c]+sum[c]);
                    total[c] = Math.floor(total[c]*100)/100;
                    sumx[c] = Math.floor(sumx[c]*100)/100;
                    sum[c] = Math.floor(sum[c]*100)/100;
                }
                console.log('total (else):'+total);
            //}
                
        }
        sum.unshift();
        $('div#sumAll span').remove();
        $('div#sumAll').append('<span>Общая:<br/><strong>Масса:</strong>'+total[0]+', <strong>кКал:</strong>'+total[1]+', <strong>Белки:</strong>'+total[2]+', <strong>Жиры:</strong>'+total[2]+', <strong>Углеводы</strong>:'+total[4]+'</span>');
        
    }
});

$('.add-contact').on("click", function () {
    var id = $("#ingred").children().length; //think about it ;)
    var tabId = 'item' + id;
    $('#ingred').append('<li><div id="' + tabId + '"><select data-placeholder="Продукт" class="chosen-select'+id+'"></select></div><span> x </span></li>');
    for ( var a in cats ){
        var ne = cats[a][0];
        $('<optgroup label="'+cats[a][1]+'"></optgroup>').appendTo('select');
        for ( var b in ne ){
            $('<option name="'+ne[b][0]+'">'+ne[b][0]+'</option>').appendTo($('optgroup[label="'+cats[a][1]+'"]'));
        }
    }
    $('.chosen-select'+id).prepend("<option></option>");
    $('.chosen-select'+id).change(function(){
    //console.log('ID:'+id);
    for ( var j in cats ){
        var ne = cats[j][0];
        for ( var i in ne ){
            if ($(this).val() == ne[i][0]){
                $('div#'+tabId+' p').remove();
                $('div#'+tabId).append('<p><strong>Масса: </strong><input id="inp'+id+'" class="input" type="text" maxlength="4" placeholder="вес" /> гр. </p>');
                $('#inp'+id).keyup(function(){
                    var sum0 = $(this).prop('value');
                    var sum1 = sum0 * ne[i][1]; sum1 = sum1.toFixed(2);
                    var sum2 = sum0 * ne[i][2]; sum2 = sum2.toFixed(2);
                    var sum3 = sum0 * ne[i][3]; sum3 = sum3.toFixed(2);
                    var sum4 = sum0 * ne[i][4]; sum4 = sum4.toFixed(2);
                    sum = [Number(id), Number(sum0), Number(sum1), Number(sum2), Number(sum3), Number(sum4)];
                    //console.log('sum:'+sum);
                    $('div#sumAll span').remove();
                    $('div#'+tabId+' p span').remove();
                    $('div#'+tabId+' p').append('<span><strong>кКал:</strong>'+sum[2]+', <strong>Белки:</strong>'+sum[3]+', <strong>Жиры:</strong>'+sum[4]+', <strong>Углеводы</strong>:'+sum[5]+'</span>');
                });
                return false;
            } //if
        } // for
    } //for
    }); // .chosen-select
    
    sumId.push(id);
    console.log('sumId:'+sumId);
    
});

рони 28.12.2014 19:43

EviLex,
нужен 1 массив по количеству инградиентов -- изначально все элементы массива 0 -- при добавке или удалениии соотвествующий элемент меняется на (вес или сразу сумму инградиета или 0) затем обход всех элементов и выдача общей суммы - и всё

EviLex 28.12.2014 20:13

Цитата:

Сообщение от рони (Сообщение 348677)
EviLex,
нужен 1 массив по количеству инградиентов -- изначально все элементы массива 0 -- при добавке или удалениии соотвествующий элемент меняется на (вес или сразу сумму инградиета или 0) затем обход всех элементов и выдача общей суммы - и всё

Спасибо за ответ. Звучит просто, можно попросить маленький примерчик? чтобы логику понять

рони 28.12.2014 20:41

EviLex,
вы бы сами пример сделали полноценный с запуском, сейчас совершенно непонятно ни алгоритм добавления ни подсчёта

рони 28.12.2014 20:44

Цитата:

Сообщение от EviLex
маленький примерчик?

http://javascript.ru/forum/dom-windo...tml#post298023

EviLex 28.12.2014 20:50

Этот пример рабочий http://jsfiddle.net/d1wztvdp/1/, спасибо за ссылку на калькулятор, постараюсь разобраться.

рони 28.12.2014 21:04

Цитата:

Сообщение от рони
Этот пример рабочий

возможно )))
Цитата:

Сообщение от рони
вы бы сами пример сделали полноценный с запуском, сейчас совершенно непонятно ни алгоритм добавления ни подсчёта

если будут вопросы сделайте предварительно макет с возможностью запуска -- как по ссылке выше.

EviLex 29.12.2014 00:09

$('body').on('keyup', 'input', function () {
    for ( var c in total ){
        total.splice(c,1, 0);
    }
    sum.shift();
    for ( var x in sumId ){
        var i = 0;
        for ( var v in total ){
            console.log('total:'+total+' sum:'+sum);
            total[v]+=sum[v];
            total[v] = Math.floor(total[v]*100)/100;
        }
    }
    sum.unshift();
    $('div#sumAll span').remove();
    $('div#sumAll').append('<span>Общая:<br/><strong>Масса:</strong>'+total[0]+', <strong>кКал:</strong>'+total[1]+', <strong>Белки:</strong>'+total[2]+', <strong>Жиры:</strong>'+total[3]+', <strong>Углеводы</strong>:'+total[4]+'</span>');
});

Вот ссылка на почти рабочий вариант http://jsfiddle.net/d1wztvdp/2/
Вкратце как это все работает:
В коде создается уникальный sum для каждого нового ингредиента (при нажатии на "+ Добавить ингредиент") его данные (калории и тп) меняются в зависимости от введных данных в его личный input.
Первая ячейка массива sum хранит уникальный id.

Теперь вопрос:
Сейчас суммируются данные последнего ингредиента сами на себя, подскажите как подправить чтобы суммировались все ингредиенты? Думаю нужно как-то цикл дописать но не могу понять как это сделать в данном случае.

EviLex 29.12.2014 00:10

=)

рони 29.12.2014 01:20

EviLex,
может в раздел работа? или попробуйте локализовать проблему - сейчас слишком много кода а результат кода накладывается на прежний результат

EviLex 29.12.2014 09:51

Я сам учусь, спасибо, буду думать дальше.

рони 29.12.2014 10:45

EviLex,
:write:
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type='text/css'>
  .container{
    margin-top:10px;
    width:340px;
  }

  ul{
    margin:0;
    padding:0;
  }

  #ingred>li{
    position:relative;
    list-style:none;
    border:rgb(153,51,0) solid 1px;
    border-radius:2px;
  }

  #ingred>li>span{
    display:none;
    cursor:pointer;
    position:absolute;
    right:5px;
    top:0px;
    color:red;
  }

  #ingred>li:hover>span{
    display:inline-block;
  }

  input{
    width:50px;
  }

  li p{
    margin:0;
  }

  li strong{
    font-size:12px;
  }

  #sumAll,h4{
    margin:0;
    padding:0;
  }
  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
     $(function() {
         var sakhar = [
             ['Карамель', 3.11, 0, 0.001, 0.777],
             ['Шоколад темный', 5.64, 0.054, 0.353, 0.526]
         ];
         var orekhi = [
             ['Арахис', 5.82, 0.263, 0.452, 0.097],
             ['Грецкий орех', 6.75, 0.138, 0.613, 0.102],
             ['Миндаль', 6.78, 0.186, 0.577, 0.136],
             ['Семя подсолнечника', 6.09, 0.207, 0.529, 0.05],
             ['Фундук', 7.37, 0.161, 0.669, 0.099]
         ];

         var cats = [
             [sakhar, 'Карамель, шоколад'],
             [orekhi, 'Орехи']
         ];

         var arr = [' Масса: ', ' кКал: ', ' Белки: ', ' Жиры: ', ' Углеводы: '];
         var opt = [];

         function sum() {
             var res = [0, 0, 0, 0, 0];
             $("#ingred select").each(function(indx, element) {
                 var parent = $(this).parents("li");
                 var val = +parent.find("input").val() || 0;
                 var a = $.map(opt[this.value], function(el, i) {
                     res[i + 1] += +(val * el).toFixed(2);
                     return "<strong>" + arr[i + 1] + "</strong>" + (val * el).toFixed(2)
                 });
                 res[0] += val;
                 parent.find("p").html(a)
             });
             res = res[0] ? $.map(res, function(el, i) {
                 return "<strong>" + arr[i] + "</strong>" + el.toFixed(2)
             }) : "";
             $("#sumAll").html(res)
         }

         var $sel = $("<select/>", {
             on: {
                 "change": sum
             }
         });
         $.each(cats, function(indx, el) {
             $("<optgroup/>", {
                 "label": el[1]
             }).appendTo($sel);
             $.each(el[0], function(ind, elem) {
                                  $("<option/>", {
                     "val": opt.length,
                     text: elem[0]
                 }).appendTo($sel);
               opt.push(elem.slice(1));

             })
         });
         var $inp = $('<label/>').append(
             $("<input/>", {
                 val: 1,
                 maxlength: "4",
                 placeholder: "вес",
                 on: {
                     "input": sum
                 }
             })).prepend(" Масса: ");
         $(".add-contact").click(function(event) {
             event.preventDefault();
             var $li = $("<li/>").appendTo("#ingred");
             $sel.clone(true, true).appendTo($li);
             $inp.clone(true, true).appendTo($li);
             var $p = $("<p/>").appendTo($li);
             var $span = $("<span/>", {
                 text: "x",
                 on: {
                     click: function() {
                         $li.remove();
                         sum()
                     }
                 }
             }).appendTo($li);
             sum()
         });

     });
  </script>
</head>

<body>
<div class="container">
    <ul id="ingred"></ul>
    <a href="#" class="add-contact">+ Добавить ингредиент</a>
    <h4>Всего:</h4>
    <div id="sumAll"></div>
</div>
</body>
</html>

EviLex 29.12.2014 10:59

Мда, по сравнению с вашим кодом, мой выглядит ужасно топорным, спасибо большое, побежал вникать.

рони 29.12.2014 11:53

EviLex,
исправлено
строка 111 была не на своём месте


Часовой пояс GMT +3, время: 02:40.