Loop over data and create html elements with data - javascript

I am fetching json data from a php script and attempting to display the data on a webpage. The issue I am having is I want to limit the number of < li > tags in a < ul >, if the limit is met then I want to create a new < ul > element.
JSON:
[{"mDescription":"Red Widget","mReference":"rwid"},{"mDescription":"Blue Widget","mReference":"bwid"},{"mDescription":"Yellow Widget","mReference":"ywid"},{"mDescription":"Orange Widget","mReference":"owid"},{"mDescription":"Green Widget","mReference":"gwid"},{"mDescription":"Black Widget","mReference":"bwid"},{"mDescription":"White Widget","mReference":"wwid"}]
I have attempted looping but I'm getting odd results, code:
function getWidgetList() {
let widgetListURL = 'php/list.php';
fetch(widgetListURL)
.then((response) => response.json())
.then((data) => {
let html = '';
html += `<ul class="col-sm-2 list-unstyled"><li><p class="title">Widgets:</p></li>`;
let counter = 0;
let limit = 3;
for (let key in data) {
let widget = data[key];
html += '<li data-desk="' + widget.mReference + '"><a><span class="d-title">' + widget['mDescription'] + '</span></a></li>';
if (++counter > limit) {
html += `</ul><ul class="col-sm-2 list-unstyled">
<li><p class="title">Widgets:</p></li>`;
counter = 0;
}
}
html += `</ul>`;
//byID('widgetList').innerHTML(html);
console.log(html);
})
}
Result:
<ul class="col-sm-2 list-unstyled"><li><p class="title">Widget:</p></li>
<li data-desk="rwid"><a><span class="d-title">Red Widget</span></a></li>
<li data-desk="bwid"><a><span class="d-title">Blue Widget</span></a></li>
<li data-desk="ywid"><a><span class="d-title">Yellow Widget</span></a></li>
<li data-desk="owid"><a><span class="d-title">Orange Widget</span></a></li>
</ul>
<ul class="col-sm-2 list-unstyled"><li><p class="title">Widget:</p></li>
<li data-desk="gwid"><a><span class="d-title">Green Widget</span></a></li>
</ul>
<ul class="col-sm-2 list-unstyled"><li><p class="title">Widget:</p></li>
<li data-desk="bwid"><a><span class="d-title">Black Widget</span></a></li>
</ul>
<ul class="col-sm-2 list-unstyled"><li><p class="title">Widget:</p></li>
<li data-desk="wwid"><a><span class="d-title">White Widget</span></a></li>
</ul>
I am trying to complete this task using modern JavaScript and no JQuery. Any Help would be greatly appreciated.

