Using innerHTML to add ordered list fails in IE - javascript

I'm using the following Javascript code to populate a DIV with an ordered list:
// send script back in split list
var scriptList = script.split("\n");
var finalScript = "<ol>\n";
var count = 0;
while(scriptList.length >= count) {
if((scriptList[count]=="") || (scriptList[count] == undefined)) {
count ++;
continue;
}
finalScript = finalScript + "<li>" + scriptList[count] + "</li>\n";
count ++;
}
finalScript = finalScript + "</ol>";
scriptingDiv.innerHTML = finalScript;
In firefox, if i look in the DOM using Firebug, this correctly translates to the following and correctly displays an ordered list.
<ol>
<li>This is the first item in the list</li>
<li>This is the second item in the list</li>
</ol>
In IE, it displays as if the </li> tags are <br /> tags and ignores all the other tags, like this:
This is the first item in the list
This is the second item in the list
Do I need to dynamically add the ordered list to the DOM for this to work? As opposed to just setting the html code in the div using .innerHTML?
TIA

Do I need to dynamically add the ordered list to the DOM for this to work? As opposed to just setting the html code in the div using .innerHTML?
Yes
var scriptList = script.split("\n");
var count = 0;
var ol = document.createElement("ol");
for(var index=0; index<scriptList.length; index++) {
if(scriptList[index]!="") {
var li = document.createElement("li");
li.innerHTML=scriptList[index];
ol.appendChild(li);
}
}
scriptingDiv.appendChild(ol);

Why not use dom methods instead? IE:
myOL = document.createElement("ol");
myLI = document.createElement("li");
myTxt = document.createTextNode("My Text!");
myLI.appendChild(myTxt);
myOL.appendChild(myLI);
etc

Related

How to add new <li> element each click?

First attempt at any sort of Javascript so be gentle aha
Have managed to have the page add the new list item to the inner html of an unordered list, but each time after that it just replaces the initial.
I feel like I'm missing something really basic here?
Any advice would be greatly appreciated.
<script>
function addItem() {
var item = document.getElementById("task-field").value;
document.getElementById("task-list").innerHTML = "<li> " + item + " </li>";
}
</script>
Use
document.getElementById("task-list").innerHTML += "<li> " + item + " </li>";
instead of
document.getElementById("task-list").innerHTML = "<li> " + item + " </li>";
The += operator will use the current value of innerHTML and append your new content in this case. This as suggested by #Hassam Imam.
Another way of doing it is using appendChild() creating the new <li> item through JS. Like this:
function addItem() {
let item = document.getElementById("task-field").value;
let parent = document.getElementById("task-list");
// Create new node.
let li_item = document.createElement("li");
li_item.innerHTML = item;
// Append child.
parent.appendChild(li_item);
}
But this last method is probably too lengthy. The += solution seems good. Just another way of doing it.
<script>
function addItem(item) {
const li = document.createElement('li');
li.innerHTML = `${item}`;
li.id = 'task-field';
document.getElementById('task-list').appendChild(li);
}
</script>

Unable to get property 'nodeValue' of undefined or null reference in simple jQuery loop

