How to count the number of divs shown on each line when it depends on the screen resolution

I have the following code:

Html

<div class="content" style="height: 30px;">
    <div class="content-box" id="myOptions">
        <div class="options-holder">
            <input type="checkbox" name="11111" id="Bob_111">
            <label for="111">Alex_1</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="22222" id="Bob_222">
            <label for="222">Alex_2</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="33333" id="Bob_333">
            <label for="333">Alex_3</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="44444" id="Bob_444">
            <label for="444">Alex_4</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="55555" id="Bob_555">
            <label for="555">Alex_5</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="66666" id="Bob_666">
            <label for="666">Alex_6</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="77777" id="Bob_777">
            <label for="777">Alex_7</label>
        </div>
        <div class="options-holder">
            <input type="checkbox" name="88888" id="Bob_888">
            <label for="888">Alex_8</label>
        </div>
    </div>
</div>
<div class="button-wrapper"> <a href="#" class="toggle-trigger" id="showMoreButton" style="display:none;">
    <span data-collapse-text="Show less" data-expand-text="Show more" class="state up">Show more</span></a>
</div>

      

JAVASCRIPT

$.fn.myToggle = function () {
    return this.each(function () {
        var targetContainer = $(this),
            targetBox = targetContainer.find('.content'),
            targetTrigger = targetContainer.find('.toggle-trigger'),
            targetState = targetTrigger.find('.state'),
            contentBox = targetBox.find('.content-box'),
            boxHeight = contentBox.outerHeight(),
            optionHeight = targetBox.find('.options-holder').outerHeight();
        $(window).on('resize', function () {
            boxHeight = contentBox.outerHeight();
            if (targetState.hasClass('down')) {
                targetBox.stop(true, false).animate({
                    height: boxHeight
                });
            }
        });
        targetTrigger.on('tap', function () {
            targetBox.stop(true, false);
            if (targetState.hasClass('down')) {
                targetState.text(targetState.data('expand-text'));
                targetBox.animate({
                    height: optionHeight
                });
            } else {
                targetState.text(targetState.data('collapse-text'));
                targetBox.animate({
                    height: boxHeight
                });
            }
            targetState.toggleClass('up down');
            return false;
        });
    });
};
$(this.el).myToggle().on('click', '.checkbox-toggle', function (event) {
    var toggle = $(this),
        container = toggle.closest('.option-filter');

    event.preventDefault();
    container.find(':checkbox').prop('checked', toggle.hasClass('all'));
});

      

The problem is that the divs .option-holder

do not fit in just one line of my div .content-box

, so I need to hide them and create a show more / less button to show or hide the rest.

Everything works fine until I only have a certain number of divs .option-holder

to fit only one line, so I don't need a toggle button (the number of divs comes dynamically from the server).

My current solution is to count the number of divs and only show the toggle button if there are more than 4 of them (in most screen resolutions I get 4 divs per line). The problem is the screen resolution is bigger and I get 5 or 6 lines.

If I have 6 divs per line, but only 5 divs to show, then the button still exists because I am showing it after 4 divs.

I know there are many simple fixes, but I am not allowed to rewrite the code and change its logic, so I need to find a way to count the number of divs each time in a row.

Now the code only works by changing the height on the div .content

every time I click the button to show or hide the rest of the divs, preventing the divs from "not showing" any additional attributes for example. style="display: none;

to work with.

before toggle

after toggle

Any suggestions

+3


source to share


2 answers


var divs = document.querySelectorAll('.options-holder'); //or getElementsByClassName... or just $('.options-holder').....
var x = divs.length;
var number_of_elements_in_first_row = 0;
for ( var i = 0; i < x; i++;) {
    if ( divs[0].offsetHeight !== divs[i].offsetHeight ) {
        divs[i].style.display = "none"; // hide divs[i]
        /* or if you need only number of elements per row
           add this instead hiding elements */
        number_of_elements_in_first_row = i;
        break;
    }
}

if ( divs[0].offsetHeight !== divs[x].offsetHeight )
    // add/show your MORE button... your function call

      

So the basic idea is that if you have more than one line, the last element will have a different vertical position.



Editorial: This code will loop through the target div array and hide all divs that are not vertically aligned with the first. This is not a complete solution, but more an idea of ​​how to deal with this problem.

+4


source


var divs = $('.options-holder');

for(var key in divs){
    if (key > 0){
        if (divs[0].offsetLeft == divs[key].offsetLeft) {
            $("#showMoreButton").css("display", "block");
        }
    }
}

      



This is a necessary solution as .offsetLeft

it's the same in every first div on every line.

+1


source







All Articles