Javascript add span to li - javascript

I want my code to instead of creating two texts with my newly created span, i want it to say"Some text x2" and then x3 and so on.
Heres my code
<div>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</div>
<td class="add" onmousedown="myFunction()">Add</td>
When i click the td, it adds to the li but when i click several times it just comes more text. I want it to say "Some text x2" instead.
function myFunction() {
var proc = document.createElement("SPAN");
var t = document.createTextNode("Some new text.");
proc.appendChild(t);
document.getElementById("myLi").appendChild(proc);
}
Thanks

As Mike said, you can do this with an innerHTML.
If I understand, what you want is :
var i =0;
function doStuff(){
var proc = "<span> my text instead x"+i + "</span>" ;
document.getElementById("myLi").innerHTML = proc;
i++;
}
<div>
<li id="myLi">
<p> something </p>
</li>
<div>
<button onclick="doStuff()"> CLICK ME </button>

How about this piece?
var globalCounter = 1;
function myFunction(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+globalCounter;
globalCounter++;
}
http://jsbin.com/munukadama/edit?html,js,output
Note you will be using global counter. If you want to avoid global conflicts, either come up with unique variable name, or encapsulate within a class as a private variable (see below).
function MyClass(){
var counter = 1;
this.update = function(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+counter;
counter++;
};
}
var myInstance = new MyClass();
And then button will become:
<button onClick="myInstance.update()">Click me for Class!</button>

Here is a jQuery solution & a jsfiddle to test it out with:
HTML:
<ul>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</ul>
Add
JavaScript:
function myFunction() {
$('#myLi').html('<span>Some new text.</span>');
}
$('.add').on('click', myFunction);

Related

Deleting the last Element in a Div [JavaScript]

