Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Динамический подсчет цены


Автор: RomanK 21.10.2006, 19:25
Здравствуйте!

Есть задача: существует форма, в которой есть несколько radio кнопок, и рядом с каждой еще есть флажок!

Типа вот этого:
Код

<form action='script.php' method='POST'>
    <ol>
        <li><input type='radio' name='type' value='1' price='10'> Exclusive List + HOT <input type='checkbox' name='type_1' price='30'></li>
        <li><input type='radio' name='type' value='2' price='20'> Exclusive List + HOT <input type='checkbox' name='type_2' price='40'></li>
    </ol><br>
    <span>TOTAL: $</span> <input type='text' name='total' value='0'> <input type='submit' name='submit' value='PAY NOW'></div><br>
</form>


Необходимо сделать так, чтобы при нажатии на какую-либо radio кнопку в поле total сразу же появилась цена, соответствующая полю price данной radio кнопки! + Если нажать !!!соответствующий флажок!!!, то есть тот... который рядом с radio кнопкой, то к текущему значению поля total прибавляется еще поле price данного флажка!!! То есть радио кнопке type со значением 1 будет соответствовать флажок с именем type_1. И если нажать не тот флажок... не соответствующий нажатой radio кнопке, то ничего не должно происходить!

Возможно ли такое сделать??? Я думаю что возможно.
У меня получилось сделать так... чтобы price радио кнопки отображался в total, но вот чтобы еще флажки прибавлялись... неполучается! smile

Огромное спасибо! smile

Автор: SelenIT 21.10.2006, 20:25
Как вариант: 
Код

<form action="script.php" method="POST" onclick="checkstate(event,this)">
    <ol>
        <li><input type="RADIO" name="type" id="type1" price="10" value="1"> Exclusive List + HOT <input type="checkbox" name="type_1" value="30"></li>
        <li><input type="radio" name="type" id="type2" price="20" value="2"> Exclusive List + HOT <input type="checkbox" name="type_2" value="40"></li>
    </ol><br>
    <span>TOTAL: $</span> <input type="text" name="total" value="0" disabled> <input type="submit" name="submit" value="PAY NOW"></div><br>
</form>
<script>
function checkstate(event,form) {
   // определим кликнутый элемент
   var elem = event.target || event.srcElement;
   // если кликнули по радиокнопке или чекбоксу:
   if (elem.tagName.toLowerCase() == "input" && elem.type) {
      if (elem.type.toLowerCase() == "radio") {
        // для радио: пишем в total ее price
        form.total.value = elem.attributes["price"].value;
        // затем определяем соотв. чекбокс, и если он чекнут - прибавляем добавку
        var check = form[elem.id.replace("type","type_")];
        if (check.checked) form.total.value = form.total.value*1 + check.value*1;
      }
      if (elem.type.toLowerCase() == "checkbox" && document.getElementById(elem.name.replace("_","")).checked) {
        // для чекбокса, при условии что чекнута соотв. radio:
        // если чекбокс чекнут - прибавляем добавку к total, если нет - вычитаем
        form.total.value = form.total.value*1 + elem.value*(elem.checked ? 1 : -1);
      }
   }
}
</script>

Автор: RomanK 21.10.2006, 20:32
SelenIT, огромнейшее спасибо!!! Мне это и надо было!!! smile)))

Добавлено @ 20:44 
Надеюсь я не совсем наглею?... но есть еще вопросик...
Как в это добавить еще вот такую возможность:
Таже самая форма... но есть еще одна строка в форме:
Код

<li><input type="radio" name="type" id="type3" price="50" value="3"> Normal List + <input type="text" name="type_3" value="60"> days</li>

Теже самые условия... только если вводят в поле type_3 количество дней... ну там 5, 6, и т.п., то к цене в total прибавляется не 60, а 60 * количество дней (введенное).

Спасибо еще раз!!! smile

Автор: SelenIT 21.10.2006, 22:09
Хм... тогда немного сложнее - глобальным перехватом клика уже не отделаться.

