1

I am having an issue with the following code snippet. The idea is to generate another category when I click the Add Category button, thus a new box blue appears with an initial row of checkboxes labelled with Section 1 inside the red box. Inside that box, if I click the button Add Section, it adds another row of checkboxes and so on. Thus, the Section labels in the red box increments as from 1 and onwards inside a particular blue box. The issue is that when I hit add section in another blue box, the label does not increment accordingly. Also, how can I trigger the Save button to get the values of the checked checkboxes and the input field separately for each blue box ?

Please help, I'm totally stuck with this. Thanks.

var categoryCount = 1;

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

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <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>
</div>
  <br>`

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

});

var count = 1;

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

count++;

  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
});

    $(".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 () { 

        $(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);
});
.cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

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="name-1">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3">
          <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>
</div>
<br>



  </div>
  <br>
  
  
crazydev
  • 575
  • 2
  • 9
  • 30

4 Answers4

2

You are counting the total occurrences (incrementing on every addition). I suggest you count the number of sections in the current category and use that to decide the number of the newly created section.

Also, I'd really suggest you keep your HTML in HTML, and not in javascript. This will greatly help in the future. What you could do is have those elements in a hidden div so you can clone them when needed...

var categoryCount = 1;

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

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <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>
</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
});
.cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

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="name-1">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3">
          <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>
</div>
<br>



  </div>
  <br>
Salketer
  • 14,263
  • 2
  • 30
  • 58
  • Thank you. It works fine. I have made a small edit that gets the values of checked checkboxes. How can I trigger the `Save` button to `alert` me the selected values of the checked checkboxes in each category ? Please one last help. Its the only issue I am having. – crazydev May 22 '18 at 07:19
  • This is a whole different question... Please refer to this maybe? https://stackoverflow.com/questions/36211135/how-to-alert-input-value – Salketer May 22 '18 at 07:33
  • I know. But I just encountered this issue. That's why I preferred to ask you again instead of making duplication questions. Please see if you can help me with this. – crazydev May 22 '18 at 07:34
1

Do it like this:

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

  var count = ($(this).closest(".serv-content").find(".cars-item").length + 1)

It will count the number of Sections in the corresponding Category.

Demo

var categoryCount = 1;

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

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <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>
</div>
  <br>`

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

});


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

  var count = ($(this).closest(".serv-content").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() {
  $(this).closest(".serv-content").find(".cars-item").each(function(){
    var sec = $(this).find(".num").text();
    $(this).find("input:checkbox:checked").each(function(){
      alert(sec + " : " + $(this).attr("id"))
    })
  })
});
.cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

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="name-1">
    </div>


    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3">
          <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>
  </div>
  <br>



</div>
<br>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
  • Thank you for your help. I have made a small edit that gets the values of checked checkboxes. How can I trigger the Save button to alert me the selected values of the checked checkboxes in each category ? Please one last help. Its the only issue I am having. – crazydev May 22 '18 at 07:20
  • 1
    @jones Try and run the demo and tell me if that is what you want? – Carsten Løvbo Andersen May 22 '18 at 07:41
  • Actually, it should get the checkboxes values of the whole category and show only one alert. But nevermind, I figured it out. Thank you very much for your help Carsten :) God bless you :) – crazydev May 22 '18 at 07:52
  • @jones No problem, happy to help – Carsten Løvbo Andersen May 22 '18 at 07:54
1

You can use a custom data attribute (data-count) on the .js-add-section button to hold the respective counter:

var categoryCount = 1;

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

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-2">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-2">
          <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>
