Adding <li> to <ul> with limit (pure JS) - javascript

So I wanted to add items to a list by typing the items in an with a beside that returns the value, adds the value to the list. Which I have done... But I want to limit the amount of times I add items the list. Say I want to limit it to 5 times only. So I can basically add 5 items to a list... And that's all... Now...How do I do that?
Thx for response.
<script type="text/javascript">
var input = document.getElementById('username');
function checkLength() {
var node = document.createElement('li');
var nodeText = document.createTextNode(input.value);
var ul = document.getElementsByTagName('ul')[0];
node.appendChild(nodeText);
ul.appendChild(node);
input.value = "";
node.setAttribute('style', "color:green; text-transform:uppercase;");
}
}
</script>

You can get the number of children of a node:
var ul = document.getElementsByTagName('ul')[0];
if (ul.childNodes.length < 5) {
ul.appendChild(node);
}
Note that this counts all the child nodes not just li elements so if you have text nodes in there which I don't think you will they will be included in this count.

Related

How to separate Li items when selecting multiple options in a variable product?

I am creating a feature on a Woocommerce variable product page where a user can select an option and that option gets added to a summary of items selected. I have multiple variations on the page so I have tried to get the innerHTML of every selected target and tried to add it to the UL by dynamically creating an li and adding to it. But at the moment only one li gets created and it adds all the options selected to it. Is there a way to separate each variation into multiple li's so that it adds the selected option to its own individual li? This is what I have so far.example here. It would be greatly appreciated if I am pointed in the right direction. Thanks a lot :)
var wrappers = document.querySelectorAll('.rtwpvs-terms-wrapper');
var summary = document.querySelector('.selection-summary');
var list = document.querySelector('.selected-items');
var li = document.createElement("li");
wrappers[0].classList.remove('opacity');
let increment = 0;
wrappers.forEach((item, sel) => {
item.addEventListener('click', (e) => {
summary.style.display = 'block';
// Create li items and assign on click innerhtml
li.appendChild(document.createTextNode(e.target.innerHTML));
list.appendChild(li);
increment++;
for(var i = 0; i < wrappers.length; i++) {
wrappers[increment].classList.remove('opacity');
}
})
})
You're appending to the same li (which you created at the top level) at every iteration of your loop. You should be creating a new <li> for each item, and append said <li> to your list, like so:
// Create li items and assign on click innerhtml
const li = document.createElement("li");
li.innerHTML = e.target.innerHTML;
list.appendChild(li);
You don't need the var li = document.createElement("li"); at the top level anymore.

For loop only loops 1 time - JavaScript

Hi i am trying to make a for loop which will automatically add "dots" depending on how many images there are, i use the myArrImg.length but it only outputs a li with a class of dots once even tho it should do it four times? can anyone help me :)
var myArrImg = ['img/erftdgdf33.jpg','img/iajdi89.jpg','img/isdkfj01.jpg','img/wergf43.jpg'];
function dotsAuto(){
var test = document.getElementById('test');
var li = document.createElement('li');
li.className = 'dots';
for (i = 0; i < myArrImg.length; i++) {
test.appendChild(li);
}
}
dotsAuto();
Your problem is not what you think. The loop is operating the right number of times, but it is not doing what you intend.
The problem is that you only ever create one li element. You then repeatedly insert that same element. So the browser thinks you are doing this:
Create an li element. Give it a className. Now, start looping through the myArrImg array. On the first time, insert that li element. On the second time, insert that li element. On the third time, insert that li element. And so on.
You need to create new li elements each time, because any element can only exist once in the document. Essentially, you keep removing the element from the document and putting it back in the same place To create new elements each time, create the li within the loop:
var li;
for (i = 0; i < myArrImg.length; i++) {
li = document.createElement('li');
li.className = 'dots';
test.appendChild(li);
}
Here I created an ul since JSFiddle doesn't allow to manipulate document, but the process is the same
var myArrImg = ['img/erftdgdf33.jpg','img/iajdi89.jpg','img/isdkfj01.jpg','img/wergf43.jpg'];
function dotsAuto(){
var test = document.getElementById('test');
for (i = 0; i < myArrImg.length; i++) {
var li = document.createElement('li');
li.className = 'dots';
li.innerHTML = myArrImg[i];
test.appendChild(li);
}
}
dotsAuto();
<ul id="test">
</ul>
Basically you create ONE li for EACH loop cycle, and then append it to the list