Чтобы как-то сохранить единообразие, придется, видимо, изменить разметку - значение цены у элементов type_n снова перенести, все-таки, в кастомный атрибут price, а value выставить в 1 для чекбоксов и 0 (по умолчанию) для текстового поля. Тогда в ф-ции строка 20 заменится на
Код
        if (check.checked || check.type.toLowerCase() == "text") {
           form.total.value = form.total.value*1 + check.value*check.attributes["price"].value;
        }
а в бывшей строке 25 elem.value заменится на elem.attributes["price"].value.

А на onkeyup и onchange надо будет навесить ф-цию checktext(event):
Код

function checktext(event) {
    var elem = event.target || event.srcElement;
    var radio = document.getElementById(elem.name.replace("_",""));
    if (radio.checked) {
        elem.form.total.value = radio.attributes["price"].value*1 + elem.attributes["price"].value*elem.value;
    }
}

Автор: RomanK 21.10.2006, 22:34
ОГРОМНОЕ ТЕБЕ СПАСИБО!!! smile))
Вот окончательный вариант:
Код

<form action="script.php" method="POST" onclick="checkstate(event,this)">
    <ol>
        <li><input type="radio" name="type" id="type1" price="10" value="1"> Exclusive List + HOT <input type="checkbox" name="type_1" value="1" price='40'></li>
        <li><input type="radio" name="type" id="type2" price="20" value="2"> Exclusive List + HOT <input type="checkbox" name="type_2" value="1" price='50'></li>
        <li><input type="radio" name="type" id="type3" price="30" value="3"> Exclusive List + <input type="text" name="type_3" value="0" price='1' OnKeyUp='checktext(event);'> days</li>
    </ol><br>
    <span>TOTAL: $</span> <input type="text" name="total" value="0" disabled> <input type="submit" name="submit" value="PAY NOW"></div><br>
</form>

<script language='JavaScript'>
    function checktext(event) {
        var elem = event.target || event.srcElement;
        var radio = document.getElementById(elem.name.replace("_",""));
        if (radio.checked) {
            elem.form.total.value = radio.attributes["price"].value*1 + elem.attributes["price"].value*elem.value;
        }
    }
    function checkstate(event,form) {
       // определим кликнутый элемент
       var elem = event.target || event.srcElement;
       // если кликнули по радиокнопке или чекбоксу:
       if (elem.tagName.toLowerCase() == "input" && elem.type) {
          if (elem.type.toLowerCase() == "radio") {
            // для радио: пишем в total ее price
            form.total.value = elem.attributes["price"].value;
            // затем определяем соотв. чекбокс, и если он чекнут - прибавляем добавку
            var check = form[elem.id.replace("type","type_")];
    //        if (check.checked) form.total.value = form.total.value*1 + check.value*1;
            if (check.checked || check.type.toLowerCase() == "text") {
               form.total.value = form.total.value*1 + check.value*check.attributes["price"].value;
            }
          }
          if (elem.type.toLowerCase() == "checkbox" && document.getElementById(elem.name.replace("_","")).checked) {
            // для чекбокса, при условии что чекнута соотв. radio:
            // если чекбокс чекнут - прибавляем добавку к total, если нет - вычитаем
            form.total.value = form.total.value*1 + elem.attributes["price"].value*(elem.checked ? 1 : -1);
          }
       }
    }
</script>

Автор: SelenIT 21.10.2006, 22:56
RomanK, все-таки onchange тоже надо бы отслеживать - вдруг юзер вставит значение в поле мышкой из буфера? Вообще лучше всегда писать обработчики событий в нижнем регистре, иначе к ним не получится обратиться в самом скрипте. Кроме того, для универсальности можно поставить эти обработчики на <form>, а не на <input> - тогда, если в форме появится еще одна строка такой структуры, это автоматом будет работать и для нее.

Автор: RomanK 21.10.2006, 23:05
То есть что ты предалагаешь?
На onchange тоже поставить checktext(event);? Так? А если ведь я на onchange поставлю, то тогда наверно onkeyup можно убрать, да?

Автор: SelenIT 21.10.2006, 23:24
RomanK, я бы оставил оба. onkeyup отcледит ввод с клавиатуры в реальном времени, а onchange дополнительно подстрахует при других способах ввода.

Автор: RomanK 21.10.2006, 23:42
SelenIT, ок... так и сделаю. Огромное спасибо! smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)