How to add a document fragement to a div - javascript

I have this simple code. I need to add this ul html list to "my-div", but with this code I cannot add it. Any idea what is wrong?
Would be possible add the fragmentusing jquery?
this.renderMenuTop = function() {
var menu, f, ul;
menu = ['menu-actuality', 'menu-archive', 'menu-pdf', 'menu-pictures'];
f = document.createDocumentFragment();
ul = document.createElement('ul');
for (var i = 0; i < menu.length; i++) {
var li = document.createElement('li')
li.id = menu[i];
ul.appendChild(li);
}
document.getElementById("my-div").appendChild(f);
//$(this.elmMenuTop).append(f);
}

You never add any elements to your document fragment. Add this after your for loop:
f.appendChild(ul);
Another option is to just dump the document fragment altogether and just:
document.getElementById("my-div").appendChild(ul);
// ^^ Change from f to ul

You never put anything in f. But why do you even have a document fragment?
this.renderMenuTop = function() {
var menu = ['menu-actuality', 'menu-archive', 'menu-pdf', 'menu-pictures'];
var ul = document.createElement('ul');
for (var i = 0; i < menu.length; i++) {
var li = document.createElement('li')
li.id = menu[i];
ul.appendChild(li);
}
document.getElementById("my-div").appendChild(ul);
//$(this.elmMenuTop).append(f);
};
If you need to append it to two different things, a document fragment won’t help.

Where do you add the list to the fragment? You'd need to add
f.appendChild(ul);
before adding it to the div. Alternatively, just add the list straight to the div without the fragment.

To answer the second part of your question, this is also possible with jQuery:
this.renderMenuTop = function() {
var menu = ['menu-actuality', 'menu-archive', 'menu-pdf', 'menu-pictures'];
var $ul = $('<ul></ul>');
for (var i = 0; i < menu.length; i++) {
$ul.append('<li>' + menu[i] + '</li>');
}
$('#my-div').append($ul);
}

Related

How to add class to element created using document.createElement?

I have managed to add a class to the ul element but I can't get the syntax right to add classes to the li and a elements. Can anyone help please?
<script>
anchors.options.placement = 'left';
anchors.add('.entry-content h2');
generateTableOfContents(anchors.elements);
// External code for generating a simple dynamic Table of Contents
function generateTableOfContents(els) {
var anchoredElText,
anchoredElHref,
ul = document.createElement('UL');
ul.className = "uk-nav uk-nav-default";
document.getElementById('table-of-contents').appendChild(ul);
for (var i = 0; i < els.length; i++) {
anchoredElText = els[i].textContent;
anchoredElHref = els[i].querySelector('.anchorjs-link').getAttribute('href');
addNavItem(ul, anchoredElHref, anchoredElText);
}
}
function addNavItem(ul, href, text) {
var listItem = document.createElement('LI'),
anchorItem = document.createElement('A'),
textNode = document.createTextNode(text);
anchorItem.href = href;
ul.appendChild(listItem);
listItem.appendChild(anchorItem);
anchorItem.appendChild(textNode);
}
</script>
before append li tag in the ul you need add your class then append li tag to ul tag like this
var listItem = document.createElement('LI');
listItem.className = 'someClassName';
ul.appendChild(listItem);

I need to put my LI array element into a UL but I cant

HERE IS THE CODE:
I need to do a couple of things but I am pretty new coding :S.
First I need to format the li elements I am loading into the array into a UL. them I need also to create a loop where I can print those 20 array elements repeating them to display 2300 elements. Thanks :)
var _objetsOfArray = new Array();
var darFormato = function (numero){
var numero = document.createElement("li");
var contenido = document.createTextNode(i);
numero.appendChild(contenido);
document.body.insertBefore(numero);
}
for (i = 0; _objetsOfArray.length < 20; i++ ){
_objetsOfArray.push (i);
darFormato(i);
};
This resolved it for you.
http://jsfiddle.net/t4Vec/
var count = 2300;
while (count){
var _objectsOfArray = [],
ul = document.createElement("ul");
for (var i = 0; i < 20; i++){
var item = document.createElement("li");
item.innerText = i;
_objectsOfArray.push(item);
ul.appendChild(_objectsOfArray[i]);
count --;
}
//do something with UL
document.body.appendChild(ul);
}
If you have a precreated list, you could use innerHTML and parse it accordingly.
My sample just prints a ul with 20 Li elements with the text node set to the index of the node
Edit: New Fiddle: http://jsfiddle.net/t4Vec/1/
I use this on a page to generate some dynamic links:
<ul id="list">
</ul>
and here is the script
var myData = [
"item1",
"item2"
]
function createItems()
{
var ul = document.getElementById("list");
for (var i = 0; i < myData.length; i++)
{
var li = document.createElement("li");
var a = document.createElement("a");
a.href = "http://stackoverflow.com/search?tab=newest&pagesize=30&q=" + myData[i].toLowerCase();
a.target = "_blank";
a.innerHTML = myData[i];
li.appendChild(a);
ul.appendChild(li);
}
}
createItems();
where I changed the hrefs to SO :)
I hope taking a look will help you