I am inserting li values into a ul element on a form.
Just as testing, I am entering 2 values into the ul. Now, once the user clicks submit, I am checking if any of those li values are duplicates in another list... if not, then submit the values. But, I am working on a scenario where if the user enters a few duplicates and non-duplicates in the ul.. then I would want the non-duplicates to be taken away from the ul element once they are submitted, but keep the duplicates in the list so that the user can see the duplicates.
Here is my code:
console.log("Serial Length - " + $("#SerialUL li").length);
var serialUlLength = $("#SerialUL li").length;
// remove serial numbers that have been submitted from the list on the form.
for(i = 0; i < serialUlLength; i++){
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().get(0).nodeValue;
var isInSubmitArray = $.inArray(serialNumber, submitArray);
if(isInSubmitArray > -1){
console.log(serialNumber);
$("#SerialUL li:eq(" + i + ")").remove();
}
}
As I stated above, as of now, I am only entering 2 li values into the ul for simple testing. The list that I am comparing against has 0 values in it.. so there shouldn't be any duplicates at this point. The problem I am experiencing happens for the second li element. I am receiving this console error:
Unable to get property 'nodeValue' of undefined or null reference
I have debugged in the console, but I guess I am staring at this for too long. Can someone assist in explaining why I am getting this error?
Any help is appreciated.
UPDATE
The values I am entering as li are 10 and 11. Here is what I see in the console based off of the code above in my question:
UPDATE 2
Code to show li being appended to ul element
// Append TextBox Value to '<ul>' element for user to see once they click button
$("#SerialUL").append("<li class='bullet-serial'>" + serialTxtBoxValue + "<button type='button' class='remove-button'>x</button></li>");
How about this vastly simpler and easier to debug - assuming a leading serial number and something not a number after
var submitArray=[123,567];
$("#SerialUL li").each(function(_,li) {
var ser = parseInt(li.textContent.trim()); // add .replace(/[^0-9]/g,"") if needed
console.log(ser)
if (submitArray.indexOf(ser) !== -1) {
console.log("removing",ser)
li.remove();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="SerialUL">
<li>123 <button>X</button></li>
<li>456 <button>X</button></li>
<li>123 <button>X</button></li>
<li>567 <button>X</button></li>
<li>789 <button>X</button></li>
</ul>
More complex version with some useful extras such as delegation
var submitArray = [];
$("#serialTxtBox").on("input", function(e) {
var val = this.value;
$("#err").toggle(val && submitArray.indexOf(val)!==-1);
if (String(val).length == 3 && submitArray.indexOf(val)==-1) {
submitArray.push(val);
$("#SerialUL").append("<li class='bullet-serial'>" + val + "<button type='button' class='remove-button'>x</button></li>");
$(this).val("");
}
if ($("#err").is(":visible")) $(this).val("");
})
$("#SerialUL").on("click",".remove-button", function(e) { // delegation
e.preventDefault();
$(this).closest("li").remove();
submitArray = [];
$("#SerialUL li").each(function(_, li) {
var ser = parseInt(li.textContent.trim()); // add .replace(/[^0-9]/g,"") if needed
submitArray.push(ser);
});
})
#err { color:red; display:none }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="serialTxtBox" /><span id="err">Already there</span>
<ul id="SerialUL">
</ul>
You are returning element node with .contenets().get(0). "nodeValue" always returns null on element node.
Try filtering for text nodes only on contents() function:
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().filter(function() {
return this.nodeType === 3;
}).get(0).nodeValue;
Or use .textContent instead .nodeValue:
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().get(0).textContent;

Getting Index of Item in List coming from Array

I have this array:
var names = [
"Name1",
"Name2",
"Name3"
];
I converted this to Unorder List for HTML:
for(i = 0; i < names.Length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
Now, I got this:
Name1
Name2
Name3
And I am happy with the result. But now I want if someone click on Name2 so it alert me the index of the value. What I want is it should in Mobile App (Cordova) so that when user click on List Item it will show details on other activity (Some other page).
PS:
I checked:
var index = $( "li" ).index( this );
and
var index = $("ul li.active").index();
But seems like these are not made for me.
May be I should Dynamically assign ID's to each <li> item? What should I do now?
You can directly get index using index method.
$("li").click(function () {
alert($(this).index());
});
If you have multiple ul elements on page and you want to bind click event to some specific element you can do this.
To bind click on element by id
$("#YourUlId li").click(function () {
alert($(this).index());
});
To bind click event by class
$(".YourUlClass li").click(function () {
alert($(this).index());
});
$( "li" ).index will return elements index with respect to all li elements in DOM.
You need to use .index() with jquery object of clicked element. It will return the elements index in its parent container:
var index = $(this).index();
Pass the id dynamically in for loop
for(i = 0; i < names.Length; i++){
text += "<li id="+i+">" + names[i] + "</li>";
}
assign the click event, u will get the id by below code
$(li).click(function(){
alert($(this).attr("id"));
});
use this for getting the current element
<ul>
<li>Male</li>
<li>Female</li>
</ul>
<script>
$("li").click(function(){
alert($(this).index())
})
</script>
See below working snippet
var names = [
"Name1",
"Name2",
"Name3"
];
var text='<ul>';
for(i = 0; i < names.length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$('li').on('click',function(){
alert($(this).index())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="choices"></div>
Using native javascript, you can just create a function that will alert the index of the array value corresponding the li element value/id
First you attach the function on the choices
document.getElementById('Name2').setAttribute('onclick','checkIndex(this)');
then loop through the array and hunt for the matching array value
function checkIndex(item){
for(i=0;i<names.length;i++){
if(names[i] == item.innerHTML){ //or item.id
alert(names.indexOf(names[i]));
}
}
}
I would handle it in a declarative way, using html data-attributes, handled by jquery. see here
Here's an example.
var names = ["jack", "mary", "lou", "andrew"];
var text = "<ul>";
for (var i = 0; i < names.length; i++) {
text += "<li data-id='" + i + "'>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$("li").click(function(e){
alert($(this).data("id"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
My Choice
<div id="choices"></div>
</body>
</html>
Of course you can change data-id with whatever you want, or either add other attributes (data-page ? data-txt ? ) and handle all this in a proper way.
Also, dynamically assign ids to your list is a possibility, but I prefer this because I find it more flexible.

Add items to a list using jquery

I had a quick question that I can't figure out. I am working with this code:
http://jsfiddle.net/spadez/ZTuDJ/32/
// If JS enabled, disable main input
$("#responsibilities").prop('disabled', true);
// $("#responsibilities").addClass("hidden");
// If JS enabled then add fields
$("#resp").append('<input placeholder="Add responsibility" id="resp_input" ></input><input type="button" value="Add" id="add"> ');
// Add items to input field
var eachline='';
$("#add").click(function(){
var lines = $('#resp_input').val().split('\n');
var lines2 = $('#responsibilities').val().split('\n');
if(lines2.length>10)return false;
for(var i = 0;i < lines.length;i++){
if(lines[i]!='' && i+lines2.length<11){
eachline += lines[i] + '\n';
}
}
$('#responsibilities').text($("<div>" + eachline + "</div>").text() );
$('#resp_input').val('');
});
The idea is that you type something in the responsibility field and it gets inserted into a text area. What I also want to do is that when an item is inserted into the text area it also prints it out above it in a list format like this:
<li>inserted item 1</li> <li>inserted item 2</li>
I'm really new to javascript but this was my best stab at it based on information found online:
$("#resp").append('<li> +eachline </li> ')
$('#responsibilities').text($("<div>" + eachline + "</div>").text() ).before("<li>"+lines+"</li>");
Demo ---> http://jsfiddle.net/ZTuDJ/34/
http://jsfiddle.net/pjdicke/ZTuDJ/35/
You will need to create a <ul> then add this below
$('#responsibilities').text( $("<div>" + eachline + "</div>").text() );
// add this line after above
$('<li>' + lines + '</li>').appendTo('#list');
I already fixed that for you in your previous question.
Jquery adding items to a list without reloading page
http://jsfiddle.net/blackjim/VrGau/15/
var $responsibilityInput = $('#responsibilityInput'),
$responsibilityList = $('#responsibilityList'),
$inputButton = $('#addResp'),
rCounter = 0;
var addResponsibility = function () {
if(rCounter < 10){
var newVal = $responsibilityList.val()+$responsibilityInput.val();
if(newVal.trim()!==''){
var newLi = $('<li>');
$('ul#respList').append(newLi.text(newVal));
$responsibilityList.val('');
rCounter+=1;
}
}
}
$inputButton.click(addResponsibility);

create HTML using javascript recursive function not working

I am trying to make a recursive function in Javascript which should basically give me HTML like BELOW
<li><a class="expand">+</a> <span class="treeNodeInner"><a id="7471">Ringtones</a>
<ul>
<li><span class="treeNodeInner"><a id="7995">Top Tones</a></span></li>
<li><span class="treeNodeInner"><a id="8642">Country</a></span></li>
<li><span class="treeNodeInner"><a id="8640">Rock</a></span></li>
</ul>
</span></li>
I am using the below function to make the above html using javascript.
Its basically a tree view were we will have nodes and sub nodes kind of thing.
I am struggling the achieve the above HTML structure through below function, please advise modifications with the below function
function GenerateNodes(categItem) {
var parentNode = "<li>"; //parent li
if (categItem.SubCategory != null && categItem.SubCategory != undefined && categItem.SubCategory.Count > 0) {
parentNode = "<li><a class='expand'>+</a>";
}
parentNode += "<input type='radio' name='category' /><span class='treeNodeInner'><a id='" + categItem.ID + "'>" + categItem.name + "</a> "; //need to close the span
if (categItem.SubCategory != null && categItem.SubCategory != undefined && categItem.SubCategory.Count > 0) {
var subNode = "<span><ul>";
for (var index = 0; index < categItem.SubCategory.Count; index++) {
subNode += GenerateNodes(categItem.SubCategory[index]);
subNode += "</ul></span>"
}
parentNode += subNode
}
parentNode += "</span></li>"
}
Thanks
Simply looking at the code, I found out that you are not inserting the new li in your html. I'm not sure if you manage this somewhere out of your code. I'd copied your code and do some debug on it. Then I try to add the li on the html using some code. See code below:
//Insert this after parentNode += "</span></li>";
var newDiv = document.createElement('div');
newDiv.innerHTML = parentNode;
categItem.appendChild(newDiv.childNodes[0]);
//I assume that categItem is the id of the container as your sample html code
//above is not clear to me. So I did using sample html below
<div id="liContainer">
</div>
See this jsfiddle how the above code work. I know this is not exactly what you want, but I hope you can get some idea from this.

Categories

Resources