Javascript работа с чекбоксами, не обычный вопрос

359
26 апреля 2018, 07:06

Помогите, ломаю голову уже который день надо этим, в общем, есть html:

    <div class='some1'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
    </div>
<div class='some2'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
    </div>
<div class='some3'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
<input type='checkbox'>
    </div>

Нужно узнать значения всех checkbox в этом html и занести их в массив, выглядеть это должно как то так array['onononon','offonononon',....]

Проблема заключается в том, что надо понять, находится ли чекбокс в определенном <div> и заносить соответственно в массив. На выходе должен быть массив из строк значений бокса в соответствии с <div>. Пробовал так:

var numq = 3; // переменная в которой хранится количество divov на странице(она считает создаваемые дивы)
var templatevar; //Временная переменная , для хранения строки
var answers = [];//Переменная для ответов
var workingclass = 'some1';//Начальный класс div 
for(var i = 0; i<numq; i++){
   $('.some'+i+' input[type=checkbox]').each(function(){
     if($(this).parent().prop('class')==workingclass){
        templatevar += $(this).val(); // returns in var 'on' or 'off' as default
     }
     else{
        answers.push(templatevar);
        templatevar = $(this).val();
        workingclass = $(this).parent().prop('class');
     }
   });
}
console.log(answers);

Но в итоге, этот код не работает. Подскажите что нибудь.

Answer 1

Запустите два цикла. Один по дивам, а второй - по вложенным чекбоксам

jQuery(function($) { 
  $('#test').click(function() { 
    var answers = []; 
    $('div.check').each(function() { 
      var answer = ''; 
      $(":checkbox", this).each(function() { 
        answer += (this.checked) ? "on" : "off" 
      }); 
      answers.push(answer); 
    }); 
    console.log(answers); 
  }); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class='check some1'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='check some2'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='check some3'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<button id="test">Test</button>

Answer 2

На чистом JavaScript (ES6):

document.getElementById('test').addEventListener('click', () => { 
  let divs = document.querySelectorAll('div[class^="some"]'),  
      result = [];  
  for (let div of divs) { 
    let str = '';  
    let chkbxs = div.querySelectorAll('input[type="checkbox"]'); 
    for (let chkbx of chkbxs) 
      str += chkbx.checked ? 'on' : 'off';  
    result.push(str);  
  } 
  console.clear();  
  console.log(result.join('\n')); 
}); 
<div class='some1'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='some2'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='some3'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<button id="test">Тест</button>

Я бы посоветовал Вам вместо "on" и "off" использовать "1" и "0", соответственно. Если строки затем передаются серверному скрипту, так будет значительно легче их разбирать. В коде для этого достаточно поменять строки в тернарном операторе:

str += chkbx.checked ? '1' : '0'; 

или, даже проще (и быстрее):

str += +chkbx.checked; 

Еще лучше - когда чекбоксов немного (<32), формировать вместо строк числа, используя битовый сдвиг. Это сделает данные компактнее, и ускорит их разбор.
То есть, сдвигать булевое значение свойства checked на битовый разряд, соответствующий позиции чекбокса в родительском элементе: первый чекбокс - нулевой разряд (00000Х), второй чекбокс - первый разряд (0000Х0), и так далее.
В скобках 8битное представление использовано только для краткости. При побитовых операциях, JavaScript позволяет использовать 32битные целые числа.

Answer 3

Не такой уж он "не обычный".

function collect() { 
  var answers = []; 
  $("div input[type='checkbox']").each(function(){ 
    var parentClass = $(this).closest("div").attr("class"); 
    var parent = answers.find(item => item.parentClass == parentClass); 
    if (!parent) { 
      parent = { parentClass: parentClass, values: "" }; 
      answers.push(parent); 
    } 
    parent.values += this.checked? "on" : "off"; 
  }); 
  answers = answers.map(item => item.values); 
  console.log(answers); 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class='some1'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='some2'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<div class='some3'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
  <input type='checkbox'> 
</div> 
<button onclick="collect()">Click</button>