Привязка 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; }); }); И картинка для удобного восприятия: ![]() |
Только уберите 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, время: 09:47. |