</div>
  <br>`

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

});


$(document.body).on('click', 'button.js-add-section', function() {
  var that = $(this);
  var thisCount = that.attr('data-count');
  var count = (thisCount && thisCount.length > 0) ? parseInt(thisCount) + 1 : 2;
  that.attr('data-count', count);
  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() {
    var section = $(this).closest('.serv-content');
    var chk = section.find('input[type="checkbox"]').filter(':checked').toArray().map(function(x) { return $(x).attr('id'); });
    console.log(chk);
});
.cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

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="name-1">
     </div>
       

    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1">
          <label for="car-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2">
          <label for="car-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3">
          <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>
</div>
<br>



  </div>
  <br>
  
  
kapantzak
  • 11,610
  • 4
  • 39
  • 61
  • Thank you for your help. I have made a small edit that gets the values of checked checkboxes. How can I trigger the Save button to alert me the selected values of the checked checkboxes in each category ? Please one last help. Its the only issue I am having. – crazydev May 22 '18 at 07:20
  • 1
    Run the code snippet again and check the console after checking some checkboxes and clicking Save – kapantzak May 22 '18 at 07:28
  • Thank youuuuuuu.. You are the boss (Y). May God bless you with immense knowledge. – crazydev May 22 '18 at 07:40
0

Jones, I played a little with your code and tried to enhance multiple things:

  • As you should keep your HTML in your HTML, I've reorganized a little the HTML structure and added a new class .typical to hide the divs that are used in the JavaScript.
  • I managed the addition of categories and sections using data-count variables that count the sections in each category, and string replacements (#cat#categoryCount, #sec#sectionCount).
  • All the checkboxes are now numbered #cat#-#sec#-1 to 3.

⋅ ⋅ ⋅

Note that the HTML starts empty and the JS adds the first category onload.
That way, you will ensure that all the div will be similar because it's all created by the JS.
Plus, you'll only need to modify the HTML code in one place!

Then, I used a function to get all the checkboxes states of the "category" as an array in console.

Here is a working snippet with all that modifications:

var categoryCount = 0;
$('.js-add-category').click(function() {
  categoryCount++;
  var categoryContent = $('.typical.serv-content').html().replace(/#cat#/g, categoryCount);
  $('.main-content').append(categoryContent);
  $('#name-title-' + categoryCount).closest('.serv-content').find('button.js-add-section').trigger('click'); // Trigger the "add section" click in the new empty category
});

$(document.body).on('click', 'button.js-add-section', function() {
  var elm = $(this).closest('.serv-content').find('.cars-item');
  var sectionCount = (+$(elm).attr('data-count') || 0) + 1; // ( Unary || 0 ) + 1
  $(elm).attr('data-count', sectionCount);
  var sectionContent = $('.typical.cars-item').html().replace(/#cat#/g, categoryCount).replace(/#sec#/g, sectionCount);
  $(this).closest('.action-btn').before(sectionContent);
});

$(document.body).on('click', 'button.js-save-section', function() {
  var cbs = [];
  $(this).closest('.serv-content').find('.cars-item input[type=checkbox]').each(function(index, obj) {
    cbs[index] = $(obj).attr('id') + ': ' + $(obj).prop('checked');
  });
  console.clear();
  console.log(cbs);
});

// Trigger category add onload
$('.js-add-category').trigger('click');
.cars-item {
  box-sizing: content-box;
  width: auto;
  height: auto;
  padding: 10px;
  border: 3px solid red;
}

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

li {
  display: inline;
}

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

/* Added to hide typicals */

.typical {
  display: none;
}


/* Added to show console correctly */

.main-content {
  margin-bottom: 80px;
}

.as-console-wrapper {
  max-height: 80px !important;
}
<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" data-count="1">

  <div class="typical serv-content">
    <div class="serv-content">
      <div class="title-content">
        <input type="text" id="name-title-#cat#" class="name-title" value="name-#cat#">
      </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>
  </div>

  <div class="typical cars-item">
    <div class="cars-item js-cars-item" data-count="1">
      <ul>
        <li>
          <input type="checkbox" id="car-#cat#-#sec#-1">
          <label for="car-#cat#-#sec#-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-#cat#-#sec#-2">
          <label for="car-#cat#-#sec#-2"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-#cat#-#sec#-3">
          <label for="car-#cat#-#sec#-3"><i class="icon-tick"></i></label>
        </li>
      </ul>

      <div class="footer">
        <span class="num"> Section #sec# </span>
      </div>
    </div>
  </div>

</div>

I hope it helps!

Takit Isy
  • 9,688
  • 3
  • 23
  • 47
  • Thank you very much @Takit. I've taken note of that. That's very nice on your side. Hopefully your solution will help other people out there too. Thanks. God bless you ! – crazydev May 22 '18 at 09:30