Как добавить класс блоку в зависимости от комбинации радиокнопок?

142
12 декабря 2019, 04:40

Всем привет. Есть два блока радиокнопок в каждом по 3 кнопки (Первый: 1 человек, 2 человека, Семья. Второй: 3 дня, 5 дней, 7 дней). Надо добавить класс блоку в зависимости от выбора кнопки в каждом блоке. Т.е., к примеру: 1 человек + 3 дня = красный квадрат, 1 человек + 5 дней = зелёный треугольник и т.д. Есть код, но он работает не до конца. 7 значений срабатывают, а 2 нет. Пример кода:

var shapes = ['square', 'circle', 'triangle-up', 'parallelogram', 'parallelogram-green', 'triangle-up-green', 'circle-green', 'square-green', 'square-black'] 
 
function showShape() { 
  var iShape = $('form :checked').toArray().map((n, i) => $(n).index() << i).reduce((p, c) => p | c, 0); 
  $('#box').removeClass(shapes.join(' ')).addClass(shapes[iShape]) 
} 
 
$('input[type="radio"]').change(showShape) 
 
showShape()
#box {} 
 
.square { 
  width: 100px; 
  height: 100px; 
  background: red; 
} 
 
.circle { 
  width: 100px; 
  height: 100px; 
  background: red; 
  -moz-border-radius: 50px; 
  -webkit-border-radius: 50px; 
  border-radius: 50px; 
} 
 
.triangle-up { 
  width: 0; 
  height: 0; 
  border-left: 50px solid transparent; 
  border-right: 50px solid transparent; 
  border-bottom: 100px solid red; 
} 
 
.parallelogram { 
  width: 150px; 
  height: 100px; 
  -webkit-transform: skew(20deg); 
  -moz-transform: skew(20deg); 
  -o-transform: skew(20deg); 
  background: red; 
} 
 
.parallelogram-green { 
  width: 150px; 
  height: 100px; 
  -webkit-transform: skew(-10deg); 
  -moz-transform: skew(-10deg); 
  -o-transform: skew(-10deg); 
  background: green; 
} 
 
.triangle-up-green { 
  width: 0; 
  height: 0; 
  border-left: 30px solid transparent; 
  border-right: 50px solid transparent; 
  border-bottom: 100px solid green; 
} 
 
.circle-green { 
  width: 100px; 
  height: 100px; 
  background: green; 
  -moz-border-radius: 50px; 
  -webkit-border-radius: 50px; 
  border-radius: 50px 
} 
 
.square-green { 
  width: 100px; 
  height: 100px; 
  background: green 
} 
 
.square-black { 
  width: 100px; 
  height: 100px; 
  background: black; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<form> 
  <input id="1" name="form-1" type="radio" checked> 1 человек 
  <input id="2" name="form-1" type="radio"> 2 человека 
  <input id="3" name="form-1" type="radio"> Семья 
</form> 
<br> 
<br> 
 
<form> 
  <input id="4" name="form-2" type="radio" checked> 3 дня 
  <input id="5" name="form-2" type="radio"> 5 дней 
  <input id="6" name="form-2" type="radio"> 7 дней 
</form> 
<br> 
<br> 
 
<div id="box"> 
  <div>

Подскажите, пожалуйста, где ошибка?

Теперь появилась другая проблема: Понадобилось стилизовать радиокнопки. Обернул в и всё перестало работать.

window.onload = function() { 
  const shapes = ['square', 'circle', 'triangle-up', 'parallelogram', 'parallelogram-green', 'triangle-up-green', 'circle-green', 'square-green', 'square-black'] 
 
  function showShape() { 
    const checkedIndexes = $('form :checked').toArray().map((n, i) => $(n).index()); 
    const iShape = checkedIndexes[0] + checkedIndexes[1] * 3; 
    console.log(iShape); 
    $('#box').removeClass(shapes.join(' ')).addClass(shapes[iShape]) 
  } 
  $('input[type="radio"]').change(showShape) 
  showShape() 
}
#box { 
  text-align: center; 
  margin: 0 auto; 
  float: none; 
} 
 
.square { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: black; 
} 
 
.circle { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: red; 
} 
 
.triangle-up { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: green; 
} 
 
.parallelogram { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: blue; 
} 
 
.parallelogram-green { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: yellow; 
} 
 
.triangle-up-green { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: orangered; 
} 
 
.circle-green { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: #2DD14A; 
} 
 
.square-green { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: #2C5A77; 
} 
 
.square-black { 
  top: 0; 
  display: block; 
  text-align: left; 
  float: left; 
  margin-right: 48px; 
  width: 446px; 
  height: 374px; 
  background-color: #53076F; 
} 
 
body { 
  margin: 0; 
  padding: 0; 
  font-family: sans-serif; 
  color: #333; 
  background-color: #eee; 
} 
 
h1, 
h2, 
h3, 
h4, 
h5, 
h6 { 
  font-weight: 200; 
  font-size: 1em; 
} 
 
h1 { 
  text-align: center; 
  padding-bottom: 10px; 
  border-bottom: 2px solid #2fcc71; 
  max-width: 40%; 
  margin: 20px auto; 
} 
 
.container { 
  max-width: 850px; 
  width: 100%; 
  margin: 0 auto; 
} 
 
input[type="radio"] { 
  display: none; 
} 
 