javascript equivalent of jquery for this function

In a dinamically generated "ol" :
document.getElementsByTagName('ol');
for (i = 0; i < len; i++){
var newLi = document.createElement("li");
var link = document.createElement('a');
link.href = "#";
link.innerHTML = (results.rows.item(i).location + "-" + results.rows.item(i).datte);
newLi.appendChild(link);
olnew[0].appendChild(newLi);
i need find the "li" clicked, i use jquery library only for this function, i am searching for the same functionality in javascript, but at momento i have not idea how i can code it. thx
var ss;
ss=$("#idfromOl");
ss.click(clickhecho);
}
function clickhecho()
{
var $all_lis = $('li');
$all_lis.on('click', function() {
var index = $all_lis.index(this);
});
}
try this:
function createfunc(i) {
return function() { alert(i); };
}
for (i = 0; i < len; i++){
var newLi = document.createElement("li");
var link = document.createElement('a');
link.href = "#";
link.innerHTML ="test"
newLi.appendChild(link);
// just add onclick event; use createFunc to create function closure (otherwise 'i' would always be the last 'i'
newLi.onclick = createfunc(i);
olnew[0].appendChild(newLi);
}
I might be mistaken, but is this what you are looking for?
var elements = document.getElementsByTagName('li');
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function (e) {
$("#clickedLi").text(e.srcElement.id);
});
}
It appends an event called addEventListener to every li element.
Inside each li element there is an click event given as a parameter which contains the id of the li clicked.
demo: http://jsfiddle.net/DUzMc/1/
Your first part of script is incomplete, so I did a short script to generate a dynamic list.
Basicly you were looking for addEventListener():
var elements = 10;
ol = document.createElement('ol');
for(i = 1; i <= elements; i++){
var li = document.createElement('li');
var a = document.createElement('a');
a.setAttribute('href', '#');
a.text = 'Link ' + i;
li.appendChild(a);
ol.appendChild(li);
a.addEventListener("click", who, false); // THIS IS THE IMPORTANT PART
}
document.getElementsByTagName('body')[0].appendChild(ol);
function who(e){
var myTarget = e.target;
myTarget.text = "clicked!";
}
The easiest way is to include the event while generating the list:
document.getElementsByTagName('ol');
for (i = 0; i < len; i++){
var newLi = document.createElement("li");
var link = document.createElement('a');
link.href = "#";
link.innerHTML = (results.rows.item(i).location + "-" + results.rows.item(i).datte);
// Add this
link.onclick = function(index) { return function() {
// do something with index variable
}}(i);
newLi.appendChild(link);
olnew[0].appendChild(newLi);
Note I use a local variable index instead of i, this is because when the item is clicked the value of i will be different (equal to len).

sort unordered list of buttons by list.id

My html5, css, javascript program will be a day calendar. Clicking on the button of an event will bring up the details of that event. Right now, I have a days worth of events in the order they were entered. I'm stuck trying to sort an unordered list of buttons based on their id. Here you can see how each ul button is created. Values come from an indexedDB.
function renderTodo(row) {
var todos = document.getElementById("todoItems");
var li1 = document.createElement("li");
var name = document.createTextNode(row.name);
var li2 = document.createElement("li");
var time = document.createTextNode(row.time);
var btn = document.createElement("BUTTON")
var a = document.createElement("a");
var li = document.createElement("li");
a.addEventListener("click", function() {
helicopter.indexedDB.deleteEvent(row.timeStamp);
}, false);
a.textContent = " [Delete]";
li1.appendChild(name);
li2.appendChild(time);
btn.onclick=viewEvent;
btn.id=row.parent;
btn.row = row;
btn.appendChild(li1);
btn.appendChild(li2);
li.appendChild(btn);
li.appendChild(a);
li.id = row.time;
todos.appendChild(li)
sortUnorderedList(todos);
}
In other words, the finished product looks something like this.
ul-button2-[delete]
ul-button1-[delete]
ul-button3-[delete]
When I convert the list to array, it drops the button and only keeps the two li values. I've tried a few things to no success (see below). Should I drop the button idea and just use CSS to give the same look or is there a good way to sort the buttons.
function sortUnorderedList(ul) {
//if(typeof ul == "string")
//ul = document.getElementById(ul);
// Idiot-proof, remove if you want
if(!ul) {
alert("The UL object is null!");
return;
}
// Get the list items and setup an array for sorting
var lis = ul.getElementsByTagName("LI");
var ali = Array.lis;
ali.sort(liSort);
ul.innerHTML = "";
// Populate the array
for(var i = 0, j = lis.length; i < 2; i++)
ul.appendChild(ali[i]);
// Sort it
//vals.sort(liSort);
//vals.reverse();
// Change the list on the page
//for(var i = 0, l = lis.length; i < l; i++)
//lis[i].innerHTML = vals[i];
}
function liSort(one, two) {
//alert(one.id + " - " two.id);
return one.id - two.id;
}
1.) Because the lis (which should be sorted) have sub-lis, it will be better to select them by class (which is available with html5); so add a class with following line after li.id = row.time;:
li.className = 'sortLi';
2.) In the function select them and convert the list to an array:
var lis = ul.getElementsByClassName("sortLi");
var ali = Array.prototype.slice.call(lis);
3.) Append them now in sorted order:
ali.sort(liSort);
for (var i = 0; i < ali.length; i++) {
ul.appendChild(ali[i]);
}
4.) The sort function:
function liSort(one, two) {
return one.id < two.id ? -1 : ( one.id > two.id ? 1 : 0 );
}
Also see an example.