The best way to do this is to use the modulo operater:
let liTagLimit = 3;
let index = 0;
let html = '<ul id="first-ul">';
for(let key in data){
//...create li
index++;
if(index % liTagLimit == 0){//<----- HERE IS THE TRICK
html += "</ul><ul>";
}
html += '</ul>';

you can use forEach with index.
html += '<ul class="col-sm-2 list-unstyled"><li><p class="title">Widgets:</p></li>';
data.forEach((widget,i)=>{
if (i != 0 && (i % limit == 0)) {
html += '</ul><ul class="col-sm-2 list-unstyled"><li><p class="title">Widgets:</p></li>';
}
html += '<li data-desk="' + widget.mReference + '"><a><span class="d-title">' + widget['mDescription'] + '</span></a></li>';
}
)
html += '</ul>';

Related

Alternative ways to dynamically create li elements

Using JavaScript, I need to dynamically create a list like this:
<ul id="list">
<li>2015</li>
<li>2016</li>
<li>2017</li>
<li>2018</li>
<li>2019</li>
<li>2020</li>
</ul>
The "classic solution" (as far as I know) is:
for (var i = 2015; i <= 2020; i++) {
var li = document.createElement("li");
li.innerHTML = i;
list.appendChild(li);
}
It works perfectly.
But I would like to find alternative, better - in terms of performance - solutions, if there are (I want to learn something more).
So I tried:
for (var i = 2015; i <= 2020; i++) {
var el = "<li>" + i + "</li>";
list.insertAdjacentHTML('beforeend', el);
console.log(el);
el += el;
}
<ul id="list"></ul>
AND
for (var i = 2015; i <= 2020; i++) {
var el = "<li>" + i + "</li>";
list.innerHTML += el;
console.log(el);
}
<ul id="list"></ul>
But in both cases this is the result:
in the DOM:
<ul id="list">
<li>2015</li>
<li></li>
<li>2016</li>
<li></li>
<li>2017</li>
<li></li>
<li>2018</li>
<li></li>
<li>2019</li>
<li></li>
<li>2020</li>
<li></li>
</ul>
while in the console:
<li>2015<li>
<li>2016<li>
<li>2017<li>
<li>2018<li>
<li>2019<li>
<li>2020<li>
Why those empty nodes (<li></li>)? And why in the DOM only?
In both you added "<li>" + i + "<li>" instead of "<li>" + i + "</li>"
Missing slash small thing, but user agents are prepared to fix missing closing... and your code appeared with doubled li

Loop of html using javascript

i am new on using of JavaScript on looping of html. I have this code below that i am working at. In this problem of mine i have 2 loop the main and the card-body loop. As you can see in the code First I need to loop the main to create a card and then at the body i need also to loop it because of the data content. I have also working code below but as you can see at the card-body its not looping anymore but static data that I inputted.
Problem
for (var i = 0; i < dataLength; i++) {
var docsLength = data.data[i].resultData;
var title = data.data[i].resultData[i].Type.Description;
var card = '<div class="card"> <div class="card-header bg-success"><h3 class="card-title">' + title + ' </h3 ></div> <div class="card-body">'; for (var a = 0; a < 2; a++) { "a" } ' </div>' +
'</div >';
$("#card_documents > .card-body").append(card);
}
Working
for (var i = 0; i < dataLength; i++) {
var docsLength = data.data[i].resultData;
var title = data.data[i].resultData[i].Type.Description;
var card = '<div class="card"> <div class="card-header bg-success"><h3 class="card-title">' + title + ' </h3 ></div> <div class="card-body">' +
"asdasdasdasd" +
'</div > ' +
'</div >';
$("#card_documents > .card-body").append(card);
}
Is my syntax wrong?. Please help. Thanks
You can replace for (var a = 0; a < 2; a++) { "a" } with "a".repeat(2).
More info about repeat() here
Yes, your syntax is wrong. Specifically the way you're trying to use the for loop.
I would suggest building up the string in a variable.
Here is a stripped down version of how you might achieve that.
var card = '<div class="card">';
for (var a = 0; a < 2; a++) {
card += "a";
}
card += '</div>';
$("#card_documents > .card-body").append(card);

Create second or next <li> under default <li> after reload page | jQuery, LocalStorage

I try to create LocalStorage data for My Folder Creation .
HTML :
This is my default li. I call it All audience folder's
<!-- Result goes here -->
<ul class="nav">
<li>
<div class="zf-folder" style="width: 232px;">
<div class="_tabFolder _itemPosition" style="height: 50px;border-bottom:1px groove; user-select: none;">
<div class="_sideFolder"></div>
<div class="_iconText" style="width: 215px">
<div class="ellipsis">
<div class="_1i5w">
<div class="_icon-col">
</div>
</div>
All Audiences<span class="hyperspan" style="position:absolute; width:100%; height:100%; left:0; top:0;"></span>
</div>
</div>
</div>
</div>
</li>
</ul>
jQuery :
var count = 1;
$(".submitButton").click(function() {
let label = count++;
// make a function that returns the DOM with updated count
function getNewList(foldername) {
var addFolder = '<li>' +
'<div class="zf-folder" style="width: 232px;">' +
'<div class="_tabFolder _itemPosition" style="height: 50px;border-bottom:1px groove; user-select: none;">' +
'<div class="_sideFolder"></div>' +
'<div class="_iconText" style="width: 215px">' +
'<div class="ellipsis">' +
'<div class="_iconFolder">' +
'<div class="_icon-col">' +
'</div>' +
'</div>' +
'<a href="#folder' + label +
'" data-toggle="tab" style="text-decoration: none;">' +
foldername + '<span class="hyperspan" style="width:100%; height:100%; left:0; top:0;"></span></a>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</li>';
return addFolder;
}
var inputan = $("#input_nameFolder").val();
// update the result array
var result = JSON.parse(localStorage.getItem("folderList"));
if (result == null) {
result = [];
}
let newfolderHTML = getNewList(inputan);
result.push({
folder: newfolderHTML
});
// save the new result array
localStorage.setItem("folderList", JSON.stringify(result));
// append the new li
$(".nav").append(newfolderHTML); // i want include myDiv
//clear input
$("#input_nameFolder").val('');
});
// on init fill the ul
var result = JSON.parse(localStorage.getItem("folderList"));
if (result != null) {
//get the nav reference in DOM
let nav = $(".nav");
//clear the html contents
nav.html('');
for (var i = 0; i < result.length; i++) {
var item = result[i];
$(".nav").append(item.folder);
}
}
How to adding new <li> tag under my default li (all audience)
after reload page/click run jsfiddle when user input a new value?
You can see after adding an input and reload web / jsfiddle, new input folder's (second li) overwrite all audience (first li).
JSFiddle
you just have to save the initial element upon initialization, see:
// on init fill the ul
var result = JSON.parse(localStorage.getItem("folderList"));
if (result != null) {
//get the nav reference in DOM
let nav = $(".nav");
//clear the html contents
nav.html('');
for (var i = 0; i < result.length; i++) {
var item = result[i];
$(".nav").append(item.folder);
}
} else {
//Save the "All Audiences" content upon empty folderList
let initialElement = [];
initialElement.push({
folder: $('ul.nav').html()
});
localStorage.setItem("folderList", JSON.stringify(initialElement));
}
See: JSFiddle

Get text and id value from li

I've been stuck in this stupid situation, i got an unorder list like this:
var liList = $("#first").find("li");
var append = "";
for(var i =0; i< liList.length; i++){
var item = $(liList);
append += "<option value=" + item.prop("id") + ">" + item.text() + "</option";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="first">
<li id=1>
li 1
<ul>
<li id=2> li 2</li>
</ul>
</li>
</ul>
I want to get the text and id for each li in unorder list, but in the item.text() code part i got the current li text and the childrens text ("li1li2", "li2", etc). Any suggestion?.
Regards
You can get the value first node from a DOM element (which happens to be text in your case) with .childNodes[0].nodeValue:
append += "<option value=" + item.prop("id") + ">" + item[0].childNodes[0].nodeValue + "</option";
Since liList is an array containing all the li elements you must iterate over every element inside you loop:
for(var i = 0; i < liList.length; i++) {
// retreive each element from the array
var item = $(liList[i]);
append += "<option value=" + item.prop("id") + ">" + item.text() + "</option>";
}

BootstrapJS - Nav Nav-list not collapsing on click.

Stumped on another one. I'm using boostrapJS to create a Nav-List. Ideally the headers will remain collapsed by default, but will expand when clicked. Right now I have some javascript that will go and dynamically populate the List, but the click event seems to be doing nothing. (sort of - I click on the header and it jitters a bit, but it does not collapse).
I've looked at the code examples, and I'm pretty sure I'm using the same classes and div structure, but It still seems to be not working, and it's not throwing any errors.
Here is my Code:
$('#header').append('<ul class="nav nav-list">');
for (i = 0; i < len; i++) {
k = keys[i];
$('#header').append('<label class="tree-toggle nav-header">' + keys[i] + '</label>');
for (var j in groupedtemplates[k]) {
$('#header').append('<li data-value=' + groupedtemplates[k][j].id + '>' + groupedtemplates[k][j].attributes.im_name.value + '</li>');
}
}
$('#header').append('</ul>');
$(document).ready(function () {
$('.tree-toggle').click(function () {
$(this).parent().children('ul.tree').toggle(200);
});
});
The HTML that it's being inserted into is just a simple container.
<div class="well" style="width:100%; padding: 8px 0;" id="header">
</div>
Figured it out.
When you append a tag without a closing tag, the browser inserts one for you. Because of this the objects were not appearing as children.
This is my revised solution that puts all the data to be appended in a variable, then appends it afterwards.
for (i = 0; i < len; i++) {
k = keys[i];
var toAppend = "";
toAppend = toAppend + '<ul class="nav nav-list">' + '<li><label class="tree-toggle nav-header">' + keys[i] + '</label</li>' + '<ul class="nav nav-list tree">'
for (var j in groupedtemplates[k]) {
toAppend = toAppend + '<li data-value=' + groupedtemplates[k][j].id + '>' + groupedtemplates[k][j].attributes.im_name.value + '</li>'
}
toAppend = toAppend + "</ul></ul>";
$('#header').append(toAppend);
}

Categories

Resources