mpdc mpdc - 4 months ago 10
jQuery Question

Dynamically insert HTML after page load (and change after key press)

When my page loads, content is pulled from a database with PHP and populated within numerous Bootstrap

.col-xs-3
columns, all within a single
.row
.

However, I need to close off the
.row
and start a new one every four columns using JavaScript/jQuery after the page has loaded and also on
keyup
, inserting the relevant HTML to the code where it needs to go. This is because the amount of content on the page can change dynamically depending on user input within a search bar (which hides certain columns).

The HTML structure of my page is as follows:

<input id="search" type="text">

<div class="row">
<div class="col-xs-3 col-flex">1</div>
<div class="col-xs-3 col-flex">2</div>
<div class="col-xs-3 col-flex">3</div>
<div class="col-xs-3 col-flex">4</div>
<div class="col-xs-3 col-flex">5</div>
<div class="col-xs-3 col-flex">6</div>
</div>


Whereas I need it like so:

<input id="search" type="text">

<div class="row">
<div class="col-xs-3 col-flex">1</div>
<div class="col-xs-3 col-flex">2</div>
<div class="col-xs-3 col-flex">3</div>
<div class="col-xs-3 col-flex">4</div>
</div>
<div class="row">
<div class="col-xs-3 col-flex">5</div>
<div class="col-xs-3 col-flex">6</div>
</div>


However, I cannot hard code the new rows with PHP, because user input in the search bar might change the visible page content to the following, and I need the rows to close in the correct places dynamically (note how
4
is missing):

<input id="search" type="text">

<div class="row">
<div class="col-xs-3 col-flex">1</div>
<div class="col-xs-3 col-flex">2</div>
<div class="col-xs-3 col-flex">3</div>
<div class="col-xs-3 col-flex">5</div>
</div>
<div class="row">
<div class="col-xs-3 col-flex">6</div>
</div>


This is my jQuery right now, but it does not seem to be working:

$(document).ready(function() {
function rowBreak() {
var columnCount = 0;
$('col-flex:visible').each(function() {
columnCount++;
if (columnCount % 4 == 0) {
$(this).append('</div><div class="row">');
}
});
}
rowBreak();
$("#search").on("keyup", function() {
rowBreak();
});
});


EDIT: And I've just realised, my code does not even take in to account the removal of additional rows before re-adding them in the correct places each key press...

Answer

Another approach is based on the fix of the following line:

$(this).append('</div><div class="row">');

This line should be:

var nextEles = $('.col-flex:hidden:gt(' + index + ')');
$('<div class="row">').append(nextEles).insertAfter(this.closest('div.row'));

Mainly, your variable columnCount is not usefull. Take a look to each parameters.

My snippet:

function rowBreak() {
  $('.col-flex:hidden').each(function (i, e) {
    if (((i + 1) % 4 == 0) && ($(this).siblings().length != 3)) {
      var x = $('.col-flex:hidden:gt(' + i + ')');
      $('<div class="row row-temp">').append(x).insertAfter(this.closest('div.row'));
    }
  });
}

$(function () {
  
  $('.col-flex').hide();
  rowBreak();
  $('.col-flex').show();
  
  
  $('#search').on('keyup', function () {
    $('.col-flex').hide();
    var s = this.value.toLowerCase();
    $('.col-flex').filter(function () {
      return $(this).find('h4').text().toLowerCase().indexOf(s) > -1;
    }).show();
    rowBreak();
  });

});
body {
  padding: 10px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>




<div class="form-group">
    <input class="form-control" id="search" placeholder="Search...">
</div>
<div class="row">
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">AECLIM</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">AEMET</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">AME</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">APMG</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">ATCN</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">METEOMET</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">MMC 2016</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
    <div class="col-xs-3 col-flex">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">SATCOM 2016</h4>
            </div>
            <div class="panel-body">
            </div>
        </div>
    </div>
</div>

Comments