Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Добавление / удаление значений в массив (https://javascript.ru/forum/jquery/59463-dobavlenie-udalenie-znachenijj-v-massiv.html)

rostik1991 12.11.2015 10:29

Добавление / удаление значений в массив
 
Здравствуйте. Уже обращался на форум, но теперь мне нужно немного переделать старый скрипт. Кратко о том что нужно:

Есть у меня список ингредиентов - "ing_list"
Есть две кнопки "ing_add", различаю их по атрибуту data('opetarion') есть МИНУС и ПЛЮС;
Есть счетчик ингредиентов count_ing и массив ингредиентов ingredients и цена каждого из ингредиентов ing_price.

Вот сам код:

<!DOCTYPE HTML>
 
<html>
 
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
$(document).ready(function(){
var ing_list = $('.add_ing_list li'),
        ing_add=ing_list.find('span.add_new_ing'),
        count_ing = 0,//счетчик ингредиентов
        ingredients='',//массив ингредиентов
        ing_price = 0;//общая цена ингредиентов

//нужно сделать еще счетчик цены ing_price чтобы он добавлялся или отнимался в зависимости от выполняемого действия

ing_add.click(function () {
        var ing_price = $(this).data('ord');//цена ингредиента
        var operation = $(this).data('operation');//операция плюс или минус
        if(operation=='plus'){
        if($(this).parent('li').hasClass('added_to_list')){
            count_ing++;
            $(this).parent('li').find('span.count_ing').text('+'+count_ing+' ');
            
            ingredients = $.map($($(this).parent('li.added_to_list')),function(el) {
                            return $(el).text()
                        });
            
        }else{
            count_ing=$(this).parent('li').find('span.count_ing').text();
            count_ing++;
            $(this).parent('li').addClass('added_to_list');
            $(this).parent('li').find('span.count_ing').text('+'+count_ing+' ');
           
            ingredients = $.map($($(this).parent('li.added_to_list')),function(el) {
                return $(el).text()
            });
        }
        } else if(operation=='minus'){
           count_ing--;
           if($(this).parent('li').hasClass('added_to_list')){
               if(count_ing<=0){
                   $(this).parent('li').removeClass('added_to_list');
                   $(this).parent('li').find('span.count_ing').text('');
                   count_ing=0;
                   
                   ingredients = $.map($($(this).parent('li.added_to_list')),function(el) {
                       return $(el).text('')
                   });
               }else{
                   $(this).parent('li').find('span.count_ing').text('+'+count_ing+' ');
                   
                   ingredients = $.map($($(this).parent('li.added_to_list')),function(el) {
                       return $(el).text()
                   });
               }
           }else{
               return false;
           }

       } else {
           return false;
       }
    alert(ingredients)
    });
});

</script>
</head>
 
<body>

<div class="pizza_add_ing">
       <ul class="add_ing_list">
             <li data-ord="10" data-id="1">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Сыр
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
             </li>

             <li data-ord="15" data-id="2">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Томаты
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
             </li>

             <li data-ord="20" data-id="3">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Курица
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
              </li>
        </ul>
</div><!-- .pizza_add_ing -->





</body>
 
</html>

Что мне нужно и что у меня получается:

Когда я нажимаю на ПЛЮС возле названия ингредиента появляется количество, и добавляется класс "added_to_list",
в массив ингредиентов должно заноситься значение, то есть весь текст родительского элемента <li>
когда нажимаю на МИНУС, количество уменьшается и из массива должно удалиться то количество которое удалили или вообще удалить из массива данный ингредиент, если количество равно = 0.
Сейчас у меня следующие проблемы:
1) когда я добавляю несколько разных ингредиентов, у меня счетчик сбивается. То есть, допустим я добавил +3 сыр, +3 томаты, +7 курицы, и когда я нажму на кнопку ПЛЮС чтобы добавить сыр, счетчик посчитает уже +8 сыр. то есть возьмет последнее значение которое я добавил и добавит +1, то есть последнее было +7 курицы, сыр станет +8.

