crazydev
crazydev

Reputation: 575

Validate dynamically generated checkbox in jquery

I have the following code-pen. What it does that we can add Add Category which will generate a blue box with initially a row of checkboxes embedded in class cars-item js-cars-item. Then we have different section that the user can add several rows of checkboxes when he clicks on Add Section. This will be embedded in a class of js-cars-item-sub-items

I am able to achieve validation on checkboxes within the js-cars-item-sub-items class. That is if I check the first checkbox in the first row as from section 2, when I click the first checkbox in the second row as in section 3, it unchecks in the section 2, and checks the section 3. This validation happens only in sections (green box).

Now, what I want to achieve is the same behavior in the main row of checkboxes (red box) - that is if I add another category, and I check the first checkbox in the first category, and when I check the same checkbox in the second category, it should uncheck the checkbox in the first category.

Anyone who can help me with this ? I am totally stuck.

var categoryCount = 1;

$('.js-add-category').click(function() {
	categoryCount++;
  var categoryContent = `<br><div class="serv-content">
     <div class="title-content">
     <input type="text" id="name-title-`+categoryCount+`" class="name-title" value="category-`+categoryCount+`">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-1">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-1">
          <label for="car-3"><i class="icon-tick"></i></label>
        </li>
      </ul>
      
      <div class="footer">
          <span class="num"> Section 1 </span>
      </div>
    </div>

<div class="action-btn">
        <button type="button" class="js-add-section">Add     Section</button>
    <button type="button" class="js-save-section">Save</button>
</div>
  <br>`

  $('.main-content').append(categoryContent);

});

var count = 1;

$(document.body).on('click', 'button.js-add-section', function() {

//count++;
let count = $(this).parent().parent().find('.cars-item').length+1;


  var sectionContent = `<div class="cars-item js-cars-item-sub-items">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <label for="car-3-2"><i class="icon-tick"></i></label>
        </li>
      </ul>      
      <div class="footer">
          <span class="num"> Section`+count+` </span>
      </div>
</div>`

$(this).closest('.serv-content').append(sectionContent);

});

$(document.body).on('click', 'button.js-save-section', function() {
		// get selected checkboxes's values
});


// validate checkboxes for sub items..

     $(".main-content").on('change', '.js-cars-item-sub-items [type="checkbox"]', function () {
        var idx = $(this).closest('li').index(); //Get the index - Number in order
        var chk = $(this).is(":checked"); //Get if checked or not
        var obj = this; //Checkbox object

        $(this).closest('.serv-content').find('.js-cars-item-sub-items').each(function () {
            //Find the checkbox with the same index of clicked checkbox. Change disabled property
            $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
        });

        var checkeds = [];
        $(this).closest(".serv-content").find(".js-cars-item-sub-items input:checkbox:checked").each(function (index) {
            checkeds[index] = $(this).attr('id');
        });
        console.clear();
        console.log("These are checked:", checkeds);
    });
    
// validate checkboxes for main items.. 

$(".main-content").on('change', '.js-cars-item [type="checkbox"]', function () {
        var idx = $(this).closest('li').index(); //Get the index - Number in order
        var chk = $(this).is(":checked"); //Get if checked or not
        var obj = this; //Checkbox object

        $(this).closest('.serv-content').find('.js-cars-item').each(function () {
            //Find the checkbox with the same index of clicked checkbox. Change disabled property
            $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
        });

        var checkeds = [];
        $(this).closest(".serv-content").find(".js-cars-item input:checkbox:checked").each(function (index) {
            checkeds[index] = $(this).attr('id');
        });
        console.clear();
        console.log("These are checked:", checkeds);
    });
.js-cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

.js-cars-item-sub-items {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid green;
}


ul {
  /* Added to fully show console in snippet */
  margin: 2px;
}

li {
  display: inline;
}

.serv-content {
  box-sizing: content-box;
  width: 250px;
  height: auto;
  padding: 10px;
  border: 5px solid blue;
}

.cars.saved {
  border-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button type="button" class="js-add-category">Add Category</button> <br> <br>

<div class="main-content">
  <div class="serv-content">
     <div class="title-content">
     <input type="text" id="name-title-1" class="name-title" value="category-1">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-1" checked>
          <label for="car-1-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-1" checked>
          <label for="car-2-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-1" checked>
          <label for="car-3-1"><i class="icon-tick"></i></label>
        </li>
      </ul>
      
      <div class="footer">
          <span class="num"> Section 1 </span>
      </div>
    </div>

<div class="action-btn">
        <button type="button" class="js-add-section">Add     Section</button>
    <button type="button" class="js-save-section">Save</button>
</div>
</div>
<br>

  </div>
  <br> <br>

Upvotes: 2

Views: 445

Answers (1)

vikscool
vikscool

Reputation: 1313

The problem comes when you loop through checkbox using the syntax $(this).closest('.serv-content').find('.js-cars-item').each() you where only looping through the caller checkbox's parent .serv-content class as the object this represents the caller checkbox and not the other .serv-content checkboxes.

So, to loop through the other .serv-content, I have added an id to all the .serv-content div that you are creating and when you click on the checkbox I am looping through all the div that have the class .serv-content but not the id of the caller.

So first, I made changes to your code on the $('.js-add-category').click()

from this:

var categoryContent = `<br><div class="serv-content">

to this:

var categoryContent = `<br><div id="serv-` + categoryCount + `" class="serv-content">

Then made changes to your checkbox's click function $(".main-content").on('change', '.js-cars-item [type="checkbox"]', function() {});

From this:

$(".main-content").on('change', '.js-cars-item [type="checkbox"]', function () {
    var idx = $(this).closest('li').index(); //Get the index - Number in order
    var chk = $(this).is(":checked"); //Get if checked or not
    var obj = this; //Checkbox object

    $(this).closest('.serv-content').find('.js-cars-item').each(function () {
        //Find the checkbox with the same index of clicked checkbox. Change disabled property
        $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
    });

    var checkeds = [];
    $(this).closest(".serv-content").find(".js-cars-item input:checkbox:checked").each(function (index) {
        checkeds[index] = $(this).attr('id');
    });
    console.clear();
    console.log("These are checked:", checkeds);
});

To This:

$(".main-content").on('change', '.js-cars-item [type="checkbox"]', 
function() {
 var idx = $(this).closest('li').index(); //Get the index - Number in order
 var chk = $(this).is(":checked"); //Get if checked or not
 var obj = this; //Checkbox object
 var callerId = $(this).closest('.serv-content').attr('id');

 $('.main-content').find('.serv-content:not(#' + callerId + ')').each(function() {
$(this).find('.js-cars-item').each(function() {
  //Find the checkbox with the same index of clicked checkbox. Change 
disabled property
  $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
});
 });

 var checkeds = [];
 $(this).closest(".serv-content").find(".js-cars-item 
  input:checkbox:checked").each(function(index) {
checkeds[index] = $(this).attr('id');
 });
 console.clear();
 console.log("These are checked:", checkeds);
});

