Вход

Просмотр полной версии : Запуск одной функции при нескольких .change


the_little
31.10.2017, 10:14
Всем привет.
Столкнулся с такой проблемой.

Есть поле (количество).
Значение этого поля меняется 2-мя способами.

1 Вариант.
Есть функция (запуск при изменении другого поля), которая передает в это поле некоторое значение.
Далее производятся вычисления.

2 Вариант.
Это поле напрямую изменяется пользователем. И далее те же расчеты.

При этом получилось 2 функции, которые выполняют одну и туже работу, но запускаются при изменении 2-х разных полей.

Есть ли вариант как-то написать условие, что запуск функции происходит при изменении любого из перечисленных полей?


<div id="calc">
<div class="description">
<h4>Описание товара</h4>
...<br>
Кол-во м2 в уп.: <span id="count">1.9218</span> м2
</div>
<div class="price">
<span>Цена:</span>
<span class="old-price">1590</span>
<span>руб.</span>
<span class="new-price">1462</span>
<span>руб.</span>
</div>
<div>
<label for="u-m">Введите требуюмую площадь: </label>
<input type="number" step="any" name="user_amount" id="u-m">
<span>( <span class="calc-amount">?</span> м) = <span class="calc-price">?</span> руб.</span>
<br><br>
<label for="b-m">Количество упаковок: </label>
<input type="number" step="1" name="bag_amount" id="b-m">
</div>
</div>



$(document).ready(function() {
$("#u-m").change(function() {
var um = $("#u-m").val(); // Вводимая пользователем площадь
var count = $("#count").html(); // Сколько м.кв. в 1 упаковке
var amount = Math.ceil(um / count); // Высчитываем сколько нужно упаковок, чтобы покрыть площадь
$("#b-m").val(amount); // Передаем полученное количество в поле, дальше все расчеты ведем от этого поля
$(".calc-amount").text(amount * count); // Передаем в .calc-amount реальную площадь этого количества упаковок
var price = $(".new-price").html(); // Получаем цену за м.кв.
$(".calc-price").text((amount * count * price).toFixed(2)); // Считаем и передаем стоимость полученных м.кв. в поле
});
$("#b-m").change(function() {
var amount = $("#b-m").val(); // Берем значения из поля (это делается на случай, если пользователь сам туда вписал число)
var count = $("#count").html(); // Сколько м.кв. в 1 упаковке
$(".calc-amount").text(count * amount); // Передаем в .calc-amount покрытие заданным количеством упаковок
var price = $(".new-price").html(); // Получаем цену за м.кв.
$(".calc-price").text((amount * count * price).toFixed(2)); // Считаем и передаем стоимость полученных м.кв. в поле
});
});

ksa
31.10.2017, 10:34
Есть ли вариант как-то написать условие, что запуск функции происходит при изменении любого из перечисленных полей?
Как вариант, использовать единую функцию на все события. Т.к. внутри нее можно узнать на каком элементе это произошло и какое событие собственно случилось.
Имея такую информацию можно сделать любые выводы и действия.

А можно просто написать третью функцию и в нее поместить общую часть из первых двух... ;)

Выбор за тобой.

Nexus
31.10.2017, 10:34
the_little, в первом варианте обратитесь к полю, которое пользователь может сам изменить и вызовите на нем событие "change".
http://api.jquery.com/trigger/
Не катит, обработчики разные.

the_little
31.10.2017, 11:16
Как вариант, использовать единую функцию на все события.

А как это сделать?

Код то у меня работает нормально. Напрягает что по сути 2 функции одинаковые, просто вызываются разными действиями...

Nexus
31.10.2017, 11:27
the_little, попробуйте так:
$(document).ready(function() {
$("#b-m,#u-m").change(function(){
var $t=$(this),
bool=$t.attr('id')=='u-m',
um=$("#u-m").val(),
count=$("#count").html(),
amount=bool?
Math.ceil(um / count):
$("#b-m").val(),
price=$(".new-price").html();

if(bool)
$("#b-m").val(amount);

$(".calc-amount").text(amount * count);
$(".calc-price").text((amount * count * price).toFixed(2));
});
});

ksa
31.10.2017, 11:35
А как это сделать?
Можно как у Nexus...

А можно так

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='https://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(){
var test=function(e){
alert(e.target.id);
};
$('#t0, #t1').change(test);
});
</script>
</head>
<body>
<input type='text' id='t0' />
<input type='text' id='t1' />
</body>
</html>

Nexus
31.10.2017, 11:39
ksa, а чем Ваш метод от моего отличается? :)
Не догоню.

ksa
31.10.2017, 11:41
а чем Ваш метод от моего отличается?
У меня именная функция, у тебя безымянная...

the_little
31.10.2017, 11:49
Спасибо!!! Работает как надо. Только хотелось бы еще в коде разобраться...

$(document).ready(function() {
$("#b-m,#u-m").change(function(){
var $t=$(this), // Переменная t, которая определяет в каком поле происходит действие???
bool=$t.attr('id')=='u-m', // Вот это не пойму. attr('id') возвращает первый id, который ему попадется???
um=$("#u-m").val(),
count=$("#count").html(),
amount=bool? // Что это делает?
Math.ceil(um / count): // не понимаю что дальше написано... Передаем Math.ceil(um / count) в #b-m.
$("#b-m").val(),
price=$(".new-price").html();

if(bool) // Что это делает?
$("#b-m").val(amount);

$(".calc-amount").text(amount * count);
$(".calc-price").text((amount * count * price).toFixed(2));
});
});

the_little
31.10.2017, 11:51
блин, надо учить букварь...