2)Когда я добавляю элементы в массив, они просто перезаписываются в место уже имеющихся
3)Когда я отминусую все элементы - текст <li> вообще пропадает.

Надеюсь поймете :)) Спасибо

ksa 12.11.2015 11:11

Как вариант...

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='http://code.jquery.com/jquery-latest.js'></script>
<!--
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.9/angular-route.js"></script>
-->
<style type='text/css'>
</style>
<script type='text/javascript'>
$(function(){
	$('.add_new_ing').click(function(){
		var n=($(this).data('operation')=='minus')? -1: 1;
		var o=$(this.parentNode);
		var ocnt=o.find('.count_ing');
		var val=+ocnt.text();
		val=val+n;
		if (val<1) {
			o.remove();
			return;
		};
		ocnt.text(val);
	});
})
</script>
</head>
<body>
<div class="pizza_add_ing">
	<ul class="add_ing_list">
		<li data-ord="10" data-id="1">
			<span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
			<span class="count_ing"></span>Сыр
			<span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
		</li>
		<li data-ord="15" data-id="2">
			<span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
			<span class="count_ing"></span>Томаты
			<span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
		</li>
		<li data-ord="20" data-id="3">
			<span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
			<span class="count_ing"></span>Курица
			<span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
		</li>
	</ul>
</div>
</body>
</html>

рони 12.11.2015 14:12

калькулятор продуктов и сумма
 
rostik1991,
:(
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .add_new_ing {
    cursor: pointer;
    margin: 0 4px;
  }

  li .add_ing_minus {
      visibility: hidden;
  }
  li.added_to_list .add_ing_minus {
       visibility: visible;
  }
  li{
    list-style-type: none;
  }

  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
$(function() {
    var ing_list = $(".add_ing_list li"),
        ing_add = ing_list.find("span.add_new_ing"),
        count_ing = {},
        ingredients = [],
        ing_price = 0,
        ing_text = {1 : 'Сыр',2 : 'Томаты', 3 : 'Курица'};
    ing_list.each(function(indx, li) {
        li = $(li);
        li.on("click", "span.add_new_ing", function(event) {
            event.preventDefault();
            var add = $(this).data("operation") == "plus" ? 1 : -1;
            var id = li.data("id");
            var count = (count_ing[id] || 0) + add;
            count < 0 && (count = 0);
            count_ing[id] = count;
            $("span.count_ing",
                li).text(count ? count + " " : "");
            li.toggleClass("added_to_list", !!count);
            ingredients = [];
            ing_price = 0;
            $.each(ing_list, function(i, li) {
                li = $(li);
                var id = li.data("id");
                var count = count_ing[id] || 0;
                var price = li.data("ord");
                if (count) {
                    ingredients.push(count + " " + ing_text[id]);
                    ing_price += price * count
                }
            });
            $("p").html(ingredients + '<br>Итого: ' + ing_price)
        })
    })
});
</script>
</head>

<body>

<div class="pizza_add_ing">
       <ul class="add_ing_list">
             <li data-ord="10" data-id="1">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Сыр
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
             </li>

             <li data-ord="15" data-id="2">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Томаты
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
             </li>

             <li data-ord="20" data-id="3">
                  <span class="add_new_ing add_ing_minus" data-operation="minus">-</span>
                  <span class="count_ing"></span>Курица
                  <span class="add_new_ing add_ing_plus"data-operation="plus">+</span>
              </li>
        </ul>
</div><!-- .pizza_add_ing -->

<p></p>



</body>

</html>

rostik1991 12.11.2015 19:42

К сожалению этот вариант вообще не подходит. Мне нужно отслеживать и добавлять значения именно в момент нажатия, и именно по конкретному элементу. Так как все ингредиенты и цены я достаю из базы через PHP, Ваш же вариант работает только здесь :-? :(

рони 12.11.2015 19:56

Цитата:

Сообщение от rostik1991
Так как все ингредиенты и цены я достаю из базы через PHP

это ничего не меняет ... доставая из базы просто можно добавить алгоритм этого кода ... при правильной иницализации никаких даже data не потребуется ... но раз не подошёл, значит не судьба :)

ksa 13.11.2015 08:43

Цитата:

Сообщение от rostik1991
К сожалению этот вариант вообще не подходит.

Это тебе только так кажется...

rostik1991 13.11.2015 14:19

Цитата:

Сообщение от ksa (Сообщение 395963)
Это тебе только так кажется...

Признаюсь) Я еще зеленый в делах с JS :)