I'm having a strange problem. I'm trying to make a program that will add and delete div's inside another div called "body". To add divs, I use document.getElementById("body").innerHTML. Adding works fine. However, in the deleting function, I replace the "body" id with a variable with the id of the div that will be deleted. But when I run the code, I get the error "cannot set innerHTML of null". I tried to replace the id variable with a fixed local variable, and it worked fine. I also tried to add quotes to the variable but that didn't work either. Is there any reason why I can't set the id to a changing variable? Thanks.
Here is my code:
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '" + i + "'><br><textarea id = '1' > foo < /textarea></div > ";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i);
deleteDiv.innerHTML = "";
i--;
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
you are incrementing i after adding a div so you must use i-1 while deleting to get correct id.
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '"+i+"'><br><textarea id = '1'>foo</textarea></div>";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i-1);
deleteDiv.remove();
i--;
}
<div id = "body2">
<div id = "0">
<textarea id = "text">lol</textarea><button onclick =
"myFunction()">Add</button>
<button onclick = "myFunction2()">Delete</button>
</div>
</div>
To remove last child, you can even use CSS selector last-child. You should also add specific class to newly added divs as you would want to remove only newly added divs.
This will also remove dependency of i.
As an addon, you can also use document.createElement + Node.appendChild instead of setting innerHTML. .innerHTMl will be expensive for highly nested structure.
function myFunction() {
document.getElementById("body2").appendChild(getDiv());
}
function getDiv(i){
var div = document.createElement('div');
div.classList.add('inner')
var ta = document.createElement('textarea');
ta.textContent = 'foo';
div.appendChild(ta);
return div;
}
function myFunction2() {
var div = document.querySelector('#body2 div.inner:last-child')
div && div.remove()
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
You can refer "innerHTML += ..." vs "appendChild(txtNode)" for more information.

Cloned element is not shown

The following code should clone the given element and insert it after:
function cloneMore(element) {
var newElement = element.cloneNode(true);
element.parentNode.insertBefore(newElement, element.nextSibling);
}
var addChoice = document.getElementById("add-choice")
addChoice.onclick = (function(){cloneMore(document.getElementById("choices").lastChild);})
The html looks like this:
<ul id="choices">
<!-- form elements -->
</ul>
<p><a id="add-choice">Add another choice</a></p>
No exception is thrown and everything executes but I can not see the new element. Why?
lastChild picks all node types, not only Elements. So you are probably cloning a TextNode \n.
I guess that what you want is lastElementChild.
function cloneMore(element) {
var newElement = element.cloneNode(true);
element.parentNode.insertBefore(newElement, element.nextSibling);
}
var addChoice = document.getElementById("add-choice")
addChoice.onclick = function() {
var choices = document.getElementById("choices");
cloneMore(choices.lastElementChild); // only Elements
console.log('lastChild type : ', choices.lastChild.nodeName);
}
<ul id="choices">
<li> choice </li>
</ul>
<p>Add another choice</p>

Can part of Text node be highlighted?

I am creating Text node like var liContent = document.createTextNode(someHtmlString);.
And then add this variable into list like $("<li/>").html(liContent).appendTo(targetUnorderList);
Question is: Can I highlight some text in the liContent item?
And if "Yes" - how can I do that?
Clarification: I need to highlight partial content within li. For example, word Nice.
Update:
At the same time I need to display all content of Text node just like a text (including html tags).
Update 2: No processing is allowed on the string which need to be displayed. Seems there are no solution, because Text node is interpreted by browser just like a plain text.
Whole code example (working):
var someHtmlString = "<i class='icon-window-add'>Nice text here</i>";
var targetUnorderList = $("#targetUnorderList");
var liContent = document.createTextNode(someHtmlString);
$("<li/>").html(liContent).appendTo(targetUnorderList)[0];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<ul id="targetUnorderList"></ul>
</div>
Yes you could just create a custom class highlight then wrap the text you want to highlight by span with this class, Since you're using jQuery it could be done simply like :
$("<li/>").html("<i class='icon-window-add'>Nice <span class='highlight'>text here</span></i>");
Hope this helps.
var li = $("<li/>").html("<i class='icon-window-add'>Nice <span class='highlight'>text here</span></i>");
$("#targetUnorderList").append(li);
.highlight {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="targetUnorderList"></ul>
</div>
try this , it will show the "highlighted text" in red color
var someHtmlString1 = "<i class='icon-window-add'>Nice ";
var someHtmlString2="Highlighted text</span>";
var someHtmlString3="here</i>";
var targetUnorderList = $("#targetUnorderList");
var span1Text=document.createTextNode(someHtmlString1);
var span3Text=document.createTextNode(someHtmlString3);
var li=$("<li/>");
var span1=$("<span/>").html(span1Text).appendTo(li);
var span2=$("<span style='color:red'/>").html(someHtmlString2).appendTo(span1);
var span3=$("<span/>").html(span3Text).appendTo(li);
li.appendTo(targetUnorderList)[0];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<ul id="targetUnorderList"></ul>
</div>

Simple ToDo-List doesn't work

My ToDo List dont wanna work the way i want. I've just been working with JavaScript for 2 weeks sthis is very new to me, therefor the code maybe doesnt look that nice.
The result comes out wrong. If I type in "buy food" the first line gonna show just that, but the next time I wanna add "walk the dog", then it displays
buy food
buy food
walk the dog
I hope you understand my problem. It also ends the unordered list tag after the first click and adds the rest of the things in another.
Here's the JavaScript:
var taskList = [];
var text = "<ul>"
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
for(i = 0; i < taskList.length; i++){
text += "<li>" + taskList[i] + "</li>" ;
}
text += "</ul>";
document.getElementById("todoList").innerHTML = text;
}
The issue is you're closing the ul tag after adding each item. Instead of concatenating raw HTML, consider using element objects and appending, and using a text node object to handle the user input - this removes the possibility of a DOM Based XSS vulnerability.
window.onload = function() {
var taskList = [];
var container = document.getElementById("todoList");
document.getElementById("add").onclick = addToList;
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
var ul = document.createElement('ul');
var li;
for (i = 0; i < taskList.length; i++) {
li = document.createElement('li');
li.appendChild(document.createTextNode(taskList[i]))
ul.appendChild(li);
}
container.innerHTML = '';
container.appendChild(ul);
}
};
Task:
<input id="toDoTask" /> <input type="button" id="add" value="Add" />
<div id="todoList">
</div>
You should not use the innerHtml. This replace all the text of your content. You should just add the li to your ul.
You can do that by using the append function by jquery Append
your <ul> must contain an id like this <ul id="toDoList">
then you make $("#toDoList").append("yourTask");
yourTask must contains the li.
With this, you don't need to iterate on all your element list
Not sure, but you seem to keep adding to text the second time, so text will be something like <ul><li>buy food</li></ul><li>buy food</li><li>walk the dog</li></ul>, which is invalid HTML by the way, but gets outputted anyway...
On each call of function addToList() you should reset the variable text.
For example:
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
text="";
for(i = 0; i < taskList.length; i++){
text += "<li>" + taskList[i] + "</li>" ;
}
text += "</ul>";
document.getElementById("todoList").innerHTML = text;
}
The whole list of items in array will appends to variable text on each call.