Nexus
31.10.2017, 11:57
the_little, от переменной "$t" можно вовсе избавиться, она фактически лишняя.
Если её удалить, то переменная "bool" должна выглядеть так:
bool=this.id=='u-m'
В обработчике события слово "this" - ссылка на элемент, на котором произошло событие.
В переменной "bool" записано действительно ли событие произошло на элементе, который содержит id='u-m'.

Переменная "amount".
При её инициализации воспользовался "тернарным оператором (https://learn.javascript.ru/ifelse#оператор-вопросительный-знак)".
Если значение переменной "bool" - истина, то производятся математические операции, в противном случае в эту переменную записывается значение из элемента с id='b-m'.

the_little
31.10.2017, 12:24
такой вопрос появился.
В поле с id='b-m' по умолчанию не было значения.
Я прописал туда value="1"

Но после очищения поля с id='n-m' - там остается 0, а не 1
И в поля куда выводятся результаты вычислений не возвращается "?", который там изначально стоял.

как это можно как то исправить?

я пробовал задавать через
if(um < 1) {
$("#b-m").val(1);
}

но тогда он не дает ввести свое значение в id='b-m' если первое поле пустое(

Nexus
31.10.2017, 12:34
the_little, без макета сложно сказать.
Если поле с id='n-m' имеет type='number', то попробуйте добавить атрибут "min=0".
Для знака вопроса используйте атрибут "placeholder".

И задавайте идентификаторы и имена полей по-человечески.
Что такое "n-m" и т.п. совершенно непонятно.

the_little
31.10.2017, 12:41
смысл немного другой.
Вот, посмотрите, если не сложно.
http://e-dz.ru/products/001-moskito-dikiy

Там количество упаковок по умолчанию стоит =1
Потом можно менять оба поля, но если верхнее поле
"Введите требуемую площадь:" очистить, то во втором поле "количество упаковок" снова появится 1

Nexus
31.10.2017, 12:49
the_little, вы все поправили?
Но после очищения поля с id='n-m' - там остается 0, а не 1
И в поля куда выводятся результаты вычислений не возвращается "?", который там изначально стоял.
Сейчас все работает как нужно.

the_little
31.10.2017, 12:55
the_little, вы все поправили?

Сейчас все работает как нужно.

это на сайте работает нормально)) а у меня нет...

У меня если я очищаю поле с площадью - в поле количество упаковок остается 0.
А нужно чтобы оставалась 1.


<!DOCTYPE html>
<html lang=ru>

<head>
<meta charset="utf-8">
<title>Калькулятор</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>

<body>
<style type="text/css">
#calc .description { margin-bottom: 30px; }
#calc .old-price { text-decoration: line-through; }
#calc .new-price { color: darkred; }
#calc .price { margin-bottom: 30px; }
#calc label { margin-bottom: 20px; }
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
</style>



<div id="calc">
<div class="description">
<h4>Описание товара</h4>
...<br>
Кол-во м2 в уп.: <span id="count">1.9218</span> м2
</div>
<div class="price">
<span>Цена:</span>
<span class="old-price">1590</span>
<span>руб.</span>
<span class="new-price">1462</span>
<span>руб.</span>
</div>
<div>
<label for="u-m">Введите требуюмую площадь: </label>
<input type="number" step="any" name="user_amount" id="u-m" min="0">
<span>( <span class="calc-amount">?</span> м) = <span class="calc-price">?</span> руб.</span>
<br><br>
<label for="b-m">Количество упаковок: </label>
<input type="number" step="1" name="bag_amount" id="b-m" min="1" value="1">
</div>
</div>

<script type="text/javascript">

$(document).ready(function() {
$("#b-m,#u-m").keyup(function(){
var $t=$(this),
bool=$t.attr('id')=='u-m',
um=$("#u-m").val(),
count=$("#count").html(),
amount=bool?
Math.ceil(um / count):
$("#b-m").val(),
price=$(".new-price").html();

if(bool)
$("#b-m").val(amount);

$(".calc-amount").text(amount * count);
$(".calc-price").text((amount * count * price).toFixed(2));

});
});
</script>
</body>
</html>

the_little
31.10.2017, 13:03
что-то не появляется кнопка запуска кода...
Смысл в том, что при удалении последней цифры из первого поля - запускается функция, и она передает 0 во второе поле.
А этого нужно избежать.

Nexus
31.10.2017, 13:08
the_little, добавьте условие.

the_little
31.10.2017, 13:14
the_little, добавьте условие.

О, сделал код выше запускаемым))

я писал условие, что если um < 1, то передать значение 1 во второе поле.
И все получалось.

Но, при таком раскладе, я не мог менять второе поле, пока в первом пусто!

Если в первом 1 или больше, то пожалуйста.
А если стереть, то он ставит 1 и не дает его менять...

the_little
31.10.2017, 15:38
min="0" тут не помогут, так как они не дают уйти вниз, если управлять стрелками в поле.
Стрелки я отключил.

Через if не получается...

может еще какие-то варианты есть?

Nexus
31.10.2017, 15:40
the_little, покажите ваш js-код, где у вас ничего не получилось.

the_little
31.10.2017, 15:44
точнее 1 то я могу подставить во 2 поле при помощи
if(um < 1) {
$("#b-m").val(1);
}
, но он потом не дает менять его руками... Только через первое поле...
Как-то можно это обойти?

Это условие должно один раз отработать и все. А он его постоянно считывает...

Nexus
31.10.2017, 16:10
the_little,
the_little, покажите ваш js-код, где у вас ничего не получилось.