Append array to a class in javascript - javascript

I have an array in javascript called menuElm that has <ul> elements in it:
<ul id="1"></ul>
<ul id="2"></ul>
<ul id="3"></ul>
I have a page in HTML that has the following:
<ul id="menu">
<li class="menu-item"></li>
<li class="menu-item"></li>
<li class="menu-item"></li>
</ul>
I want to add the elements of menuElm to the HTML page so it would look like this:
<ul id="menu">
<li class="menu-item">
<ul id="1"></ul>
</li>
<li class="menu-item">
<ul id="2"></ul>
</li>
<li class="menu-item">
<ul id="3"></ul>
</li>
</ul>
I have tried the following, but the <ul> elements just wont show up in the page nor in the code:
function CreateMenu() {
var menuElm;
var k = 0;
menuElm = createElm("ul");
menuElm.id = ++k;
for (var i = 0; i < menuElm.length; ++i) {
document.getElementsByClassName("menu-item")[i].appendChild(menuElm[i]);
}
}
I am new with JavaScript, what am I doing wrong?

menuElm.length
The ul element doesn't have a length, so you are looping from 0 to 0, which is 0 iterations.
menuElm = createElm("ul");
This function isn't defined. You need document.createElement('ul');
menuElm = createElm("ul");
menuElm.id = ++k;
You appear to be creating one list item, and then changing its ID and appending it multiple times.
You need a new list item each time you go around the loop.
appendChild(menuElm[i]);
You've been treating menuElm as an element previously. It isn't an array, [i] makes no sense here.

$("#menu").find('li').each(function(i){
$(this).append(menuElm[i]);
});
/* if you want to use jquery here is the code to append */

Related

JavaScript: splitting an HTML list in half