Create and Append an element, innerHTML? the horror... [please no jquery]

I have a script that returns a list in alphabetical order as follows
<div id="x">
<ul>
<li>Apple
<li>Banana
<li>Blackberry
<li>Blueberry
<li>Cherry
<li>Cranberry
</ul>
</div>
However there are many items (almost 100) in the list and I am hoping to rearrange them as follows
<div id="x">
<span id="A">A</span>
<ul>
<li>Apple
</ul>
<span id="B">B</span>
<ul>
<li>Banana
<li>Blackberry
<li>Blueberry
</ul>
<span id="C">C</span>
<ul>
<li>Cherry
<li>Cranberry
</ul>
<div>
I'm not really sorting fruit btw, this is just an example.
It MUST be in that form, for reasons that matter not, I just need help creating and appending the span elements and the individual lists.
I have tried using inner/outer HTML and I'm finding it really really difficult. I currently have something like this:
function getAllLists()
{
var page = document.getElementById("x")
var allLists = page.getElementsByTagName("li");
var num = allLists.length;
//Some form of a for counter loop here
for (var counter = 0; counter < num; counter++) {
var first=allLists[counter].outerHTML;
var second=allLists[counter+1].outerHTML;
var firstletter= (allLists[counter].substring(0, 1)).toUpperCase();
var secondletter= (allLists[counter+1].substring(0, 1)).toUpperCase();
allLists[counter].outerHTML = '<span id="'+firstletter+'">'+firstletter+'</span>'+first;
}
}
PLEASE PLEASE PLEASE PLEASE AVOID USING JQUERY.
I can't stress this enough!!
Not only do I find it extremely difficult to understand, as I am still an amateur at javascript and find js already difficult enough as it is, the syntax for jquery is like just stupidly hard to understand.
I am certain it is possible to achieve what I am aiming for WITHOUT the need to use jquery.
Any ideas? all help/comments/ideas are more than appreciated.
Many thanks.
Firstly forget all about manipulating the DOM using inner/outerHTML. They are handy for inserting chunks of HTML or sections of documents, but they are definitely not intended for general DOM manipulation.
Use DOM methods.
Firstly, load all the LI elements into an array. Then sort them using a sort function. Then put them back into the DOM wrapped in UL elements and separated by spans each time the first letter changes.
Edit
Here's a function that does the job. It sorts the lIs, not sure if that's really needed. If not, the function becomes a lot simpler.
<script type="text/javascript">
// Simple helper
function getText(el) {
if (typeof el.textContent == 'string') {
return el.textContent.replace(/^\s+|\s+$/g,'');
}
if (typeof el.innerText == 'string') {
return el.innerText.replace(/^\s+|\s+$/g,'');
}
}
function sortLIs(id) {
// Get the element
var el = document.getElementById(id);
// Get the UL element that will be replaced
var sourceUl = el.getElementsByTagName('ul')[0];
// Get the LIs and put them into an array for sorting
var nodes = sourceUl.getElementsByTagName('li');
var li, lis = [];
for (var i=0, iLen=nodes.length; i<iLen; i++) {
lis[i] = nodes[i];
}
// Sort them
lis.sort(function(a, b) {
return getText(a) > getText(b)? 1 : -1;
});
// Now put them into the document in different ULs separated
// by spans.
// Create some temporary elements for cloning
var ul, ulo = document.createElement('ul');
var sp, spo = document.createElement('span');
var frag = document.createDocumentFragment(); // fragments are handy
var firstChar, currentChar;
// For each LI in the array...
for (i=0; i<iLen; i++) {
li = lis[i];
firstChar = getText(li).substr(0,1) || '';
// If first char doesn't match current, create a new span
// and UL for LIs
if (firstChar !== currentChar) {
currentChar = firstChar;
// New span
sp = spo.cloneNode(false);
sp.appendChild(document.createTextNode(firstChar.toUpperCase()));
sp.id = firstChar;
frag.appendChild(sp);
// New UL
ul = ulo.cloneNode(false);
frag.appendChild(ul);
}
// Add the li to the current ul
ul.appendChild(li);
}
// Replace the UL in the document with the fragment
el.replaceChild(frag, sourceUl);
}
</script>
<div id="x">
<ul>
<li>Cherry
<li>Banana
<li>Apple
<li>Blueberry
<li>Cranberry
<li>Blackberry
</ul>
</div>
<button onclick="sortLIs('x');">Sort</button>
Note that the LIs are just moved to the document fragment and that the original UL is replaced by multiple elements. I've jumbled the LIs to show that the sort works.
Edit 2
If you have the array as text, then:
var fruits = ['Cherry','Banana','Apple','Blueberry',
'Cranberry','Blackberry'].sort();
function insertFruits(id) {
var el = document.getElementById(id);
// Check that the above worked
if (!el) return;
var frag = document.createDocumentFragment();
var li, lio = document.createElement('li');
var ul, ulo = document.createElement('ul');
var sp, spo = document.createElement('span');
var firstChar, currentChar;
for (var i=0, iLen=fruits.length; i<iLen; i++) {
fruit = fruits[i];
firstChar = fruit.substr(0,1).toUpperCase();
if (firstChar !== currentChar) {
currentChar = firstChar;
sp = spo.cloneNode(false);
sp.appendChild(document.createTextNode(firstChar));
sp.id = firstChar;
frag.appendChild(sp);
ul = ulo.cloneNode(false);
frag.appendChild(ul);
}
li = lio.cloneNode(false);
li.appendChild(document.createTextNode(fruit));
ul.appendChild(li);
}
el.appendChild(frag);
}
HTML:
<body>
<div id="x">
<ul>
<li>Apple
<li>Banana
<li>Blackberry
<li>Blueberry
<li>Cherry
<li>Cranberry
</ul>
<ul id="new"></ul>
JavaScript:
var list = document.querySelector('#x ul'),
newUl = document.getElementById('new'),
fruits = [],
key = "A";
for(var i=0; i<list.children.length; i++){
fruits.push(list.children[i].innerText);
}
fruits.sort();
for(var i=0; i<fruits.length; i++){
if(key == fruits[i].split('')[0]){
var span = document.createElement('span'),
li = document.createElement('li');
span.setAttribute('id', key);
li.innerText = fruits[i];
if(document.getElementById(key)){
document.getElementById(key).appendChild(li);
}
else{
span.appendChild(li);
newUl.appendChild(span);
}
}
if(fruits[i+1]){
key = fruits[i+1].split('')[0];
}
}
Example:Live Code
Well, this is the way I get it done:
var allLists, elements, item, lastLetter, lastUl, letter, page, span, _i, _len;
page = document.getElementById("x");
allLists = page.getElementsByTagName("li");
lastLetter = null;
lastUl = null;
elements = document.createDocumentFragment();
for (_i = 0, _len = allLists.length; _i < _len; _i++) {
item = allLists[_i];
letter = item.innerText[0].toUpperCase();
if (letter !== lastLetter) {
lastLetter = letter;
span = document.createElement('span');
span.innerText = letter;
span.id = letter;
elements.appendChild(span);
lastUl = document.createElement('ul');
elements.appendChild(lastUl);
}
lastUl.appendChild(item.cloneNode(true));
}
while (page.firstChild) page.removeChild(page.firstChild);
page.appendChild(elements.cloneNode(true));
See this working here: http://jsfiddle.net/HjWhY/

Categories