Splitting an object and wrapping around x elements before and after
I have an array of JavaScript airports.
This array will be dynamically generated in PHP, so its length could potentially change. The only fixed variable I know of is how much to display on the screen at once. (8).
What I would like to do is build some function that takes in an array, and after every 8 wraps it in an element <li>
, which is then added to the existing <ul>
DOM element .
Example array =
var airports = [ //Array of airports, location ID/Display name
"<span data-aid='LON'>London - All</span>",
"<span data-aid='ABZ'>Aberdeen</span>",
"<span data-aid='BHD'>Belfast Harbour</span>",
"<span data-aid='BFS'>Belfast - International</span>",
"<span data-aid='BHX'>Birmingham</span>",
"<span data-aid='BOH'>Bournemouth</span>",
"<span data-aid='BRS'>Bristol</span>",
"<span data-aid='CWL'>Cardiff</span>",
"<span data-aid='EMA'>East Midlands</span>",
"<span data-aid='EDI'>Edinburgh</span>",
"<span data-aid='EXT'>Exeter</span>",
"<span data-aid='GLA'>Glasgow Intl</span>",
"<span data-aid='HUY'>Humberside</span>",
"<span data-aid='LBA'>Leeds Bradford</span>",
"<span data-aid='LPL'>Liverpool</span>",
"<span data-aid='LCY'>London - City</span>",
"<span data-aid='LGW'>London - Gatwick</span>",
"<span data-aid='LHR'>London - Heathrow</span>",
"<span data-aid='LTN'>London - Luton</span>",
"<span data-aid='SEN'>London - Southend</span>",
"<span data-aid='STN'>London - Stansted</span>",
"<span data-aid='QQS'>London - St Pancras</span>",
"<span data-aid='MAN'>Manchester</span>",
"<span data-aid='NCL'>Newcastle</span>",
"<span data-aid='NWI'>Norwich</span>",
"<span data-aid='SOU'>Southampton</span>"
];
Expected Result.
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li> <!-- Continues -->
The problem I foresee is how do you program in logic to add to the final </li>
if the list is not a multiple of eight?
source to share
Build <li>
, add it to <body>
, then add at most 8 of your <span>
s. After 8, add another one <li>
and add the next batch <span>
to a new one <li>
and continue this way. The rest <span>
will automatically end in the latter <li>
.
I've added some CSS for the demo for the effect. I hope you don't mind.
var airports = [ //Array of airports, location ID/Display name
"<span data-aid='LON'>London - All</span>",
"<span data-aid='ABZ'>Aberdeen</span>",
"<span data-aid='BHD'>Belfast Harbour</span>",
"<span data-aid='BFS'>Belfast - International</span>",
"<span data-aid='BHX'>Birmingham</span>",
"<span data-aid='BOH'>Bournemouth</span>",
"<span data-aid='BRS'>Bristol</span>",
"<span data-aid='CWL'>Cardiff</span>",
"<span data-aid='EMA'>East Midlands</span>",
"<span data-aid='EDI'>Edinburgh</span>",
"<span data-aid='EXT'>Exeter</span>",
"<span data-aid='GLA'>Glasgow Intl</span>",
"<span data-aid='HUY'>Humberside</span>",
"<span data-aid='LBA'>Leeds Bradford</span>",
"<span data-aid='LPL'>Liverpool</span>",
"<span data-aid='LCY'>London - City</span>",
"<span data-aid='LGW'>London - Gatwick</span>",
"<span data-aid='LHR'>London - Heathrow</span>",
"<span data-aid='LTN'>London - Luton</span>",
"<span data-aid='SEN'>London - Southend</span>",
"<span data-aid='STN'>London - Stansted</span>",
"<span data-aid='QQS'>London - St Pancras</span>",
"<span data-aid='MAN'>Manchester</span>",
"<span data-aid='NCL'>Newcastle</span>",
"<span data-aid='NWI'>Norwich</span>",
"<span data-aid='SOU'>Southampton</span>"
];
var container = $("body");
var wrapAt = 8;
var currLi = $("<li>");
container.append(currLi);
for (var i = 0; i < airports.length; i++) {
currLi.append(airports[i]);
if ((i + 1) % wrapAt == 0) {
currLi = $("<li>");
container.append(currLi);
}
}
span {
margin: 5px;
background-color: lightblue;
}
li {
min-width: 1000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
source to share
Try it ( http://jsfiddle.net/sergdenisov/c855rzx6/ ):
var airports = [ //Array of airports, location ID/Display name
"<span data-aid='LON'>London - All</span>",
"<span data-aid='ABZ'>Aberdeen</span>",
"<span data-aid='BHD'>Belfast Harbour</span>",
"<span data-aid='BFS'>Belfast - International</span>",
"<span data-aid='BHX'>Birmingham</span>",
"<span data-aid='BOH'>Bournemouth</span>",
"<span data-aid='BRS'>Bristol</span>",
"<span data-aid='CWL'>Cardiff</span>",
"<span data-aid='EMA'>East Midlands</span>",
"<span data-aid='EDI'>Edinburgh</span>",
"<span data-aid='EXT'>Exeter</span>",
"<span data-aid='GLA'>Glasgow Intl</span>",
"<span data-aid='HUY'>Humberside</span>",
"<span data-aid='LBA'>Leeds Bradford</span>",
"<span data-aid='LPL'>Liverpool</span>",
"<span data-aid='LCY'>London - City</span>",
"<span data-aid='LGW'>London - Gatwick</span>",
"<span data-aid='LHR'>London - Heathrow</span>",
"<span data-aid='LTN'>London - Luton</span>",
"<span data-aid='SEN'>London - Southend</span>",
"<span data-aid='STN'>London - Stansted</span>",
"<span data-aid='QQS'>London - St Pancras</span>",
"<span data-aid='MAN'>Manchester</span>",
"<span data-aid='NCL'>Newcastle</span>",
"<span data-aid='NWI'>Norwich</span>",
"<span data-aid='SOU'>Southampton</span>"
];
processAirports(airports);
function processAirports(arr) {
if (!arr.length) {
return;
}
var $container = $('.js-container');
var count = 0;
var $li;
for (var i = 0; i < arr.length; i++) {
$li = (count === 0) ? $('<li></li>') : $li;
$li.append(arr[i]);
if (count === 7) {
$container.append($li);
count = 0;
continue;
}
count++;
}
}
source to share
One approach to your problem:
// a named function taking two arguments,
// n, Number or String: defining the group-size,
// arr, Array: the array whose elements you want
// to group together
function groupsOf(n, arr) {
// if n is undefined, we use the default of 8,
// otherwise we call parseInt() to ensure the
// we have a number (this is a naive check, as
// we're not checking that the supplied argument is
// either a Number or String; nor are we validating
// the existence of the Array):
n = 'undefined' === typeof n ? 8 : parseInt(n, 10);
// initialising an array to hold the grouped elements:
var grouped = [];
// iterating over the supplied Array, using
// Array.prototype.forEach():
arr.forEach(function(arrayElem, index) {
// the first variable (here: 'arrayElem') is the current
// array-element of the array over which we're iterating,
// the second (here: 'index') is the index of the current
// array-element from the array over which we're iterating.
// if the remainder of the index divided by the group-size
// is not zero, we add the current array-element to the
// last child-array of the grouped array:
if (index % n !== 0) {
grouped[grouped.length - 1].push(arrayElem);
} else {
// otherwise we add a new child-array, containing
// the current array-element, to that grouped array:
grouped.push([arrayElem]);
}
});
// returning the grouped array:
return grouped;
}
var airports = [/* array removed for brevity */]
// a reference to the element to which we're adding the groups:
var list = document.getElementById('airports'),
// creating an <li> element:
li = document.createElement('li'),
// creating a document fragment:
fragment = document.createDocumentFragment(),
// creating an 'empty' variable for use within the
// (later) loop:
clone;
// calling the function, iterative over the the returned array:
groupsOf(8, airports).forEach(function(group) {
// cloning the created <li>, storing it in the clone variable:
clone = li.cloneNode();
// setting the innerHTML of the clone to the joined together
// string of HTML held within the current array-element,
// using Array.prototype.join():
clone.innerHTML = group.join('');
// appending the clone to the document fragment:
fragment.appendChild(clone);
});
// appending the document fragment to the list element:
list.appendChild(fragment);
function groupsOf(n, arr) {
n = 'undefined' === typeof n ? 8 : parseInt(n, 10);
var grouped = [];
arr.forEach(function(arrayElem, index) {
if ((index) % n !== 0) {
grouped[grouped.length - 1].push(arrayElem);
} else {
grouped.push([arrayElem]);
}
});
return grouped;
}
var airports = [ //Array of airports, location ID/Display name
"<span data-aid='LON'>London - All</span>",
"<span data-aid='ABZ'>Aberdeen</span>",
"<span data-aid='BHD'>Belfast Harbour</span>",
"<span data-aid='BFS'>Belfast - International</span>",
"<span data-aid='BHX'>Birmingham</span>",
"<span data-aid='BOH'>Bournemouth</span>",
"<span data-aid='BRS'>Bristol</span>",
"<span data-aid='CWL'>Cardiff</span>",
"<span data-aid='EMA'>East Midlands</span>",
"<span data-aid='EDI'>Edinburgh</span>",
"<span data-aid='EXT'>Exeter</span>",
"<span data-aid='GLA'>Glasgow Intl</span>",
"<span data-aid='HUY'>Humberside</span>",
"<span data-aid='LBA'>Leeds Bradford</span>",
"<span data-aid='LPL'>Liverpool</span>",
"<span data-aid='LCY'>London - City</span>",
"<span data-aid='LGW'>London - Gatwick</span>",
"<span data-aid='LHR'>London - Heathrow</span>",
"<span data-aid='LTN'>London - Luton</span>",
"<span data-aid='SEN'>London - Southend</span>",
"<span data-aid='STN'>London - Stansted</span>",
"<span data-aid='QQS'>London - St Pancras</span>",
"<span data-aid='MAN'>Manchester</span>",
"<span data-aid='NCL'>Newcastle</span>",
"<span data-aid='NWI'>Norwich</span>",
"<span data-aid='SOU'>Southampton</span>"
];
var list = document.getElementById('airports'),
li = document.createElement('li'),
fragment = document.createDocumentFragment(),
clone;
groupsOf(8, airports).forEach(function(group) {
clone = li.cloneNode();
clone.innerHTML = group.join('');
fragment.appendChild(clone);
});
list.appendChild(fragment);
li {
margin: 0 0 0.5em 0;
width: 80%;
counter-reset: spanCount;
}
span {
display: inline-block;
box-sizing: border-box;
width: 50%;
border: 1px solid #000;
counter-increment: spanCount;
}
span::before {
content: counter(spanCount);
color: #f90;
margin-right: 0.2em;
}
<ul id="airports"></ul>
Literature:
source to share