Get text and id value from li - javascript

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>";
}

Related

Convert string to HTML element using JavaScript or jQuery

I have a string like this:
i1:1,i3:5,i2:5
How can I convert it to a HTML element like this using pure JavaScript or jQuery?
<ul>
<li id="i1" value="1"></li>
<li id="i3" value="5"></li>
<li id="i2" value="5"></li>
</ul>
What I have tried so far:
document.write('<ul>i1:1,i3:5,i2:5</ul>');
split the initial string on the comma, then map over the resulting array. On each iteration of map you can then split on the colon, and return a HTML string. You just need to make sure you join the array that map returns into a new string before you add it to the DOM.
const str = 'i1:1,i3:5,i2:5';
const result = str.split(',').map(el => {
const [key, value] = el.split(':');
return `<li id="${key}" value="${value}">${value}</li>`;
}).join('');
const ol = document.querySelector('ol');
ol.insertAdjacentHTML('beforeend', `<ul>${result}</ul>`);
<ol />
Additional documentation
Destructuring assignment
Template literals
insertAdjacentHTML
I believe that my simple solution using method forEach() and method split() will not be superfluous, which will split the string into an id and a value taken from an array of similar data.
let ul = document.createElement("ul");
document.body.appendChild(ul);
["i1:1", "i3:5", "i2:5"].forEach(function (li) {
let id_value = li.split(":");
ul.innerHTML += "<li id=" + id_value[0] + ">" + id_value[1] + "</li>";
});
console.log(ul.outerHTML);
With jQuery:
function createUlListByString(myString) {
var elements = myString.split(',');
var ul = $('<ul>');
elements.forEach(function(item) {
item = item.split(':');
var li = $('<li id="' + item[0] + '" value="' + item[1] +'">'+ item[1] + '</li>');
ul.append(li);
});
return ul;
}
var ul = createUlListByString('i1:1,i3:5,i2:5');
Vanilla JavaScript:
function createUlListByString(myString) {
var elements = myString.split(',');
var ul = document.createElement('ul');
elements.forEach(function(item) {
item = item.split(':');
var li = document.createElement('li');
li.id = item[0];
li.value = item[1];
ul.append(li);
});
return ul;
}
var ul = createUlListByString('i1:1,i3:5,i2:5');

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

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);
}

Display the checkboxes selected into a section and the unselected into another one

