Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   пересчет суммы в заказе в зависимости от выбраных чекбоксов (https://javascript.ru/forum/dom-window/29391-pereschet-summy-v-zakaze-v-zavisimosti-ot-vybranykh-chekboksov.html)

georg 26.06.2012 09:55

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

У меня пока сделан только подсчет в зависимости от измененного количества, вот скрипт(источник):
function calculate(quantity, price, updItemId){
            
        var anum = /(^\d+$)|(^\d+\.\d+$)/;
        if (!anum.test(quantity)) {
            
            alert('Введенное значение не является числом!');
            return;
        }
		
         // сумма = количество * цену
        goodSum = quantity * price;
        
        document.getElementById(updItemId).innerHTML = goodSum;
        var meForm   = document.getElementById('me_order_form');
        var bdoArray  = meForm.getElementsByTagName('bdo');
            // устанавливаем начальное нулевое значение ОБЩЕЙ суммы
        var allSumm = 0;
            // и в цикле прибавляем к ней сумму каждого товара
        for (j = 0; j < bdoArray.length; j++) {
             
            allSumm = allSumm + parseFloat(bdoArray[j].innerHTML);
			
        }
       document.getElementById('total_sum').innerHTML = allSumm;
		
    }



а это разметка формы
<form id='me_order_form'>
        <table class="variants">
        	<tr>
            	<th class="col1"><input type="checkbox"></th>
                <th class="col2">Размеры и комплекты</th>
                <th class="col3">Количество</th>
                <th class="col4">Стоимость, руб.</th>
            </tr>
        	<tr>
            	<td class="col1"><input type="checkbox" id="r1" onchange="sums()"></td>
                <td class="col2">товар 1</td>

                <td class="col3"><div class="count"><input type='text' value='0' id='inp_1' onBlur='calculate(this.value, "5000", "bdo_1")'></div></td>
                <td class="col4"><bdo dir='ltr' id='bdo_1'>5000</bdo></td>
            </tr>
        	<tr>
            	<td class="col1"><input type="checkbox"  id="r2" onchange="sums()"></td>
                <td class="col2">товар 2</td>
                <td class="col3"><div class="count"><input type='text' value='0' id='inp_2' onBlur='calculate(this.value, "7000", "bdo_2")'></div></td>
                <td class="col4"><bdo dir='ltr' id='bdo_2'>7000</bdo></td>
            </tr>
        	<tr>
            	<td class="col1"><input type="checkbox" id="r3" onchange="sums()"></td>
                <td class="col2">товар 3</td>
                <td class="col3"><div class="count"><input type='text' value='0' id='inp_3' onBlur='calculate(this.value, "300", "bdo_3")'></div></td>
                <td class="col4"><bdo dir='ltr' id='bdo_3'>300</bdo></td>
            </tr>
            <tr class="bottom">
            	<td colspan="2" class="total">Общая сумма заказа: <span class="price" id='total_sum'>0</span> <span class="price">Р</span></td>
                <td colspan="2" class="order"><a href="#"></a></td>
            </tr>                                    
        </table>
      </form>

вопрос: как правильно написать, чтобы пересчет был только для строк, у которых активен чекбокс? Я писал в цикле , где сумма подсчитывается
for (j = 0; j < bdoArray.length; j++) {

          var elem=document.getElementById("r"+i);
	  if(elem.checked)

            allSumm = allSumm + parseFloat(bdoArray[j].innerHTML);
			
        }

но так не считает общую сумму. Помогите, пожалуйста!

ksa 26.06.2012 11:05

georg, типа набросок...

<!DOCTYPE html>
<html>
<head>
<!--
<script src="http://code.jquery.com/jquery-latest.js"></script>
<link rel="stylesheet" type="text/css" href="tmp.css" />
-->
<style type="text/css">
</style>
<script type="text/javascript">
function calculate(Obj, price){
	var o=Obj.parentNode.parentNode.parentNode;
	var anum = /(^\d+$)|(^\d+\.\d+$)/;
	var quantity=Obj.value;
	if (!anum.test(quantity)) {
		alert('Введенное значение не является числом!');
		return;
	}
	// сумма = количество * цену
	goodSum = quantity * price;
	o.getElementsByTagName('bdo')[0].innerHTML = goodSum;
	sums();
};
function sums(Obj) {
	var meForm   = document.getElementById('me_order_form');
	if (!Obj.checked) {
		meForm.getElementsByTagName('input')[0].checked=false;
	}
	var bdoArray  = meForm.getElementsByTagName('bdo');
	// устанавливаем начальное нулевое значение ОБЩЕЙ суммы
	var allSumm = 0;
	// и в цикле прибавляем к ней сумму каждого товара
	for (j = 0; j < bdoArray.length; j++) {
		var o=bdoArray[j].parentNode.parentNode;
		if (o.getElementsByTagName('input')[0].checked) {
			allSumm = allSumm + parseFloat(bdoArray[j].innerHTML);
		}
	}
	document.getElementById('total_sum').innerHTML = allSumm;
};
function allSumm(Obj) {
	var meForm   = document.getElementById('me_order_form');
	var o  = meForm.getElementsByTagName('input');
	var i;
	for (i = 0; i < o.length; i++) {
		if (o[i].type=='checkbox') {
			o[i].checked=Obj.checked;
		}
	}
	sums(Obj);
}
</script>
</head>
<body>
<form id='me_order_form'>
	<table class="variants">
		<tr>
			<th class="col1"><input type="checkbox" onclick='allSumm(this)'></th>
			<th class="col2">Размеры и комплекты</th>
			<th class="col3">Количество</th>
			<th class="col4">Стоимость, руб.</th>
		</tr>
		<tr>
			<td class="col1"><input type="checkbox" class='item' id="r1" onclick="sums(this)"></td>
			<td class="col2">товар 1</td>

			<td class="col3">
				<div class="count">
					<input type='text' value='0' id='inp_1' onBlur='calculate(this, 5000)'>
				</div>
			</td>
			<td class="col4">
				<bdo dir='ltr' id='bdo_1'></bdo>
			</td>
		</tr>
		<tr>
			<td class="col1"><input type="checkbox" class='item'  id="r2" onclick="sums(this)"></td>
			<td class="col2">товар 2</td>
			<td class="col3"><div class="count"><input type='text' value='0' id='inp_2' onBlur='calculate(this, 7000)'></div></td>
			<td class="col4"><bdo dir='ltr' id='bdo_2'></bdo></td>
		</tr>
		<tr>
			<td class="col1"><input type="checkbox" class='item' id="r3" onclick="sums(this)"></td>
			<td class="col2">товар 3</td>
			<td class="col3"><div class="count"><input type='text' value='0' id='inp_3' onBlur='calculate(this, 300)'></div></td>
			<td class="col4"><bdo dir='ltr' id='bdo_3'></bdo></td>
		</tr>
		<tr class="bottom">
			<td colspan="2" class="total">Общая сумма заказа: <span class="price" id='total_sum'>0</span> <span class="price">Р</span></td>
			<td colspan="2" class="order"><a href="#"></a></td>
		</tr>                                    
	</table>
</form>
</body>
</html>

bes 26.06.2012 11:19

<table id="myTable">
<tr>
  <th><input type="checkbox">
  <th><input>
</tr>
<tr>
  <th><input type="checkbox">
  <th><input>
</tr>
</table>
<button id="myButton">sum = 0</button>

<script>
window.onload = function () {
  var myTable = document.getElementById('myTable');
  var myButton = document.getElementById('myButton');
  var rows = myTable.rows;
  var len = rows.length;
  var checkbox;
  var inp;
  var sum;


  myButton.onclick = function () {
    sum = 0;
    for (var i = 0; i < len; i++) {
      checkbox = rows[i].children[0].children[0];
      inp = rows[i].children[1].children[0]; 
      if (checkbox.checked == true && isNaN(parseFloat(inp.value)) != true) {
        sum += parseFloat(inp.value); 
      }       
    }
    myButton.innerHTML = 'sum = ' + sum;
  }

}
</script>

georg 26.06.2012 12:13

ребята, огромное спасибо, все получилось)

