Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.06.2018, 19:52
Аспирант
Отправить личное сообщение для tp-20 Посмотреть профиль Найти все сообщения от tp-20
 
Регистрация: 19.06.2018
Сообщений: 42

Привязка 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
Ответить с цитированием
  #2 (permalink)  
Старый 20.06.2018, 14:17
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

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

Последний раз редактировалось Dilettante_Pro, 20.06.2018 в 14:35.
Ответить с цитированием
  #3 (permalink)  
Старый 20.06.2018, 19:43
Аспирант
Отправить личное сообщение для tp-20 Посмотреть профиль Найти все сообщения от tp-20
 
Регистрация: 19.06.2018
Сообщений: 42

Сообщение от Dilettante_Pro Посмотреть сообщение
Только уберите checked из строки 5 вашего html
Спасибо! Привязка ползунка к радиокнопкам заработала!

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

Последний раз редактировалось tp-20, 20.06.2018 в 19:46.
Ответить с цитированием
  #4 (permalink)  
Старый 20.06.2018, 21:36
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

tp-20,
На Рассчитать мой пример работать не может, т.к. он создан по вашим неполным данным - в частности, отсутствует функция recalc. Что она делает - я не знаю. И пример html я написал вручную, вместо вашего smarty
Ответить с цитированием
  #5 (permalink)  
Старый 21.06.2018, 00:16
Аспирант
Отправить личное сообщение для tp-20 Посмотреть профиль Найти все сообщения от tp-20
 
Регистрация: 19.06.2018
Сообщений: 42

есть отдельный скрипт непосредственно для рассчёта калькулятора.
я сначала подумал, что можно обойтись без него, но тут привязана часть функционала.
оттуда и лезет ошибка с планами 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();
Ответить с цитированием
  #6 (permalink)  
Старый 21.06.2018, 10:33
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

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?
Ответить с цитированием
  #7 (permalink)  
Старый 21.06.2018, 12:04
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

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

тогда использовать
p=$('input[name="plan"]:checked').attr('id');
Ответить с цитированием
  #8 (permalink)  
Старый 21.06.2018, 19:16
Аспирант
Отправить личное сообщение для tp-20 Посмотреть профиль Найти все сообщения от tp-20
 
Регистрация: 19.06.2018
Сообщений: 42

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, 21.06.2018 в 20:50.
Ответить с цитированием
  #9 (permalink)  
Старый 22.06.2018, 10:25
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

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
Ответить с цитированием
  #10 (permalink)  
Старый 22.06.2018, 10:28
Профессор
Отправить личное сообщение для Dilettante_Pro Посмотреть профиль Найти все сообщения от Dilettante_Pro
 
Регистрация: 27.11.2015
Сообщений: 2,899

Сообщение от tp-20
давайте в лс пообщаемся
На форуме общаться эффективнее - может помочь кто-нибудь еще.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
radio button внутри петли и jquery Юльув jQuery 5 09.11.2010 16:10
Баг Firefox: по F5 перескакивает radio при динамическом добавлении в DOM input Atoll Events/DOM/Window 6 22.06.2010 18:25
jQuery и Input - > radio yu_ jQuery 3 02.04.2010 00:43
jquery и input text tazododu jQuery 3 19.02.2010 09:55
jQuery watermark input field jquery_watermark Armen jQuery 4 29.12.2009 23:15