I have a 26-item list with one for each letter of the alphabet
<ul>
<li id="a">A</li>
...
<li id="m">M</li>
<li id="n">N</li>
...
<li id="z">Z</li>
</ul>
How could I use JavaScript to terminate the list after 'M' (i.e. </ul>, add an <h2> element and start another list, beginning with 'N'?
So:
<ul>
...
<li id="m">M</li>
</ul>
<h2>Part 2</h2>
<ul>
<li id="n">N</li>
...
</ul>
I can insert the h2 element fine with .createElement and .insertBefore, but I can't get the closing and opening list tags either side of it. I've tried innerHTML, outerHTML, insertBefore...
The array#slice method doesn't work on DOM elements. We will have to iterate through all of the elements, and create a new array instead.
First we have to remove the original list from the DOM. We can do that with the removeChild function
var originalList = document.getElementById("existingList");
document.body.removeChild(orginalList);
# Or wherever your list was nested under
# find all your list elements. This is assuming you only have 26 list elements
var li = document.getElementsByTagName("li");
var firstLetters, secondLetters = [], [];
# Create array for first half of list elements
for (var i = 0; i < li.length/2; i++) {
firstLetters.push(li[i]);
}
# Create array for second half of list elements
for (var i = li.length/2; i < li.length; i++) {
secondLetters.push(li[i]);
}
var list1 = document.createElement("ul");
var list2 = document.createElement("ul");
document.body.appendChild(list1);
document.body.appendChild(list2);
for (var i = 0; i < firstLetters.length; i++) {
list1.appendChild(firstLetters(i));
}
for (var i = 0; i < secondLetters.length; i++) {
list2.appendChild(secondLetters(i));
}
You can get the ul, clone it, insert the clone, and append the childnodes of the ul after the 13th child element to the clone:
var ul = document.querySelector('ul'),
newUl = ul.cloneNode(false),
last = ul.children[12];
ul.parentNode.insertBefore(newUl, ul.nextSibling);
ul.parentNode.insertBefore(document.createElement('h2'), newUl)
.appendChild(document.createTextNode('Part 2'));
while(last.nextSibling) newUl.appendChild(last.nextSibling);
var ul = document.querySelector('ul'),
newUl = ul.cloneNode(false),
last = ul.children[12];
ul.parentNode.insertBefore(newUl, ul.nextSibling);
ul.parentNode.insertBefore(document.createElement('h2'), newUl).appendChild(document.createTextNode('Part 2'));
while(last.nextSibling) newUl.appendChild(last.nextSibling);
<ul>
<li id="a">A</li>
<li id="b">B</li>
<li id="c">C</li>
<li id="d">D</li>
<li id="e">E</li>
<li id="f">F</li>
<li id="g">G</li>
<li id="h">H</li>
<li id="i">I</li>
<li id="j">J</li>
<li id="k">K</li>
<li id="l">L</li>
<li id="m">M</li>
<li id="n">N</li>
<li id="o">O</li>
<li id="p">P</li>
<li id="q">Q</li>
<li id="r">R</li>
<li id="s">S</li>
<li id="t">T</li>
<li id="u">U</li>
<li id="v">V</li>
<li id="w">W</li>
<li id="x">X</li>
<li id="y">Y</li>
<li id="z">Z</li>
</ul>

Javascript/Jquery: Number nested list

I have a nested list:
<ul>
<li id="1">first</li>
<li id="2">second</li>
<ul>
<li id="2-1">second nested first element</li>
<li id="2-2">second nested secondelement</li>
<li id="2-3">second nested thirdelement</li>
<ul>
<li id="2-3-1">Other</li>
</ul>
</ul>
<li id="3"i>third</li>
<li id="4">fourth</li>
</ul>
Each element has an id that indicates the position within the list. How do I generate it automatically?
Thank you.
UPDATE:
html is generated by Apache velocity without ID. I'm trying to create a method for updating the id if you move elements with jquery sortable. The structure of the id must be "1" for the first item "1-1" for the first element of the first "li". I tried using index () but I can't generate the id in the form that I need
It's not clear what you exactly want to do here, but here's an example of generating dynamic li's with dynamic id's:
HTML:
<ul id="autoGenerated">
</ul>
JS:
for(var i = 1; i < 3 ;i++){
$("#autoGenerated").append("<li id=2-" + i + ">Testing " + i + "</li>")
}
$('#autoGenerated li').click(function(){
alert($(this).attr("id"));
})
Fiddle.

Looking for elements with specific depth in JavaScript

I need to write a function in pure JavaScript witn no framework to get all specific tags, but only from first level under parent.
For example: I need to call some function on first <ul> and get all <li> from first level of it (<li> with text 1.2 and <li> with text 2.1)
<div id="sideNavigation">
<ul>
<li class=" act open ">
1.2
<ul>
<li class=" ">
1.2
<ul>
<li class=" ">
1.3
<ul>
<li class=" ">1.4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class=" ">
2.1
<ul>
<li class=" ">2.2.1</li>
<li class=" ">2.2.2</li>
<li class=" ">2.2.3</li>
</ul>
</li>
</ul>
</div>
I've been trying to do it like this:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li");
but it returns all <li> in this div not only first level <li>. Do you have any quick method to solve my problem or do I have to implement a new function to detect depth of nodes
You can use the attribute .children to get those "li"
var firstDepthLi = document.getElementById("sideNavigation").children[0].children;
If you want a generic function you can create something like:
var getElementsByDepth = function(el, tagname, depth) {
var children = el.children;
var res = new Array();
for(var i=0; i<children.length; i++) {
if (children[i].tagName == tagname) {
res.push(children[i]);
if (depth > 0)
res.concat(getElementsByDepth(children[i], tagname, depth-1));
}
}
return res;
}
Try:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[0];
That should return the first li element out of all li's on the page. Change the zero at the end to a different number to get a different element. You could even set a variable for the value:
var liNum = 0;
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[liNum];
And in a function:
function getLi(depth) {
var specificLi = document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
return specificLi;
}
var firstLi = getLi(0);
console.log(firstLi);
<div id="sideNavigation">
<ul>
<li>First list tag</li>
<li>Second list tag</li>
<li>Third list tag</li>
</ul>
</div>
And to make the function even shorter, you could just do:
function getLi(depth) {
return document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
}
That should work. :)

How to rearrange list?

