Привязка input radio к слайдеру jQuery-UI
Есть простой калькулятор для рассчёта прибыли.
Там есть три тарифных плана. START: 100-1000 STANDART: 1001-3000 PREMIUM: 3001-5000 Нужно добиться того, чтобы при вводе в текстовое поле определённого числа в диапазоне от 100 до 5000, один из input radio становился активным автоматически. Т.е. нужно связать радиокнопки, ползунок и числовое поле (ползунок и числовое поле уже взаимосвязаны). Тут ещё сложность в том, что планы перебираются циклом foreach в смарте. Вёрстка калькулятора:
<form method="post" name="calc" onsubmit="recalc(); return false;">
<div>
<ul>
{foreach from=$calc_pselect item=i key=k}
<li><label class="radio"><input type="radio" name="plan" value="{$k}" checked><div>{$i}</div></label>
</li>
{/foreach}
</ul>
</div>
<div>
<input name="sum" id="calc_sum" type="text" class="minCost" value=""/>
<div class="slider"></div>
</div>
<div>
<input name="calc_btn" value="Рассчитать" type="submit">
</div>
{_getFormSecurity form='calc'}
</form>
Скрипт такой:
jQuery(document).ready(function($) {
var input = $('input.minCost');
var slider = $('.slider').slider({
range: 'max',
min: 100,
max: 5000,
value: 100,
step: 10,
animate: 300,
slide: function(event, ui) {
input.val(ui.value);
}
});
input.val(slider.slider('value'));
input.on('change', function() {
slider.slider('value', $(this).val());
});
jQuery("input.minCost").change(function(){
var value1=jQuery(input).val();
if (value1 > 5000) { value1 = 5000; jQuery(input).val(5000)}
if (value1 < 100) { value1 = 100; jQuery(input).val(100)}
jQuery(".slider").slider("values",0,value1);
});
// фильтрация ввода в поля
jQuery('input').keypress(function(event){
var key, keyChar;
if(!event) var event = window.event;
if (event.keyCode) key = event.keyCode;
else if(event.which) key = event.which;
if(key==null || key==0 || key==8 || key==13 || key==9 || key==46 || key==37 || key==39 ) return true;
keyChar=String.fromCharCode(key);
if(!/\d/.test(keyChar)) return false;
});
});
И картинка для удобного восприятия: ipic |
Только уберите checked из строки 5 вашего html
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/south-street/jquery-ui.css">
<style>
ul li {
display: inline-block;
margin-right: 5px;
padding: 3px;
}
</style>
<form method="post" name="calc" onsubmit="recalc(); return false;">
<div>
<ul>
<li><label class="radio"><input type="radio" name="plan" value="1000" checked ><div>START</div></label>
</li>
<li><label class="radio"><input type="radio" name="plan" value="3000" ><div>STANDART</div></label>
</li>
<li><label class="radio"><input type="radio" name="plan" value="5000" ><div>PREMIUM</div></label>
</li>
</ul>
</div>
<div>
<input name="sum" id="calc_sum" type="text" class="minCost" value=""/>
<div class="slider"></div>
</div>
<div>
<input name="calc_btn" value="Рассчитать" type="submit">
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
jQuery(document).ready(function($) {
var plan = $('input[name=plan');
var input = $('input.minCost');
var slider = $('.slider').slider({
range: 'max',
min: 100,
max: 5000,
value: 100,
step: 10,
animate: 300,
slide: function(event, ui) {
input.val(ui.value);
checkPlan();
}
});
input.val(slider.slider('value'));
checkPlan();
// input.on('change', function() {
// slider.slider('value', $(this).val());
// });
plan.on('change', function() {
slider.slider('value', $(this).val());
input.val($(this).val());
});
input.on('change', function() {
var value1=input.val();
if (value1 > 5000) { value1 = 5000; input.val(5000)}
if (value1 < 100) { value1 = 100; input.val(100)}
slider.slider('value',value1);
checkPlan();
});
// фильтрация ввода в поля
jQuery('input').keypress(function(event){
var key, keyChar;
if(!event) var event = window.event;
if (event.keyCode) key = event.keyCode;
else if(event.which) key = event.which;
if(key==null || key==0 || key==8 || key==13 || key==9 || key==46 || key==37 || key==39 ) return true;
keyChar=String.fromCharCode(key);
if(!/\d/.test(keyChar)) return false;
});
function checkPlan() {
plan.each(function(i, elem) {
if(+input.val() <= +elem.value) {
$(elem).prop('checked', true);
return false;
}
});
}
});
</script>
|
Цитата:
Есть ошибка: при нажатии на кнопку submit "Рассчитать" скрипт ругается - TypeError: plans[p] is undefined, после чего страница перезагружается. Удаление из кода plans[p] ни к чему не привело. Думаю, что эти планы plans[p] вообще нужно убрать, т.к. они прописаны вручную. Верно? )) Прошу помощи разобраться! |
tp-20,
На Рассчитать мой пример работать не может, т.к. он создан по вашим неполным данным - в частности, отсутствует функция recalc. Что она делает - я не знаю. И пример html я написал вручную, вместо вашего smarty |
есть отдельный скрипт непосредственно для рассчёта калькулятора.
я сначала подумал, что можно обойтись без него, но тут привязана часть функционала. оттуда и лезет ошибка с планами plans[p] is undefined
function round2(z)
{
z = (1*z).toFixed(2);
return 1*z;
}
function recalc()
{
var sum=round2(document.forms['calc']['sum'].value);
if (sum<=0) sum=0;
var prib=0;
{*
var cmpd=0;
var radios=document.getElementsByName('cmpd');
for (i=0; i<radios.length; i++)
if (radios[i].checked)
{
cmpd=radios[i].value;
break;
}
*}
var cmpd=document.forms['calc']['cmpd'];
if (cmpd==undefined)
{
cmpd=0;
}
else
{
cmpd=cmpd.value;
}
document.getElementById('cmpd').innerHTML=cmpd;
var days=document.forms['calc']['days'];
if (days==undefined)
{
days=0;
}
else
{
days=days.value;
}
var plans=[{$calc_plans}];
var pn='?';
var pd='?';
var ip='?';
var db='?';
var dr='?';
var dd='?';
var p=document.forms['calc']['plan'];
if (p==undefined)
{
for (var p in plans)
if ((sum>=plans[p][1]) & (sum<plans[p][2]))
{
pn=plans[p][0];
pd=plans[p][3];
ip=plans[p][4];
db=plans[p][5];
dr=plans[p][6];
dd=plans[p][7];
break;
}
}
else
{
p=p.value;
pn=plans[p][0];
pd=plans[p][3];
ip=plans[p][4];
db=plans[p][5];
dr=plans[p][6];
dd=plans[p][7];
}
if (pn!='?')
{
if (ip == 0)
{
ip = days;
dd = days;
}
sum=round2(sum+db*sum/100);
zcomp=0;
for (i=0; i<ip; i++)
{
profit=round2(pd*sum/100);
csum=round2(cmpd*profit/100);
zcomp=zcomp+csum;
prib=prib+profit-csum;
sum=sum+csum;
}
sum=round2(dr*(sum-zcomp)/100);
}
document.getElementById('plan').innerHTML=pn;
document.getElementById('bonus').innerHTML=db;
document.getElementById('profit').innerHTML=pd;
document.getElementById('period').innerHTML=ip;
document.getElementById('days').innerHTML=dd;
document.getElementById('prib').innerHTML=round2(prib+zcomp);
document.getElementById('return').innerHTML=dr;
document.getElementById('prib2').innerHTML=round2(sum+prib+zcomp);
}
recalc();
|
tp-20,
Я не знаю, что пишет smarty в ваш набор radio
{foreach from=$calc_pselect item=i key=k}
<li><label class="radio"><input type="radio" name="plan" value="{$k}" checked><div>{$i}</div></label>
</li>
{/foreach}
Что такое $k ? Я вручную вписал в этот набор максимальные значения планов - для привязки к значениям в input и slider.
<li><label class="radio"><input type="radio" name="plan" value="1000" checked ><div>START</div></label>
</li>
<li><label class="radio"><input type="radio" name="plan" value="3000" ><div>STANDART</div></label>
</li>
<li><label class="radio"><input type="radio" name="plan" value="5000" ><div>PREMIUM</div></label>
</li>
Вы использовали при проверке мой набор radio? |
Dilettante_Pro,
Если я прав в своих предположениях, то в генерации набора radio лучше проставлять индекс плана в id элемента, а в value писать максимальное значение плана. А в функции recalc вместо p=p.value; тогда использовать
p=$('input[name="plan"]:checked').attr('id');
|
Dilettante_Pro,
$calc_pselect - это и есть один из планов $k - это значение ползунка (от 100 до 5000) Да, я использовал ваш набор radio, т.к. в смарти цикле foreach выдаёт ошибку - undefined plans[p]. id в input не дал результата (в цикле foreach) результат расчёта калькулятора выводится в элементе prib2 в скрипте в последней строке функции recalc. Когда скрипт работает правильно, до нажатия на кнопку Рассчитать, уже есть значение 0. Сейчас, когда скрипт работает неверно - значение пусто. единственный правильный вариант когда калькулятор считает и не перезагружается такой: (это что касается вёрстки)
{foreach from=$calc_pselect item=i key=k}
<li><label class="radio"><input type="radio" name="plan" value="{$k}" checked><div>{$i}</div></label></li>
{/foreach}
в input обязательно должен быть checked, а value обязательно {$k}. если поставить фиксировано например 100, скрипт опять выдаёт ошибку plans undefined============== вижу, вы готовы помочь. давайте в лс пообщаемся, а я отблагодарю :)) |
tp-20,
Цитата:
Вы читали пост№7? Зачем значение ползунка ставить в radio? Я не знаю smarty, но из {foreach from=$calc_pselect item=i key=k} можно предположить, что это индекс конкретного плана из массива планов, который потом используется в recalc в plans[p]. Но по индексу пункта плана невозможно(точнее, сложнее - можно при наличии в js-скрипте массива планов) синхронизировать радио с инпутом и слайдером. Попробуйте сделать по рекомендациям из пост№7. Цитата:
Цитата:
|
Цитата:
|
а можно принудительно задать конкретные значения в js-скрипте? через условия if?
т.е. конкретно прописать: если значение меньше 1000, то присвоить checked первой радиокнопке. если значение меньше 3000, отметить вторую радиокнопку. и значение меньше 5000 - третья радиокнопка.
<input type="radio" name="plan" value="{$k}" checked="checked">
<input type="text" name="sum" id="calc_sum" class="minCost" value=""/>
var plan = $('input[name=plan]'); // input с планами, values = {$k} - это счётчик планов (0,1,2)
var input = $('input.minCost'); // текстовое поле - ввести число от 100 до 5000
if (input.val() < 1000){
(plan.val(0)).prop('checked', true);
}
if (input.val() < 3000){
(plan.val(1)).prop('checked', true);
}
if (input.val() < 5000){
(plan.val(2)).prop('checked', true);
}
этот код не работает. что нужно исправить? |
tp-20,
var input = $('input.minCost'); // текстовое поле - ввести число от 100 до 5000
var plan = $('input[name=plan]'); // input с планами, values = {$k} - это счётчик планов (0,1,2)
plan.eq(0).prop('checked', true);
if (+input.val() > 3000){
plan.eq(2).prop('checked', true);
}
if (+input.val() > 1000){
plan.eq(1).prop('checked', true);
}
|
рони,
выдаёт ошибку TypeError: this.options.values is null, ссылаясь на jquery-ui по этому адресу: https://code.jquery.com/ui/1.12.1/jquery-ui.js jquery-ui.js (строка 14839, столбец 35) Соответственно, скрипт не работает |
Цитата:
|
Приветствую!
Калькулятор тот же, только слегка видоизменённый)) Поэтому новую тему создавать не буду..) Что имеем: двигаем ползунок - меняется значение в инпуте и в блоке "доход в день и в месяц". Что надо: когда вручную вводим число в инпут, в блоке "доход в день и в месяц" значения не меняются, хотя ползунок перемещается. Как это сделать? ![]() <div> <input type="text" class="main-tariffs-calc-value main-tariffs-calc-value-1" value="10000"> // инпут, куда вручную вводим значение <div class="main-tariffs-calc-slider-1"></div> // ползунок (слайдер) </div> <div> <div>Доход за сутки:</div> <div><input type="text" value="100" class="daily-value-1"> USD</div> </div> <div> <div>Доход за месяц:</div> <div><input type="text" value="3000" class="month-value-1"> USD</div> </div> <div> <div>Итоговый доход:</div> <div><input type="text" value="70000" class="total-value-1"> USD</div> </div>
var input = $('input.main-tariffs-calc-value-1');
var slider = $('.main-tariffs-calc-slider-1').slider({
range: 'min',
min: 500,
max: 50000,
value: [10000],
step: 500,
animate: 500,
slide : function(event, ui) {
slider_value = input.val(ui.value); // это значение ползунка
slider_value = Number(slider_value.val()); // явно преобразуем его в число
//console.log(slider_value);
daily_value = Number($('.daily-value-1').val()); // инпут для значения прибыли за 1 день
daily_value = slider_value * 1.8/100;
$('.daily-value-1').val(daily_value); // динамически выводим новое значение (при движении ползунка)
month_value = ($('.month-value-1').val()); // инпут для значения прибыли за 1 месяц
month_value = slider_value * 1.8/100*30;
$('.month-value-1').val(month_value); // динамически выводим новое значение (при движении ползунка)
total_value = Number($('.total-value-1').val()); // инпут для значения итоговой прибыли
total_value = slider_value * 1.8/100*70 + slider_value;
$('.total-value-1').val(total_value); // динамически выводим новое значение (при движении ползунка)
}
});
input.on('change', function() {
slider.slider('value', $(this).val());
});
$('.main-tariffs-calc-value-1').text($('.main-tariffs-calc-slider-1').slider('value'));
|
tp-20,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$(function() {
var input = $('input.main-tariffs-calc-value-1');
var slider = $('.main-tariffs-calc-slider-1').slider({
range: 'min',
min: 500,
max: 50000,
value: [10000],
step: 500,
animate: 500
});
$('.main-tariffs-calc-slider-1').on( "slide", function( event, ui ) {
if(ui) slider_value = input.val(ui.value); // это значение ползунка
slider_value = Number(input.val()); // явно преобразуем его в число
//console.log(slider_value);
daily_value = Number($('.daily-value-1').val()); // инпут для значения прибыли за 1 день
daily_value = slider_value * 1.8/100;
$('.daily-value-1').val(daily_value); // динамически выводим новое значение (при движении ползунка)
month_value = ($('.month-value-1').val()); // инпут для значения прибыли за 1 месяц
month_value = slider_value * 1.8/100*30;
$('.month-value-1').val(month_value); // динамически выводим новое значение (при движении ползунка)
total_value = Number($('.total-value-1').val()); // инпут для значения итоговой прибыли
total_value = slider_value * 1.8/100*70 + slider_value;
$('.total-value-1').val(total_value); // динамически выводим новое значение (при движении ползунка)
} );
input.on('change', function() {
slider.slider('value', $(this).val());
$('.main-tariffs-calc-slider-1').trigger('slide');
});
$('.main-tariffs-calc-value-1').text($('.main-tariffs-calc-slider-1').slider('value'));
});
</script>
</head>
<body>
<div>
<input type="text" class="main-tariffs-calc-value main-tariffs-calc-value-1" value="10000"> // инпут, куда вручную вводим значение
<div class="main-tariffs-calc-slider-1"></div> // ползунок (слайдер)
</div>
<div>
<div>Доход за сутки:</div>
<div><input type="text" value="100" class="daily-value-1"> USD</div>
</div>
<div>
<div>Доход за месяц:</div>
<div><input type="text" value="3000" class="month-value-1"> USD</div>
</div>
<div>
<div>Итоговый доход:</div>
<div><input type="text" value="70000" class="total-value-1"> USD</div>
</div>
</body>
</html>
|
Рони, спасибо, как всегда молниеносный точный ответ!
Вы вынесли slide отдельно, чтобы можно было поставить условие if?
$('.main-tariffs-calc-slider-1').on( "slide", function( event, ui ){
И вы ещё добавили trigger - за что он здесь отвечает? или что выполняет? спасибо
input.on('change', function() {
slider.slider('value', $(this).val());
$('.main-tariffs-calc-slider-1').trigger('slide');
});
|
Цитата:
|
Калк и код тот же.
Подскажите, как сделать изменение значений при вводе в input? Сейчас значения меняются по нажатию на Enter или когда input теряет фокус. А нужно - непосредственно при вводе цифр в input Менял change на onkeypress и на oninput - без изменений
input.on('change', function() {
slider.slider('value', $(this).val());
$('.main-tariffs-calc-slider-1').trigger('slide');
});
Скриншот для наглядности: ![]() |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
выручай! :help: |
tp-20,
var plan = $('[name=plan]');
|
рони,
этот вариант я тоже пробовал, но select не меняется. https://jsfiddle.net/tps20/qdym1uvb/2/ - тут накидал, чтобы проще ориентироваться. |
Цитата:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/south-street/jquery-ui.css">
<form method="post" name="calc" onsubmit="recalc(); return false;">
<div>
<select name="plan" id="plan">
<option value="1000">Start</option>
<option value="3000">Medium</option>
<option value="5000">Pro</option>
</select>
</div>
<div>
<input name="sum" id="calc_sum" type="text" class="minCost" value="" />
<div class="slider"></div>
</div>
<div>
<input name="calc_btn" value="Рассчитать" type="submit">
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
jQuery(function($) {
var plan = $('[name=plan]');
var input = $('input.minCost');
var slider = $('.slider').slider({
range: 'max',
min: 1000,
max: 5000,
value: 1000,
step: 10,
animate: 300,
slide: function(event, ui) {
input.val(ui.value);
checkPlan();
}
});
input.val(slider.slider('value'));
checkPlan();
plan.on('change', function() {
slider.slider('value', this.value);
input.val(this.value);
});
input.on('change', function() {
var value = this.value;
if (value > 5000) value = 5000;
if (value < 1000) value = 1000;
this.value = value;
checkPlan();
slider.slider('value', value);
});
$('input').keypress(function(event) {
var key, keyChar;
if (!event) var event = window.event;
if (event.keyCode) key = event.keyCode;
else if (event.which) key = event.which;
if (key == null || key == 0 || key == 8 || key == 13 || key == 9 || key == 46 || key == 37 || key == 39) return true;
keyChar = String.fromCharCode(key);
if (!/\d/.test(keyChar)) return false;
});
function checkPlan() {
var value = input.val();
if (value == 1000 || value == 3000 || value == 5000) plan.val(value)
}
});
</script>
</body>
</html>
|
рони,
да, спасибо! то что надо. подскажи пожалуйста ещё один момент. нужно указать диапазон value: например от 1000 до 2999, от 3000 до 4990, и от 4991 до 5000 - для примера. я так понял, это на строке 68 нужно изменить условие для value - должны быть диапазоны, чтобы при движении ползунка значения в селекте чётко переключались. что-то типа такого:
if ((value >= 1000 && value <= 2999) ||
(value >= 3000 && value <= 4990) ||
(value >= 4991 && value <= 5000)) plan.val(value)
|
tp-20,
function checkPlan() {
var value = +input.val();
if (value < 2300) value = 1000;
else if (value < 3600) value = 3000;
else value = 5000;
plan.val(value)
}
|
добрый вечер.
вопрос по слайдеру. как убрать второй ползунок? т.е. range не нужен. просто нужен одиночный ползунок. Спасибо!
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/south-street/jquery-ui.css">
<div id="slider"></div>
<input type="text" name="from" id="from" value="" placeholder="from" />
<input type="text" name="to" id="to" value="" placeholder="to" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
myData = [ 1,2,4,6,8,10,20,30,40,50,100,200,300,400,500 ];
slider_config = {
range: true,
min: 0,
max: myData.length - 1,
step: 1,
slide: function( event, ui ) {
// Set the real value into the inputs
$('#from').val( myData[ ui.values[0] ] );
$('#to').val( myData[ ui.values[1] ] );
},
create: function() {
$(this).slider('values',0,0);
$(this).slider('values',1,myData.length - 1);
}
};
// Render Slider
$('#slider').slider(slider_config);
</script>
<style>
* {
font-family:Arial;
font-size:20px;
}
body {
padding:20px;
}
#slider { margin:20px }
</style>
</body>
</html>
|
tp-20,
:-?
slider_config = {
min: 0,
max: myData.length - 1,
step: 1,
slide: function( event, ui ) {
$('#from').val( myData[ ui.value ] );
},
create: function(event, ui) {
$('#from').val( myData[0] );
}
};
|
рони, спасибо! :victory:
|
| Часовой пояс GMT +3, время: 19:13. |