Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Привязка input radio к слайдеру jQuery-UI (https://javascript.ru/forum/jquery/74172-privyazka-input-radio-k-slajjderu-jquery-ui.html)

tp-20 19.06.2018 19:52

Привязка 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

Dilettante_Pro 20.06.2018 14:17

Только уберите 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>

tp-20 20.06.2018 19:43

Цитата:

Сообщение от Dilettante_Pro (Сообщение 487901)
Только уберите checked из строки 5 вашего html

Спасибо! Привязка ползунка к радиокнопкам заработала!

Есть ошибка: при нажатии на кнопку submit "Рассчитать" скрипт ругается - TypeError: plans[p] is undefined, после чего страница перезагружается. Удаление из кода plans[p] ни к чему не привело.
Думаю, что эти планы plans[p] вообще нужно убрать, т.к. они прописаны вручную. Верно? ))
Прошу помощи разобраться!

Dilettante_Pro 20.06.2018 21:36

tp-20,
На Рассчитать мой пример работать не может, т.к. он создан по вашим неполным данным - в частности, отсутствует функция recalc. Что она делает - я не знаю. И пример html я написал вручную, вместо вашего smarty

tp-20 21.06.2018 00:16

есть отдельный скрипт непосредственно для рассчёта калькулятора.
я сначала подумал, что можно обойтись без него, но тут привязана часть функционала.
оттуда и лезет ошибка с планами 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();

Dilettante_Pro 21.06.2018 10:33

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 21.06.2018 12:04

Dilettante_Pro,
Если я прав в своих предположениях, то в генерации набора radio лучше проставлять индекс плана в id элемента, а в value писать максимальное значение плана.
А в функции recalc вместо
p=p.value;

тогда использовать
p=$('input[name="plan"]:checked').attr('id');

tp-20 21.06.2018 19:16

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
==============
вижу, вы готовы помочь. давайте в лс пообщаемся, а я отблагодарю :))

Dilettante_Pro 22.06.2018 10:25

tp-20,
Цитата:

Сообщение от tp-20
$calc_pselect - это и есть один из планов
$k - это значение ползунка (от 100 до 5000)
Да, я использовал ваш набор radio, т.к. в смарти цикле foreach выдаёт ошибку - undefined plans[p].
id в input не дал результата (в цикле foreach)

Не нужно использовать мой набор radio - нужно правильно генерировать набор при помощи smarty.
Вы читали пост№7?
Зачем значение ползунка ставить в radio?
Я не знаю smarty, но из {foreach from=$calc_pselect item=i key=k} можно предположить, что это индекс конкретного плана из массива планов, который потом используется в recalc в plans[p].
Но по индексу пункта плана невозможно(точнее, сложнее - можно при наличии в js-скрипте массива планов) синхронизировать радио с инпутом и слайдером.
Попробуйте сделать по рекомендациям из пост№7.

Цитата:

Сообщение от tp-20
в input обязательно должен быть checked

checked проставляет скрипт JS при начальном запуске и при изменениях значений.
Цитата:

Сообщение от tp-20
а value обязательно {$k}. если поставить фиксировано например 100, скрипт опять выдаёт ошибку plans undefined

Смотри текст выше и пост№7

Dilettante_Pro 22.06.2018 10:28

Цитата:

Сообщение от tp-20
давайте в лс пообщаемся

На форуме общаться эффективнее - может помочь кто-нибудь еще.


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