0

I'm setting up a website with div filters and want to count div's dynamically depending on filter sets.

This code works fine but do not react dynamically on filter changes...

$('.detail').each(function(i) { 
    var n = $(this).children('.box').length;
    $(".countDiv"+i).text("There are " + n + " divs inside parent box detail.");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content-body" class="clearfix">

<!-- detail div no 1 = 3 items inside -->
    <span class="countDiv0"></span> 
    <div class="detail">
        <div class="box">
            Div item 1
        </div>
        <div class="box">
            Div item 2
        </div>
        <div class="box">
            Div item 3
        </div>
    </div>
    <br /><br />
    <!-- detail div no 1 = 4 items inside -->
    <span class="countDiv1"></span> 
    <div class="detail">
        <div class="box">
            Div item 1
        </div>
        <div class="box">
            Div item 2
        </div>
        <div class="box">
            Div item 3
        </div>
        <div class="box">
            Div item 4
        </div>
    </div>

</div>

Can anybody help?

DaFois
  • 2,197
  • 8
  • 26
  • 43
  • 1
    The totals in your example look ok. So what do you mean by "do not react dynamically on filter changes" What kind of filter changes? Can you add a "filter change" to your example? – Wyck Jun 02 '19 at 14:09
  • Hi Wyck, please have a look on example here: http://remos.schalganfallrehabilitation.de and have a look on the comment below I wrote Thameen... – Jakob Tiebel Jun 03 '19 at 14:16

3 Answers3

0

well, too answer properly we would need to see the code that is performing the filter action. anyway, what you need to do is to encapsulate your code in a function and call that function whenever you are done filtering. example:

function countDivs() {
  //your code here for counting the divs
}

function filterAction() {
  //your code here that filters and creates the divs dynamically
  countDivs()
}
folo
  • 476
  • 4
  • 5
0

$(document).ready(function(){
$("#btnCreate").click(function(){
$('.detail').append("<div class='box'>Div item n</div>");
});
});

$("body").on('DOMSubtreeModified', ".detail", function() {
    $('.detail').each(function(i) { 
    var n = $(this).children('.box').length;
    $(".countDiv"+i).text("There are " + n + " divs inside parent box detail.");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content-body" class="clearfix">

<!-- detail div no 1 = 3 items inside -->
    <span class="countDiv0"></span> 
    <div class="detail">
        <div class="box">
            Div item 1
        </div>
        <div class="box">
            Div item 2
        </div>
        <div class="box">
            Div item 3
        </div>
    </div>
    <br /><br />
    <!-- detail div no 1 = 4 items inside -->
    <span class="countDiv1"></span> 
    <div class="detail">
        <div class="box">
            Div item 1
        </div>
        <div class="box">
            Div item 2
        </div>
        <div class="box">
            Div item 3
        </div>
        <div class="box">
            Div item 4
        </div>
    </div>
</div>
<div>
<button type="button" id="btnCreate">Create a new div inside detail div</button>
</div>

I can't understand what you mean by filter changes. What i understood was any changes made to the document DOM. If so then you need to bind the DivCount event like @folo(above) said to an event such as this..

$("body").on('DOMSubtreeModified', "mydiv", function() {
    //countDiv();
});

Refer to this link

I have update my answer. please check Please do the numbering as i have used n.

Thameem
  • 700
  • 1
  • 13
  • 38
  • Hi Thameen, can you show me how to combine your example with the example: above $('.detail').each(function(i) { var n = $(this).children('.box').length; $(".countDiv"+i).text("There are " + n + " divs inside parent box detail."); }); – Jakob Tiebel Jun 02 '19 at 11:20
  • I have updated my answer. Please check now. Sorry for late. – Thameem Jun 02 '19 at 14:05
  • Hi Thameen, I tried it but it didn't work. However, I found a way using `setInterval(function() { my-count-div-function }, 1000);` So far so good. Now I can show the number of visible div's in status bar on top of my open accordion container. See example on http://remos.schlaganfallrehabilitation.de And after changing filter settings (when the number of shown divs shrinks) the value changes dynamically. But how can I show the filtered number of divs in my accordion when hidden? can't find a solution because filters hide the divs as well. Seems to be impossible to differentiate. – Jakob Tiebel Jun 03 '19 at 14:12
  • Good work. The example was not clear to me. However to count / ignore hidden divs you can check for the visibility property or CSS - display:none property. But still am not clear. Need to see the complete source code for clear understanding. – Thameem Jun 03 '19 at 15:00
0

you can use mutation observer to listen on changes of children under your detail. more info about mutation can be found here https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver.

for your case, you can add that in the code inside each

1) add observer that takes care of dom changes

function createObserver(targetNode, cb) {
  const config = { childList: true };

  // Callback function to execute when mutations are observed
  const callback = function(mutationsList, observer) {
    for (var mutation of mutationsList) {
      if (mutation.type == 'childList') {
        cb();
      }
    }
  };

  // Create an observer instance linked to the callback function
  var observer = new MutationObserver(callback);

  // Start observing the target node for configured mutations
  observer.observe(targetNode, config);
}

2) hook that into your counting logic

$('.detail').each(function(i) {
  const targetNode = this;
  const countingDiv = $('.countDiv' + i);
  const cb = () =>
  countingDiv.text(
    `There are ${
      $(targetNode).children('.box').length
    } divs inside parent box detail.`
  );
  cb();
  createObserver(targetNode, cb);
});

you can see it in action here http://jsfiddle.net/sq5cd3rh/4/

duc mai
  • 1,412
  • 2
  • 10
  • 17