label { 
  height: 100%; 
  background: white; 
  border: 2px solid hsla(150, 75%, 50%, 1); 
  padding: 1rem; 
  margin-bottom: 1rem; 
  text-align: center; 
  box-shadow: 0px 3px 10px -2px hsla(150, 5%, 65%, 0.5); 
  position: relative; 
  cursor: pointer; 
} 
 
input[type="radio"]:checked+label { 
  background: hsla(150, 75%, 50%, 1); 
  color: hsla(215, 0%, 100%, 1); 
  box-shadow: 0px 0px 20px hsla(150, 100%, 50%, 0.75); 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<div class="container"> 
  <h1>ВЫБЕРИТЕ ПЛАН:</h1> 
  <div style="display: block; margin: 0 auto; text-align: center;"> 
    <div style="display: inline-block;margin-right: 20px;margin-bottom: 40px;"> 
      <h2>Количество человек:</h2> 
      <div> 
        <form> 
          <label for="1"><input id="1" name="form-1" type="radio" checked>1</label> 
          <label for="2"><input id="2" name="form-1" type="radio">2</label> 
          <label for="3"><input id="3" name="form-1" type="radio">4</label> 
        </form> 
        <br> 
        <br></div> 
    </div> 
 
 
    <div style="display: inline-block;margin-bottom: 40px;"> 
      <h2>Количество дней:</h2> 
      <div> 
 
        <form> 
          <label for="4"><input id="4" name="form-2" type="radio" checked>3</label> 
          <label for="5"><input id="5" name="form-2" type="radio"> 5</label> 
          <label for="6"><input id="6" name="form-2" type="radio"> 7</label> 
        </form> 
        <br> 
        <br></div> 
    </div> 
 
 
    <div id="box"> 
    </div> 
  </div> 
</div>

Подскажите, пожалуйста, где я напортачил?

Answer 1

Проблема была с вычислением индекса.

Посмотрите пример, здесь используется метод попроще.

const shapes = ['square', 'circle', 'triangle-up', 'parallelogram', 'parallelogram-green', 'triangle-up-green', 'circle-green', 'square-green', 'square-black'] 
 
function showShape() { 
  const checkedIndexes = $('form :checked').toArray().map((n, i) => $(n).index()); 
  const iShape = checkedIndexes[0] + checkedIndexes[1] * 3; 
  console.log(iShape); 
  $('#box').removeClass(shapes.join(' ')).addClass(shapes[iShape]) 
} 
 
$('input[type="radio"]').change(showShape) 
 
showShape()
#box {} 
 
.square { 
  width: 100px; 
  height: 100px; 
  background: red; 
} 
 
.circle { 
  width: 100px; 
  height: 100px; 
  background: red; 
  -moz-border-radius: 50px; 
  -webkit-border-radius: 50px; 
  border-radius: 50px; 
} 
 
.triangle-up { 
  width: 0; 
  height: 0; 
  border-left: 50px solid transparent; 
  border-right: 50px solid transparent; 
  border-bottom: 100px solid red; 
} 
 
.parallelogram { 
  width: 150px; 
  height: 100px; 
  -webkit-transform: skew(20deg); 
  -moz-transform: skew(20deg); 
  -o-transform: skew(20deg); 
  background: red; 
} 
 
.parallelogram-green { 
  width: 150px; 
  height: 100px; 
  -webkit-transform: skew(-10deg); 
  -moz-transform: skew(-10deg); 
  -o-transform: skew(-10deg); 
  background: green; 
} 
 
.triangle-up-green { 
  width: 0; 
  height: 0; 
  border-left: 30px solid transparent; 
  border-right: 50px solid transparent; 
  border-bottom: 100px solid green; 
} 
 
.circle-green { 
  width: 100px; 
  height: 100px; 
  background: green; 
  -moz-border-radius: 50px; 
  -webkit-border-radius: 50px; 
  border-radius: 50px 
} 
 
.square-green { 
  width: 100px; 
  height: 100px; 
  background: green 
} 
 
.square-black { 
  width: 100px; 
  height: 100px; 
  background: black; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<form> 
  <input id="1" name="form-1" type="radio" checked> 1 человек 
  <input id="2" name="form-1" type="radio"> 2 человека 
  <input id="3" name="form-1" type="radio"> Семья 
</form> 
<br> 
<br> 
 
<form> 
  <input id="4" name="form-2" type="radio" checked> 3 дня 
  <input id="5" name="form-2" type="radio"> 5 дней 
  <input id="6" name="form-2" type="radio"> 7 дней 
</form> 
<br> 
<br> 
 
<div id="box"> 
  <div>

READ ALSO
маска для ввода номера телефона чистый javascript

маска для ввода номера телефона чистый javascript

помогите написать маску такого формата +7 (999) 999-99-99 без стороних библиотек

123
найти навешенный обработчик

найти навешенный обработчик

Имеем элемент с навешенным на нём обработчиком $(el)on('click', function() {/* содержимое анонимной функции */}), как найти этот обработчик в мозиле event не указывает...

134
Плавное перемещение меню сайта

Плавное перемещение меню сайта

Я пытаюсь сделать такой же эффект как у bootstrap когда листаешь страничку вверх-вниз и меню, которое находится вверху, перемещается вместе со скроллированием

144
MySQL NULL ошибка запроса SELECT

MySQL NULL ошибка запроса SELECT

Всем привет, пишу парсер расписанияБывают ситуации когда нету у занятия учителя

122