And here is your complete code snippet.

var categoryCount = 1;

$('.js-add-category').click(function() {
  categoryCount++;
  var categoryContent = `<br><div id="serv-` + categoryCount + `" class="serv-content">
     <div class="title-content">
     <input type="text" id="name-title-` + categoryCount + `" class="name-title" value="category-` + categoryCount + `">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-1">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-1">
          <label for="car-3"><i class="icon-tick"></i></label>
        </li>
      </ul>
      
      <div class="footer">
          <span class="num"> Section 1 </span>
      </div>
    </div>

<div class="action-btn">
        <button type="button" class="js-add-section">Add     Section</button>
    <button type="button" class="js-save-section">Save</button>
</div>
  <br>`

  $('.main-content').append(categoryContent);

});

var count = 1;

$(document.body).on('click', 'button.js-add-section', function() {

  //count++;
  let count = $(this).parent().parent().find('.cars-item').length + 1;


  var sectionContent = `<div class="cars-item js-cars-item-sub-items">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <label for="car-3-2"><i class="icon-tick"></i></label>
        </li>
      </ul>      
      <div class="footer">
          <span class="num"> Section` + count + ` </span>
      </div>
</div>`

  $(this).closest('.serv-content').append(sectionContent);

});

$(document.body).on('click', 'button.js-save-section', function() {
  // get selected checkboxes's values
});


// validate checkboxes for sub items..

$(".main-content").on('change', '.js-cars-item-sub-items [type="checkbox"]', function() {
  var idx = $(this).closest('li').index(); //Get the index - Number in order
  var chk = $(this).is(":checked"); //Get if checked or not
  var obj = this; //Checkbox object

  $(this).closest('.serv-content').find('.js-cars-item-sub-items').each(function() {
    //Find the checkbox with the same index of clicked checkbox. Change disabled property
    $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
  });

  var checkeds = [];
  $(this).closest(".serv-content").find(".js-cars-item-sub-items input:checkbox:checked").each(function(index) {
    checkeds[index] = $(this).attr('id');
  });
  console.clear();
  console.log("These are checked:", checkeds);
});

// validate checkboxes for main items.. 

$(".main-content").on('change', '.js-cars-item [type="checkbox"]', function() {
  var idx = $(this).closest('li').index(); //Get the index - Number in order
  var chk = $(this).is(":checked"); //Get if checked or not
  var obj = this; //Checkbox object
  var callerId = $(this).closest('.serv-content').attr('id');
  debugger;
  $('.main-content').find('.serv-content:not(#' + callerId + ')').each(function() {
    $(this).find('.js-cars-item').each(function() {
      //Find the checkbox with the same index of clicked checkbox. Change disabled property
      $(this).find('li:eq(' + idx + ') [type="checkbox"]').not(obj).prop("checked", false);
    });
  });

  var checkeds = [];
  $(this).closest(".serv-content").find(".js-cars-item input:checkbox:checked").each(function(index) {
    checkeds[index] = $(this).attr('id');
  });
  console.clear();
  console.log("These are checked:", checkeds);
});
.js-cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

.js-cars-item-sub-items {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid green;
}

ul {
  /* Added to fully show console in snippet */
  margin: 2px;
}

li {
  display: inline;
}

.serv-content {
  box-sizing: content-box;
  width: 250px;
  height: auto;
  padding: 10px;
  border: 5px solid blue;
}

.cars.saved {
  border-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button type="button" class="js-add-category">Add Category</button> <br> <br>

<div class="main-content">
  <div class="serv-content">
    <div class="title-content">
      <input type="text" id="name-title-1" class="name-title" value="category-1">
    </div>


    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-1" checked>
          <label for="car-1-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-1" checked>
          <label for="car-2-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-1" checked>
          <label for="car-3-1"><i class="icon-tick"></i></label>
        </li>
      </ul>

      <div class="footer">
        <span class="num"> Section 1 </span>
      </div>
    </div>

    <div class="action-btn">
      <button type="button" class="js-add-section">Add     Section</button>
      <button type="button" class="js-save-section">Save</button>
    </div>
  </div>
  <br>

</div>
<br> <br>

Upvotes: 2

Related Questions