How to append a span tag and give each id a new name

I have 3 inputs that are nestled inside a span tag (I'm using span and not li because I have many li's in my code). I have a javascript function that appends each span tag (which includes the 3 inputs). I need each input to have a specific id name. Not sure how to do this, I'm learning javascript right now so forgive me for I'm a noob.
In my function I have the appendchild working for the span tag. At the bottom of the code I have a for loop that I wrote to append an ul/li and that name works. But I can't get that same functionality to work for the span tags.
How can I append child and each time I appendchild that the inputs get a new id name?
Here is my code so far:
function budgetList(){
var elmnt = document.getElementsByTagName("SPAN")[0];
var cln = elmnt.cloneNode(true);
var budgetListing = document.getElementById("budget-listing");
var append = budgetListing.appendChild(cln);
var expenseName = document.getElementById('expenseName');
var expectedExpense = document.getElementById('expectedExpense');
var actualExpense = document.getElementById('actualExpense');
var ul = document.createElement("ul");
document.body.appendChild(li);
for(var i = 0; i <= 0; i++){
var li = document.createElement("li");
li.className = "budget-list" + i;
var a = document.createElement("a");
a.innerHTML = "<input type='text'>";
// a.innerHTML = "Subfile " + i;
var att = document.createAttribute("class");
att.value = "budgeting" + i;
li.appendChild(a);
ul.appendChild(li);
}
}
Here is the html
<button onclick="budgetList()">Add New Row</button>
<input type="button" value="save" onclick="save()" />
<ul id="budget-listing">
<span>
<input type="text" id="expenseName">
<input type="text" id="expectedExpense">
<input type="text" id="actualExpense">
</span>
</ul>
A few things...
1) <ul> stands for Unordered List and <ul> elements expect their children to be <li> elements (which you can remember as List Item). So, while some browsers may be forgiving of you appending spans to your <ul> tag, it's not considered good practice. And is technically a violation of the standard
2) Your loop will only run exactly once. You'll see it's starting with variable i initialized at 0 and will only run as long as i<=0 which will only ever be true on the first iteration because afterwards you increment (i++) which means the second time through i will equal 1 and 1 is NOT less than or equal to 0. So, in this case there's no need to use a loop at all.
3) Your code is a little disjointed from what you requested and what the page context is suggesting. It appears to me, when the user clicks the button you want to duplicate the span with 3 inputs. If this is indeed the case, then I offer the following solution...
function budgetList(){
// You get the span that will serve as a template, good
var elmnt = document.getElementsByTagName("SPAN")[0];
// you clone it, good
var cln = elmnt.cloneNode(true);
//next we want to modify the IDs of the child spans.
// A good way to do this is to use a unique number that will change with every step
// There a few ways to get a unique number each time
// I propose taking the number of span groups
var budgetListing = document.getElementById("budget-listing");
var uniqueNumber = budgetListing.childNodes.length;
// Now we update all the ids using the unique number
cln.getElementsByTagName('INPUT')[0].setAttribute('id', "expenseName_"+uniqueNumber);
cln.getElementsByTagName('INPUT')[1].setAttribute('id', "expectedExpense_"+uniqueNumber);
cln.getElementsByTagName('INPUT')[2].setAttribute('id', "actualExpense_"+uniqueNumber);
// and write our new span group into the container
budgetListing.appendChild(cln);
}
Let me know if I made any incorrect assumptions or if this is close to what you're requesting. JavaScript and its interaction with HTML can be confusing at first, but stick with it!
EDIT: Didn't realize getElementById wasn't a function... Replaced with getElementsByTagName

Change a javascript Filter List to display in a HTML drop down