ksa, если я оберну поле для ввода значения еще в один div (хочу справа и слева поставить ссылки "вперед"-"назад"), вот так:
<tr>
	            <td class="col1"><input type="checkbox" class='item' id="r3" onclick="sums(this)"></td>
	            <td class="col2">товар 3</td>
	            <td class="col3">
                       <div>
                          <a class="left" href="#"></a>
                          <div class="count"><input type='text' value='0' id='inp_3' onBlur='calculate(this, 300)'></div>
                           <a class="right" href="#"></a>
                     </div>
                 </td>
	          <td class="col4"><bdo dir='ltr' id='bdo_3'></bdo></td>
	        </tr>


то тогда не считает. требуется прописать дополнительный ParentNode для input? я попробовал, не сработало

ksa 26.06.2012 13:34

Цитата:

Сообщение от georg
ParentNode

Это не верный идентификатор свойства... Правильно как у меня.
Цитата:

Сообщение от ksa
parentNode

Цитата:

Сообщение от georg
требуется прописать дополнительный

Чем глубже суешь - тем выше нужно подниматься... :yes:

georg 26.06.2012 14:05

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

ExXxTaSy 25.07.2012 17:38

ой классная штука. только я убрал эти чекбоксы. мне нужно просто 1 ячейка в которую вводишь кол и она пересчитывает цену.