Im trying to rearrange a list. I've got for example a list with categories:
<ul class="category">
<li class="cat1 active">cat1</li>
<li class="cat2 active">cat2</li>
<li class="cat3">cat3</li>
<li class="cat4">cat4</li>
</ul>
and a list with subjects
<ul class="subjects">
<li class="sub1">sub1</li>
<li class="sub2">sub2</li>
<li class="sub3">sub3</li>
<li class="sub4">sub4</li>
<li class="sub5">sub5</li>
<li class="sub6">sub7</li>
<li class="sub7">sub7</li>
<li class="sub8">sub8</li>
</ul>
What I want to do is when a certain category has the class active, some subjects will go to the top of the list. for example like this:
<ul class="subjects">
<li class="sub3">sub3</li>
<li class="sub5">sub5</li>
<li class="sub8">sub8</li>
<li class="sub1">sub1</li>
<li class="sub2">sub2</li>
<li class="sub4">sub4</li>
<li class="sub6">sub6</li>
<li class="sub7">sub7</li>
</ul>
I can do this with this code:
if($('li.cat1').hasClass('active')){
$('.sub3, .sub5, .sub8').insertBefore($('.subjects li:first-child'));
}
But then the real problem starts when multiple categories is active. I have done it like so:
if($('li.cat1').hasClass('active')){
$('.sub3, .sub5, .sub8').insertBefore($('.subjects li:first-child'));
}
if($('li.cat2').hasClass('active')){
$('.sub3, .sub4, .sub7').insertBefore($('.subjects li:first-child'));
}
The result is this:
<ul class="subjects">
<li class="sub4">sub4</li>
<li class="sub7">sub7</li>
<li class="sub3">sub3</li>
<li class="sub5">sub5</li>
<li class="sub8">sub8</li>
<li class="sub1">sub1</li>
<li class="sub2">sub2</li>
<li class="sub6">sub6</li>
</ul>
the order is now 4,7,3,5,8. Those are the numbers that have been selected but how do I rearrange them into: 3,4,5,7,8,1,2,6? Could someone help me with this? Here is the JsFiddle http://jsfiddle.net/NTPd4/2/
You could do 2 things to make it ALL good. First, make an sort method to suit your needs (i went by alpha of inner html, pik your poison). Second, make a variable for a jQuery object you can simply add elements too.
Next, use the variable in your if statements to gather the elements you want. Then before inserting, sort them!
Example
function sortAlpha(a,b){
return a.innerHTML.toLowerCase() > b.innerHTML.toLowerCase() ? 1 : -1;
};
var activeSubjects = $();
if ($('li.cat1').hasClass('active')) {
activeSubjects = activeSubjects.add($('.sub5, .sub3, .sub8'))
}
if ($('li.cat2').hasClass('active')) {
activeSubjects = activeSubjects.add($('.sub3, .sub4, .sub7'))
}
activeSubjects.sort(sortAlpha).insertBefore($('.subjects li:first-child'));
I think the .add will sort them automigikally, but keep in mind, you could also use the sort function straightforward, like:
$('.sub5, .sub3, .sub8').sort(sortAlpha);
Also, for your current setup (where all text is same except for number) you could use a sort function like:
function sortNum(a,b) {
return parseInt($(a).text().substring(3)) - parseInt($(b).text().substring(3));
}
However, the sortAlpha will probably better suite your needs in the long run. As I mentioned before, you can arrange your sort function how you like.
If you want all five elements in their original order, you need to move them at the same time. Use .add() to combine them:
$('.sub3, .sub5, .sub8').add('.sub3, .sub4, .sub7').prependTo($('.subjects'));
Or, integrating it into your code:
var $selector = $();
if ($('li.cat1').hasClass('active')) {
$selector = $selector.add('.sub3, .sub5, .sub8');
}
if ($('li.cat2').hasClass('active')) {
$selector = $selector.add('.sub3, .sub4, .sub7');
}
$selector.prependTo('.subjects');
http://jsfiddle.net/mblase75/GYfpv/

Populate menu with a text file eg text.txt

I am trying to build a kiosk on a local machine only. I'm planning to use JavaScript to make the menu lists functional. Here is my html code example.
<ul class="sf-menu">
<li class="current">
Area1
<ul>
<li>
John's Store
</li>
<li class="current">
Katy's store
<ul>
<li class="current">Orange</li>
<li>Watermelon</li>
<li>Apple</li>
</ul>
</li>
<li>
Catherine's Store
<ul>
<li>Banana</li>
<li>Pear</li>
<li>Cherry</li>
</ul>
</li>
</ul>
</li>
<li>
Area2
<ul>
<li>
Peter
<ul>
<li>Apple</li>
<li>Rockmelon</li>
</ul>
</li>
<li>
Lynda
<ul>
<li>Strawberry</li>
<li>Jackfruit</li>
<li>Orange</li>
</ul>
</li>
</ul>
</li> <!--current-->
</ul> <!--sf-menu-->
The person who is going to update/change the menu(which is going to be massive) is going to use a simple text file eg notepad - .txt (for certain reasons). Is there any way to update the menu items with a simple text file? Can I use a JavaScript or jQuery plugin/code?
Any direction would be appreciated.
You can do this using .get:
var textFile = "SCHEME://DOMAIN/FILENAME.txt";
jQuery.get(textFile, function(textFileData) {
//Parse file and populate menu based on specs.
//textFileData will have the text
}
If you want the text back for each line you can do (assuming the names are separated by a newline):
var EachLineInTextFile= textFileData.responseText.split("\n");
for (var i = 0, len = EachLineInTextFile.length; i < len; i++)
{
//This will give you each name from here you can put the name where you want it
}
A sample would be:
<script type="text/javascript">
$(document).ready(function () {
var textFile = "http://localhost/MyDomain/Menu.txt";
jQuery.get(textFile, function (textFileData) {
var EachLineInTextFile = textFileData.responseText.split("\n");
for (var i = 0, len = EachLineInTextFile.length; i < len; i++) {
STORE_TO_REPLACE = EachLineInTextFile[i];
//STORE_TO_REPLACE: I would have to the entire format of your file to do this.
}
})
});
</script>
From here, if you need help replacing the values in your list take a look at this article
Or, if you want to replace them all you can use .each to iterate through your list.

Categories

Resources