stelert 13.11.2015 14:25

Все данные сохраняются в ing.ingridients т.е. твой массив.

<!DOCTYPE HTML>

<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script>
$(document).ready(function(){

    setObj = Object.defineProperty;

    ing = {
        ingridients: {},
        action: {},

        run: function() {
          this.clickWacher();
        },

        clickWacher: function() {
            var _this = this;

            $(".ing_change").click(function() {
                _this.collectData(this);
                _this.calculate();
                _this.populateData();
                _this.changeCounter(this);
          });
        },

        collectData: function(elem) {
            this.action = {
                ingridient: $(elem).parent().data('ing'),
                price: $(elem).parent().data('price'),
                change: $(elem).text(),
                label: $(elem).parent().find('.ing_label').text()
            }
        },

        calculate: function() {
            if (!this.ingridients[this.action.ingridient]) {
                var i = this.action.change == "+" ? 1 : 0 ;
                setObj(this.ingridients, this.action.ingridient, {
                    value: {
                        price: this.action.price,
                        num: i,
                        label: this.action.label
                    }
                });
            }
            else if (this.ingridients[this.action.ingridient].num > 0 || this.action.change == "+") {
                this.ingridients[this.action.ingridient].num += this.action.change == "+" ? 1 : -1 ;
                this.ingridients[this.action.ingridient].price = this.action.price * this.ingridients[this.action.ingridient].num ;
            }
        },

        populateData: function() {
            if (this.ingridients[this.action.ingridient].num > 0) {
                if ($('#' + this.action.ingridient).length == 0) $('.stat').append('<p id="' + this.action.ingridient + '"></p>');
                $('#' + this.action.ingridient).text("Ингридиент: "+ this.action.label + " " + this.ingridients[this.action.ingridient].num
                + "шт. " + this.action.price + "$. Сумма: " + this.ingridients[this.action.ingridient].price + "$");
            }
            else $("#" + this.action.ingridient).remove();
        },

        changeCounter: function(elem) {
            var counter = $(elem).parent().find('.ing_num').text(": " + this.ingridients[this.action.ingridient].num);
        }

    }

    ing.run();

});
    </script>
</head>

<body>

<div class="pizza_add_ing">
    <ul class="add_ing_list">
        <li data-ing="cheese" data-price="10">
            <span class="ing_change">-</span>
            <span class="ing_label">Сыр</span><span class="ing_num">: 0</span>
            <span class="ing_change">+</span>
        </li>

        <li data-ing="tomato" data-price="15">
            <span class="ing_change">-</span>
            <span class="ing_label">Томаты</span><span class="ing_num">: 0</span>
            <span class="ing_change">+</span>
        </li>

        <li data-ing="chicken" data-price="20">
            <span class="ing_change">-</span>
            <span class="ing_label">Курица</span><span class="ing_num">: 0</span>
            <span class="ing_change">+</span>
        </li>
    </ul>
    <div class="stat"></div>
</div>


<style>
    .ing_change {
        background: #558b2f;
        color: #ffffff;
        font-weight: bold;
        cursor: pointer;
        width: 25px;
        display: inline-block;
        text-align: center;
        line-height: 25px;
    }
    li {
        margin-bottom: 15px;
        list-style: none;
    }
    .ing_label {
        width: 55px;
        display: inline-block;
    }
    .ing_num {
        width: 25px;
        display: inline-block;
    }
</style>
</body>

</html>


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