подскажите следующее. как сделать.
у меня есть $price1 $price2 $price3

к каждой цене привязано свое количество. типо если покупать товар до к примеру 10 шт это цена 1.(розница)
если от 10 то цена 2(мелкий опт)
и если к примеру от 50 то покупаешь по цене 3(крупный опт)

вот как сделать что бы при пересчете оно это учитывало. ?) помогите плз. в явяскрипте не шарю абсолютно)

lord2kim 25.07.2012 17:58

ExXxTaSy,
<html>
<head>
<title></title>
<script>
var price1 = 10, price2 = 20, price3 = 30;
function conversion(val) {
	var div = document.getElementById("div"), price = document.getElementById("price");
	if (isNaN(val)) { div.innerHTML = ""; price.innerHTML = ""; }
	else {
		switch (true) {
			case (val <= 0): {
				div.innerHTML = "";
				price.innerHTML = ""; break;
			}
			case (val < 10): {
				div.innerHTML = val*price1;
				price.innerHTML = price1; break;
			}
			case (val >= 10 && val < 50): {
				div.innerHTML = val*price2;
				price.innerHTML = price2; break;
			}
			case (val > 50): {
				div.innerHTML = val*price3;
				price.innerHTML = price3; break;
			}
		}
	}
}
</script>
</head>
<body>
<input type="text" onBlur="conversion(this.value)" onChange="conversion(this.value)" onkeypress="conversion(this.value)" onkeyup="conversion(this.value)" value="1" id="txt">
<div id="div"></div><div id="price"></div>
<script>window.onload = conversion(document.getElementById("txt").value);</script>
</body>
</html>

ExXxTaSy 25.07.2012 18:27

Цитата:

Сообщение от lord2kim (Сообщение 191631)
ExXxTaSy,
<html>
<head>
<title></title>
<script>
var price1 = 10, price2 = 20, price3 = 30;
function conversion(val) {
	if (isNaN(val)) { }
	else {
		document.getElementById("div").innerHTML = val < 10 ? val*price1 : ((val > 10 && val < 50) ? val*price2 : (val > 50 ? val*price3 : ""));
	}
}
</script>
</head>
<body>
<input type="text" onBlur="conversion(this.value)" onChange="conversion(this.value)" onkeypress="conversion(this.value)">
<div id="div"></div>
</body>
</html>