I'm looking to add a HTML filter as shown in link below. I have the filter replicated from the link, but I want to modify the javascript to display in a drop down vs as a UL element: http://www.designchemical.com/lab/jquery/demo/jquery_demo_create_class_filter.htm.
<label for="solutions-filter">Topics</label><select id="solutions-filter" name="solutions-filter">
<option value="all">
All
</option>
<option value="acct_overview">
Account Overview
</option>
<option value="active_view">
Account Overview
</option>
</select>
I have bold'ed the two lines from the javascript code below that I believe I need to change to make it fit into this model, but I'm at a loss on how to change it being new to JavaScript. Does anyone have time to take a peak and see what I may need to change to add the filter into this type of drop down?
<script type="text/JavaScript">
$(document).ready(function() {
// map the classes for each item into a new array
classes = $("#demo-list li a").map(function(){
return $(this).attr("class").split(' ');
});
// create list of distinct items only
var classList = distinctList(classes);
// generate the list of filter links
**var tagList = '<ul id="tag-list"></ul>';**
tagItem = '<li>all</li>';
$.each(classList, function(index,value){
var value = value.replace("-", " ");
tagItem += '<li>'+value+'</li>';
});
// add the filter links before the list of items
**$("#demo-list").before($(tagList).append(tagItem));**
// filter the demo list when the filter links are clicked
$('#tag-list li a').live('click',function(e){
var getText = $(this).text().replace(" ", "-");
if(getText == 'all'){
$("#demo-list li a").slideDown();
} else {
$("#demo-list li a").fadeOut();
$("#demo-list li a."+getText).fadeIn();
}
// add class "active" to current filter item
$('#tag-list li a').removeClass('active');
$(this).addClass('active');
// prevent the page scrolling to the top of the screen
e.preventDefault();
});
});
// Function to create a distinct list from array
function distinctList(inputArray){
var i;
var length = inputArray.length;
var outputArray = [];
var temp = {};
for (i = 0; i < length; i++) {
temp[inputArray[i]] = 0;
}
for (i in temp) {
outputArray.push(i);
}
return outputArray;
}
</script>
Thank you so much for your time.

Split ul to more ul's with jQuery

I have made a script with jQuery. The script split a list of li's, to more ul's. When the list is moer than 10 li items the list must be split in more ul's.
I have made the script in this post.
But the script is not working. What I did wrong here.
The script is for a submenu in the navigation. When the navigation li items are more than 4 than the ul of li items must be splitted in two ul's. How can I fix this script. Thanks!
submenu();
function submenu() {
$(".submenu").each(function () {
if($("li", this).length > 4){
$(this).closest(".submenu").addClass("width-2")
var submenu = $(this).closest(".submenu");
var $bigList = $(this), group;
while((group = $bigList.find('li:lt(8)').remove()).length) {
$('<ul/>').append(group).appendTo(submenu);
}
}
if($("li", this).length > 10){
$(this).closest(".submenu").addClass("width-3")
}
});
}
I'm not entirely sure I understand what you're trying to do, but this code will split each submenu UL into more submenus of the specified size while keeping all items in the original DOM order:
function splitSubmenu(maxNumItems) {
$(".submenu").each(function () {
// get all child li tags
var list$ = $(this).children("li");
var num, nextAfter$, after$ = $(this);
// as long as the current list it too long, loop
while (list$.length > maxNumItems) {
// decide how many to remove this iteration
num = Math.min(maxNumItems, list$.length - maxNumItems);
// create new UL tag, append num items to it
// and insert it into the DOM
nextAfter$ = $('<ul class="submenu">')
.append(list$.slice(maxNumItems, maxNumItems + num))
.insertAfter(after$);
// update insertion point for next loop iteration
after$ = nextAfter$;
// remove the items we just took out from the current jQuery object
list$ = list$.filter(function(index) {
return(index < maxNumItems || index >= 2 * maxNumItems);
});
}
});
}
splitSubmenu(4);
You can see it work here: http://jsfiddle.net/jfriend00/VMjvQ/.
I did not understand what you were trying to do with the additional classes so that part is not included.

Categories