Martin
Martin

Reputation: 1

jquery checkbox prepend - works separately, but not when put together inside function

I`m new to javascript and jquery, but very eager to learn.

My end goal is to make a popup, in which a table of contents is displayed, with links, as is normal in a table of contents. This table of contents is called "Print adjust". just before every chapter headline inside the table of contents, I want a checkbox. If ticked, this checkbox will remove that chapter from the document. In addition, I want one checkbox that if ticked, ticks all the other checkboxes, and removes all chapters in the document. If all chapter specific checkboxes are checked, the master checkbox will be automatically checked. I have tested parts of the code separately, but have challenges when I put it into the "Print adjust" function. The table of contents is fully operational, checkboxes are diplayed in fromt of every headline inside the TOC, but when I expect the checkboc class "justone" to be inserted, the "class "Master" is inserted on every line - the master should only be one checkbox inside a separate div, and that should be the checkbox "to rule them all". This checkbox is not inserted at all, but all the other checkboxes get this class. In the div I want this checkbox, only text input fields are displayed - many of them.

If anybody can point me in the right direction, it would be much appreciated.

Here is the part of the function I`m struggling with:

var check= document.createElement ('input');
check.type= "checkbox";
check.id= "CHECK" + sectionNumber;
check.className="justone";

$("input[type='checkbox'].justone").change(function(){
    var a = $("input[type='checkbox'].justone");
    if(a.length == a.filter(":checked").length){
        $('.containerhideall').prop('checked', true);
    }
    else {
        $('.containerhideall').prop('checked', false);
    }
});

$('.justone').change(function(){
    if($('.justone:checked').length==0){
        $('#purpose_scope').show();
    }else{
        $('#purpose_scope').hide();
        $('.justone:checked').each(function(){
            $('#'+$(this).attr('data-ptag')).show();
        }) 
    }});

    var MASTERcheck= document.createElement ('input');
    MASTERcheck.type= "checkbox";
    MASTERcheck.id= "MASTER";
    MASTERcheck.className="containerhideall";
    MASTERcheck.innerHTML=sectionNumber;

    $('.containerhideall').click(function() {
    if ($(this).is(':checked')) {
        $('input:checkbox').prop('checked', true);
    } else {
        $('input:checkbox').prop('checked', false);
    }
});

$('.containerhideall').change(function(){
    if($('.containerhideall:checked').length==0){
        $('.screensteps-section').show();
    }else{
        $('.screensteps-section').hide();
        $('.containerhideall:checked').each(function(){
            $('#'+$(this).attr('data-ptag')).show();
        })
    }
});

$('.checkall').prepend (MASTERcheck);
    $('.PRINTEntry').each(function(n) {
    (this).prepend (check);
});

Upvotes: 0

Views: 81

Answers (1)

poorly-written-code
poorly-written-code

Reputation: 1073

Mutating variables can be tricky. Id suggest avoiding that where possible. Without seeing the rest of your code, it's hard to say exactly how you'd be best going about this. But I think this will point you in the right direction:

@media print {
  .hideFromPrint {
    display: none;
  }
}

<div class="TOC">
  <div class="chapter">
    <span>chapter 1</span>
  </div>
  <div class="chapter">
    <span>chapter 2</span>
  </div>
  <div class="chapter">
    <span>chapter 3</span>
  </div>
  <div class="footer">
    <input class="checkbox all hide-chapter" type="checkbox"><span>hide all chapters</span>
  </div>
</div>

$('<input class="checkbox single hide-chapter" type="checkbox">')
  .prependTo('.chapter')
  .on('click', function() {
    $(this)
      .closest('.chapter')
      .removeClass('hideFromPrint')
      .addClass(this.checked ? 'hideFromPrint' : '');
    $('.checkbox.all')
      .prop('checked', $('.checkbox.single').length === $('.checkbox.single:checked').length)
  });

$('.checkbox.all').on('click', function() {
    $('.checkbox.single').prop('checked', this.checked)
  });

https://jsfiddle.net/v1y92Lak/64/

Some things to note:

The single checkboxes are binded after they are dynamically added. jQuery doesn't work like css, that is, where css is applied to anything with the right class regardless of when it's added, jQuery can only work with what's currently in the DOM. It doesn't matter if you use a class that already has an event listener bound to it if the element didn't exist when you added the bind. I know this caught me up alot at first.

Rather than removing the chapters you don't want, I'm using a nifty css property that hides it from being printed. Theory being less DOM manipulation is better.

I'm using click rather than change to prevent issues with the checkboxes changing each other.

Upvotes: 0

Related Questions