спасибо) а можно еще так что бы оно выводило цену по которой происходит расчет)

lord2kim 25.07.2012 18:51

ExXxTaSy, поправил предыдущий пост

ExXxTaSy 26.07.2012 15:35

Цитата:

Сообщение от lord2kim (Сообщение 191646)
ExXxTaSy, поправил предыдущий пост

а можно еще что бы сразу кол было 1?) оно заодно и будет цену и сумму выводить сразу. ат о получаются пустые поля(,


громадное спасибо))))

ExXxTaSy 26.07.2012 15:39

ага. количество ввел сам. теперь светится. но цены не светятся)
по сути нужно что бы прайс1 стояла.

lord2kim 26.07.2012 15:50

ExXxTaSy, поправил пред предыдущий пост

ExXxTaSy 26.07.2012 17:51

спасибо!!!

rick_77 29.11.2018 14:33

Добрый день!
Если возможно подскажите как можно адаптировать код от KSA 26.06.2012, 12:05? что бы была возможность НЕ чекбоксом выбирать пункты для расчёта сумм, а через меню:
<div style="position: absolute; width: 160px; height: 47px; z-index: 2; left: 10px; top: 232px" id="layer17">
<td>Темп. воздуха</td>
<td>
<select id="temperatura" onchange="document.location=OnChange="Rasch_Gor(\' temperatura\',this.options[this.selectedIndex].value" title="Температура среды"/>
<option>Выберите температуру</option>
<option value="1">Температура выше 0</option>
if($_SESSION['temperatura']==1);
<option value="2">от 0 до -5 градусов</option>
if($_SESSION['temperatura']==2);
<option value="3">от -5 до -10 градусов</option>
if($_SESSION['temperatura']==3);
<option value="4">от -10 до -15 градусов</option>
if($_SESSION['temperatura']==4);
<option value="5">от -15 до -20 градусов</option>
if($_SESSION['temperatura']==5);
<option value="6">от -20 до -25 градусов</option>
if($_SESSION['temperatura']==6);
<option value="7">от -25 и ниже</option>
if($_SESSION['temperatura']==7);
</select>
</td>
</div>
Или направить где я могу научиться это делать самостоятельно. Благо дарю!

laimas 29.11.2018 14:49

Это не меню, а список, только незадача в том, что по условию в данном списке может быть только две опции. О каком выборе и расчете идет речь?

rick_77 29.11.2018 14:58

Спасибо за ответ!
Есть некая переменная gor_vydat, далее меню (раннее описанное) при выборе пунктов которого переменная gor_vydat должна умножаться на процент, который привязан к пункту меню. Наверное сложно описал.

rick_77 29.11.2018 15:02

Цитата:

Сообщение от laimas (Сообщение 499516)
Это не меню, а список, только незадача в том, что по условию в данном списке может быть только две опции. О каком выборе и расчете идет речь?

Возможно необходимо изменить как бы создание меню под задачу?

laimas 29.11.2018 15:04

Цитата:

Сообщение от rick_77
Есть некая переменная gor_vydat, далее меню ...

Показанное, это список, значение которого по выбору в нем можно получить проще - this.value. Дальше что? Ну задавая вопрос описывайте переменные, с какими процентами и как они связаны и т.д. У вас в показанном собственно выбор не богат - некое значение по умолчанию плюс одно для выбора. Можете проценты поместить в опции как data атрибуты, получайте, рассчитывайте .... Или опишите вопрос как следует.

rick_77 29.11.2018 15:06

Понял. Сейчас опишу...

rick_77 29.11.2018 15:12

Задача такая. Необходимо руководствуясь температурой окружающей среды выдать для заправки автомобиля количество горючего в соответствии с нормой, а именно:
- если температура воздуха от 0 до -5 то к наливаемому горючему добавляется ещё 2 %;
- если температура воздуха от -5 до -10 то к наливаемому горючему
добавляется ещё 4 %;
- если температура воздуха от -10 до -15 то к наливаемому горючему добавляется ещё 6 %...
и так далее.
Я пытаюсь реализовать так, что бы при выборе пункта меню на выходе я получил количество горючего, которое хранится в переменной gor_vydat ПЛЮС сверху добавляется количество по норме.

rick_77 29.11.2018 15:15

Поскольку я начинающий, то я параллельно ищу ответ на вопрос и реализовываю его сразу. На практике лучше изучается.

laimas 29.11.2018 15:28

Неизвестно Откуда на сервере берутся данные (по уму это должна быть база), но если по минимуму то достаточно массива и гораздо простого вывода списка:

<?php
$arr = [2=>['title'=>'от 0 до -5 градусов', 'percent'=> 2], ...];
?>
<select id="temperatura" onchange="document.location=OnChange="Rasch_Gor(\' temperatura\',this.options[this.selectedIndex].value" title="Температура среды"/>
<option>Выберите температуру</option>
<option value="1" data-percent="0">Температура выше 0</option>
<option value="<?=$_SESSION['temperatura']?>" data-percent="<?=$arr[$_SESSION['temperatura']]['percent']?>"><?=$arr[$_SESSION['temperatura']]['title']?></option>
</select>


Получить и рассчитать несложно. Но вот это onchange="document.location=OnChange="Rasch_Gor .... нечто неописуемое, и к тому же, пусть рабочее, тогда о каком расчете на клиенте идет речь?

PS. Еще раз - вы понимаете, что ваш список будет содержать не все опции для выбора или нет? Случаем не значение ли ранее выбранного, хранящегося в сессии, нужно отметить в списке?

rick_77 29.11.2018 15:46

Такой вот тип меню я взял с нета, немного адаптировал под свои требования, по сути я ещё не знаю что значит эта строка. Применил, она заработала и далее ищу ответы на вопросы. Поэтому и спрашиваю, может сменить тип выпадающего меню, что бы можно было выполнить поставленную задачу?

rick_77 29.11.2018 15:47

данные вводятся вручную, но записываются в базу

rick_77 29.11.2018 15:49

Вот таким образом и вводится
<div style="position: absolute; width: 159px; height: 47px; z-index: 2; left: 10px; top: 185px" id="layer19">
<tr>
<td>Выдать горючего, л.:</td>
<td><input type="text" name="vydat" size = 15 title = "Выдано горючего"></td>
</tr>

laimas 29.11.2018 15:51

Вы не отвечаете на вопросы:

1) где нужно производить на расчет - на сервере или на клиенте?
2) если на клиенте, то почему по событию выбора в списке прописан переход?
3) что вы хотите "смудрить" со списком на сервере используя переменную в сессии?