I want to show the checkboxes selected into a div but actually I have a duplicate item in the list and I'm not sure how to display the unselected items into another div.
You can try out here http://jsfiddle.net/tedjimenez/7wzR5/
Here my code:
JS CODE
/* Array */
var list = new Array("valuetext000", "valuetext001", "valuetext002", "valuetext003", "valuetext004", "valuetext005", "valuetext006", "valuetext007", "valuetext008", "valuetext009", "valuetext010", "valuetext011", "valuetext012", "valuetext013", "valuetext014", "valuetext015", "valuetext016", "valuetext017")
var html = "";
/* Array will be converted to an ul list */
for (var i = 0; i < list.length; i++) {
html += "<input type='checkbox' name='boxvalue' value='" + list[i] + "' /><label>" + list[i] + "</label><br>";
}
$("#elmAv").append(html);
THE HTML CODE
<form>
<div id="elmAv"></div>
<div id="selectionResult"></div>
<script>
/* Function to display the items selected */
function showBoxes(frm) {
var checkedItems = "\n";
//For each checkbox see if it has been checked, record the value.
for (i = 0; i < frm.boxvalue.length; i++) {
if (frm.boxvalue[i].checked) {
checkedItems = checkedItems + "<li>" + frm.boxvalue[i].value + "<li>";
}
}
$("#elmAv").empty();
$("#selectionResult").append(checkedItems);
}
</script>
<input type="Button" value="Get Selection" onClick="showBoxes(this.form)" />
</form>
Simply add another div after selectionResult like this:
<div id="unselectedResult"></div>
And then update showBoxes() with the following code:
function showBoxes(frm) {
var checkedItems = "Checked:<br>\n";
var uncheckedItems = "Unchecked:<br>\n";
//For each checkbox see if it has been checked, record the value.
for (i = 0; i < frm.boxvalue.length; i++) {
if (frm.boxvalue[i].checked) {
checkedItems = checkedItems + "<li>" + frm.boxvalue[i].value + "</li>";
}
else {
uncheckedItems = uncheckedItems + "<li>" + frm.boxvalue[i].value + "</li>";
}
}
$("#elmAv").empty();
$("#selectionResult").append(checkedItems);
$('#unselectedResult').append(uncheckedItems);
}
Should get the result you're looking for.
This should work. Added another array listChecked to track checked values.
<script>
/* Array */
var list = new Array("valuetext000", "valuetext001", "valuetext002", "valuetext003", "valuetext004", "valuetext005", "valuetext006", "valuetext007", "valuetext008", "valuetext009", "valuetext010", "valuetext011", "valuetext012", "valuetext013", "valuetext014", "valuetext015", "valuetext016", "valuetext017")
var listChecked = new Array();
$(document).ready(function() {
displayUnchecked();
});
/* Array will be converted to an ul list */
function displayUnchecked()
{
var html = "";
for (var i = 0; i < list.length; i++) {
if ($.inArray(list[i], listChecked) == -1)
html += "<input type='checkbox' name='boxvalue' value='" + list[i] + "' /><label>" + list[i] + "</label><br>";
}
$("#elmAv").html(html);
}
</script>
</head>
<body>
<form>
<div id="elmAv"></div>
<div id="selectionResult"></div>
<script>
/* Display the items selected */
function showBoxes(frm) {
var checkedItems = "\n";
//alert('here');
//For each checkbox see if it has been checked, record the value.
for (i = 0; i < frm.boxvalue.length; i++) {
if (frm.boxvalue[i].checked) {
listChecked.push(frm.boxvalue[i].value);
}
}
$.each(listChecked, function (index, value)
{
checkedItems = checkedItems + "<li>" + value + "</li>";
});
//alert('here');
displayUnchecked();
//$("#elmAv").empty();
$("#selectionResult").html(checkedItems);
}
</script>
<input type="Button" value="Get Selection" onClick="showBoxes(this.form)" />
</form>
</body>

Ajax success append HTML with fadeIn()

I am appending html to a <ul> on an ajax success function.
HTML
<ul id="revisionList">
<!-- ajax.js will insert ordered list here based on number of revisions -->
</ul>
Ajax Success
success: function(json)
{
/*
If successful build the list of revision links
Links include link that will load images in next tab
*/
//loop through revisions and display
for(i = 0, j = json.revision_count.length; i < j; i++) {
//count for revision number
var k = i + 1;
//revision number, does not match k
var revisionID = json.revision_count[i].layout;
$('#revisionList').append(
"<li><a onclick=\"initEditRevision(" + galleryID + ',' + revisionID + ")\" href=\"#editRev\" data-toggle=\"tab\">Revision " + k + "</a></li>"
);
}
}
How do I go about fading in the whole <ul> after the list is built?
Try this
success: function(json) {
var $list = $('#revisionList');
$list.hide(); // Hide Here
for (i = 0, j = json.revision_count.length; i < j; i++) {
var k = i + 1;
var revisionID = json.revision_count[i].layout;
$list
.append("<li><a onclick=\"initEditRevision(" + galleryID + ',' +
revisionID + ")\" href=\"#editRev\"
data-toggle=\"tab\">Revision " + k + "</a></li>");
}
$list.fadeIn('slow'); // Fade In here
}​
for (...
}
$("#revisionList").hide().fadeIn();
Or perhaps you can hide it before the for loop; whatever works best.
You have to hide it using CSS display property firstly or using style attribute if you don't want to use CSS.
#revisionList{display: none;}
OR
<ul id="revisionList" style="display: none;">
then fade in after that all lis appnded completely.
$("#revisionList").fadeIn(500);

Categories

Resources