Appending new container on click

I'm trying to learn HTML and Javascript/jQuery. If I have a container which holds a title, an image, a description and a number, then I want to create a new container with the exact same format (except the values will be different), how is this commonly done?
This is an example of the format I'm looking for in each item.
<li>
<div>
<div>
Image Name
</div>
<div>
<a href=URL>
<img src='image_url'>
</a>
</div>
<div>
Description
</div>
<div>
num_comment Comments
</div>
</div>
</li>
Do I just create a string and concatenate with the actual values for the image, then add that string to some variable I've saved called html_content, and then set the html value to html_content? Is that the common way of doing this or is there a better way?
EDIT
To give a better idea of what I'm currently doing, here's the javascript:
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
};
$('pics').html(html);
}
In jQuery you just have to use the append() function to add on to something.
You could do something like...
$('select element').append('<li><div>....etc.');
and where you want a different value you can use a variable.
You can use .clone() and create a copy of this, then iterate through the cloned object and change what you need:
var $objClone = $("li").clone(true);
$objClone.find("*").each(function() {
//iterates over every element. customize this to find elements you need.
});
To change the image source you can do:
$objClone.find("img").attr("src", "new/img/here.jpg");
Fiddle demoing the concept: http://jsfiddle.net/H9DnA/1/
You may find it useful to explore some of the JavaScript templating libraries. The essential idea is that you create a template of your markup:
<li>
<div>
<div>
{{name}}
</div>
<div>
<a href="{{url}}">
<img src="{{imageUrl}}">
</a>
</div>
<div>
{{description}}
</div>
<div>
{{comments}}
</div>
</div>
</li>
Then you merge it against some associated matching object and insert it into your document:
{ name: 'Image Name',
url: 'http://example.com',
imageUrl: 'http://example.com/image.jpg',
description: 'Description',
comments [ { text: 'Comment' } ]
}
function render(pics)
{
var theList = document.getElementByid("LIST ID");
for (var i in pics){
var listItem = document.createElement('li'); // Create new list item
var nameDiv = document.createElement('div'); // Create name DIV element
nameDiv.innerHTML = pics[i].name; // Insert the name in the div
var img = document.createElement('img'); // Create Img element
img.setAttribute('src',pics[i].src); // Assign the src attribute of your img
var imgDiv = document.createElement('div'); // Create Img Div that contains your img
imgDiv.appendChild(img); // Puts img inside the img DIV container
var descDiv = document.createElement('div'); // Create Description DIV
descDiv.innerHTML = pics[i].description; // Insert your description
listItem.appendChild(nameDiv); // Insert all of you DIVs
listItem.appendChild(imgDiv); // inside your list item
listItem.appendChild(descDiv); // with appropriate order.
theList.appendChild(listItem); // Insert the list item inside your list.
}
}
I think this will work just fine:
$('#button').click(function () {
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
$("ul").append(html);
}
}
// call render
});
I didn't do a test run on your code so there might be an error somewhere. My tweak adds this line $("ul").append(html); inside your loop

Categories