rick_77 29.11.2018 15:57

Установлен Денвер, dbForge и SublimeText. Сервер локальный.

laimas 29.11.2018 16:02

Цитата:

Сообщение от rick_77
Установлен Денвер, dbForge и SublimeText. Сервер локальный.

А это каким образом относится к вопросам? :D

Неужто вопросы непонятны? Попробуем так:

а) при выборе в списке (то есть при каждом изменении в нем) выбор пользователя отправляется на сервер и там производится расчет?

б) при выборе в списке рассчитывается на клиенте, а на сервер отправляется отправлением формы (submit)?

Какой из вариантов требуется?

rick_77 29.11.2018 16:29

Подскажите, здесь возможно присоединить скриншот? Я бы показал наглядно.

rick_77 29.11.2018 16:29

Всё увидел...

rick_77 29.11.2018 16:42

https://photos.google.com/search/_tr...aWbeZtHE?hl=ru
Необходимо ввести в область 1 количество горючего, при выборе в меню определённого пункта (область 2), а в области 3 отображается ТО количество горючего , которое необходимо выдать с учётом норм.

laimas 29.11.2018 17:31

Можно, но зачем, словами что не проще ответить? Спрашивается то простое.

Пишу все, далее думайте. Нельзя в DIV помещать TD.

Пусть есть форма со списком, в котором по выбору рассчитывается нечто и отображается на клиенте как результат выбора. Данный расчет на клиенте чисто для клиента и серверу на него наплевать, ему нужен выбор клиента. То есть клиент выбрал, увидел, удовлетворился и отправил форму. Сервер по полученному значению произвел расчет и ... далее не знаю для чего.

Вывод списка, что у вас, это какая-то профанация - переменная $_SESSION['temperatura'] не являясь набором может иметь только одно значение, а значит ваш список может иметь только 3 опции, так как опции выводятся по условию (и заметьте, что это у вас попытка вывода, ибо это не вывод, а сплошные ошибки), что, судя по задаче, совсем не то что нужно.

Судя по "хотению" переменная $_SESSION['temperatura'] хранит ранее выбранное пользователем значение и если был выбор, то делает соответствующую опцию в списке выбранной. Но выводить список как каждую опцию отдельно, определяя выбор в списке, это не гут, вывод производится в цикле, а параметры опций определяются значениями из описанного набора. Коли у вас "руками" значит такой набор нужно описать в массиве. При этом опция <option>Выберите температуру</option> лишняя, так как опция <option value="1">Температура выше 0</option> фактически есть опция по умолчанию, то есть изначально это и есть выбор.

//данные для выбора
$data = [
    1 => ['title'=> 'Температура выше 0', 'percent'=>0],
    ['title'=> 'от 0 до -5 градусов', 'percent'=>.2],
    ['title'=> 'от -5 до -10 градусов', 'percent'=>.4],
    ['title'=> 'от -10 до -15 градусов', 'percent'=>.6],
    ['title'=> 'от -15 до -20 градусов', 'percent'=>.8],
    ['title'=> 'от -20 до -25 градусов', 'percent'=>.10],
    ['title'=> 'от -25 и ниже', 'percent'=>.12]
];

//вывод списка в форме (я не привожу код формы и как список располагается в ней)
echo '<select name="percent" id="T">';
//если $_SESSION['temperatura'] определена (был уже выбор) и равна ключу массива данных, то опция списка будет выбрана
foreach($data as $k=>$v) echo '<option data-percent="'.$v['percent'].'" value="'.$k.'" '.($_SESSION['temperatura']==$k ? 'selected' : null).'>'.$v['title'].'</option>';

echo '</select>';


Далее расчет на клиенте (код должен быть расположен ниже кода формы и элемента span в котором будет вывод расчета или ... ладно, пока опустим)

<!-- в этом элементе будет отображается и сумма при расчете -->
<span id="total">250</span>

<script>
var gor_vydat = 250; //откуда это берется вопрос, ну пусть где-то, как-то, в общем значение передано на клиента
//рассчитываем по выбору
document.getElementById('T').onchange = function() {
    document.getElementById('total').innerHTML = gor_vydat + gor_vydat * this.options[this.value-1].getAttribute('data-percent');
}
</script>


Пощелкал пользователь, выбрал, подходит ему, отправляет форму. Сервер принимая ее проверяет истинность данных и если ОК, производит расчет, выводит результат и опять форму, иначе какая надобность в $_SESSION['temperatura']? То есть прием формы должен быть кодом расположенным до вывода формы.

if($d = (int)$_GET['percent'] AND key_exists($d, $data)) {
    //данные с клиента не левые, расчет
    $total = 250 + 250 * $data[$d]['percent'];
    //запомнить выбор в сессии
    $_SESSION['temperatura'] = $d;
}


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

У меня не так много времени, чтобы вытягивать из вас по капельке, поэтому читайте, думайте и всегда отвечайте на вопросы полно.

rick_77 29.11.2018 17:35

Ого! Большущая благодарность за проделанную работу! Приступаю к чтению и опробации! Ещё раз благодарю!

rick_77 29.11.2018 17:38

Понял на счёт вопросов. Буду стараться описывать ситуацию по полной! Удачи и Вам!


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