dynamic add and remove list group with input javascript - javascript

I am quite new to javascript and was wondering if anyone can help with an issue I am having. I want to dynamically add and remove from a list group with inputs. I have worked out the mechanic's from a script floating around the internet but having issues with getting the input as part of the add remove method.
see below.
<script type="text/javascript">
function addItem(){
var ul = document.getElementById("selectme-list");
var selectme= document.getElementById("selectme");
var li = document.createElement("li");
li.className = "list-group-item";
li.setAttribute('id',selectme.value);
li.setAttribute('name','codeal[]');
li.setAttribute('value',selectme.value);
li.appendChild(document.createTextNode(selectme.value));
ul.appendChild(li);
}
function removeItem(){
var ul = document.getElementById("selectme-list");
var selectme = document.getElementById("selectme");
var item = document.getElementById(selectme.value);
ul.removeChild(item);
}
</script>
This script adds and removes the LI fine. But I want to have the input hold the information.
I want example: <li class="list-group-item"><input id="RM" name="codeal[]" value="RM"/>RM</li>
Currently getting example: <li class="list-group-item" id="RM" name="codeal[]" value="RM">RM</li>
Any help would be much appreciated thanks

Try creating a new input node as you created list and append it to list node as child element.
function addItem(){
var ul = document.getElementById("selectme-list");
var selectme= document.getElementById("selectme");
var li = document.createElement("li");
li.className = "list-group-item";
li.setAttribute('id',selectme.value);
x = document.createElement("INPUT");
x.setAttribute('name','codeal[]');
x.setAttribute("type", "text");
x.setAttribute("value", selectme.value);
li.appendChild(x);
ul.appendChild(li);
}

Related

Finding which row has been selected in a getmdl-select

I have the following code to populate a drop down using getmdl-select
var ul = document.getElementById('allocateToUL');
result.forEach(function (u) {
var li = document.createElement('li');
var dataVal = document.createAttribute('data-value');
var dataSelector = document.createAttribute('data-selector');
dataVal.value = u.Id;
dataSelector.value = u.Id;
li.innerText = u.FriendlyName;
li.className = 'mdl-menu__item';
li.setAttributeNode(dataVal);
li.setAttributeNode(dataSelector);
ul.appendChild(li);
// note call getmdlSelect.init once item is added
getmdlSelect.init('.getmdl-select');
componentHandler.upgradeAllRegistered();
});
What I do not seem to be able to do is find out which option is selected here;
I have tried
document.getElementsByClassName('mdl-menu').find('li.active')
But that just tells me 'find' is not a function although it getElements.... does return list of elements.
Any suggestions?
It looks like you want to use the jQuery find method, but you are not using a jQuery selector. Try replacing:
document.getElementsByClassName('mdl-menu').find('li.active')
With:
$('.mdl-menu').find('li.active')

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.

Add multiple Li to Ul with javascript

With the onclick event I am trying to add mutliple LIs to UL, It wont add more than one Li with this method no matter how many appendChilds I do.
var form = document.getElementById("form");
var newUl = document.createElement('ul');
var newLi = document.createElement('li');
newButton.addEventListener("click", function(){
form.appendChild(newUl);
newUl.id = "formList";
var formList = document.getElementById("formList");
formList.appendChild(newLi);
formList.appendChild(newLi);
formList.appendChild(newLi);
}
//// html
<div id="form">
</div>
newLi is a reference to the node you wish to append to the formList. It can exist just once.
So, first time it executes formList.appendChild(newLi), it will append it to formList. Second time it executes, it would be removed from the first position and now added to second position. Same for third position.
You cannot append the same node multiple times using appenChild.
The Node.appendChild() method adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position (there is no requirement to remove the node from its parent node before appending it to some other node). This means that a node can't be in two points of the document simultaneously. So if the node already has a parent, the node is first removed, then appended at the new position.
Description at MDN
You have to make a separate element each time.
Try this:
var form = document.getElementById("form");
function newLi() {
return document.createElement("li");
}
newButton.addEventListener("click", function(){
//Create a separate <ul> each time, give it a class, and add it.
var newUl = document.createElement("ul");
newUl.class = "formList";
form.appendChild(newUl);
//create new <li>'s and append them
formList.appendChild(newLi());
formList.appendChild(newLi());
formList.appendChild(newLi());
//smile. :D
}
Unlike Muhammad, I assume that you want to create a separate unordered list (<ul>) each time.
Hence, whenever the button is clicked, we add a new <ul> and then append our <li>s into the new <ul>.
var form = document.getElementById("form");
var newUl = document.createElement('ul');
newUl.id = "formList";
form.appendChild(newUl);
newButton.addEventListener("click", function(){
var newLi = document.createElement('li');
newUl.appendChild(newLi);
})
You need to create the ul once, and assign to it the id = "formList", then append it to the form
On every click, create new li element
You don't need to select the ul again, because you already has a reference to it.
Here you can find a working fiddle https://jsfiddle.net/LeoAref/m5d0bzeL/
There's too much to correct in your post all at once. But if you're trying to template your LI, you can clone it using cloneNode
var template_ul = document.createElement('ul');
var template_li = document.createElement('li');
let newButton = document.getElementById('new');
var count = 0;
newButton.addEventListener("click", function() {
let list = template_ul.cloneNode();
document.getElementById('form').appendChild(list);
let first_li = template_li.cloneNode();
var text = document.createTextNode(++count);
first_li.appendChild(text);
list.appendChild(first_li);
list.appendChild(template_li.cloneNode());
list.appendChild(template_li.cloneNode());
});
body {
text-align:center;
}
button { margin: 4px auto 1em; }
ul {
margin: 0 auto 1em;
padding: 0;
width: 50%
}
ul:nth-child(2n) li{
background:#c90;
}
li {
list-style-type: none;
background: #09c;
height: 20px;
padding: 2px;
}
ul,
li {
border: 1px solid #444;
}
<button id="new">New</button>
<div id="form">
</div>
function addNode(){
var x = document.createElement("ul");
x.setAttribute("id","myList");
document.body.appendChild(x);
var myListItem = document.createElement("li");
var textNode = document.createTextNode("List Item one");
var t2 = document.createTextNode("second item");
myListItem.appendChild(textNode);
document.getElementById("myList").appendChild(newLi("FirstItem"));
document.getElementById("myList").appendChild(newLi("Second Item"));
document.getElementById("myList").appendChild(newLi("Third Item"));
document.getElementById("myList").appendChild(newLi("Fourth Item"));
}
//function which generates a new li tag and accepts a string for TextNode
function newLi(x)
{
var m = document.createElement("li");
var t = document.createTextNode(x);
m.appendChild(t);
return m;
}

Adding dynamically <li> in javascript

I'm trying to add elements dynamically in an ul with ajax and my current code is this in ajax method:
var ul = document.getElementById("menu");
var li = document.createElement("li");
li.appendChild(document.createTextNode(array[i]));
ul.appendChild(li);
But it creates "standard" li elements, i want to create them in this type:
<li style="cursor:pointer;"><a onclick="javascript:$('#cod').val(array[i])">array[i]</a></li>
How can i do this?
[EDIT]
What i want to create is THIS (you can see that it appears a "shadow" that signify it is selectable
But jvascript creates this type of OPTIONS,
now you can see that the options doesn't got that "shadow".
How i understand content for this <%=IDAnag%> insert your back end. And when you click on link this content has already been generated. Maybe you can try something like that:
function AppendLi(val){
var ul = document.getElementById("menu");
var li = document.createElement("li");
li.innerHTML= val;
ul.appendChild(li);
}
<li style="cursor:pointer;">
<a onclick="AppendLi(this.textContent)">
<%=IDAnag%>
</a>
</li>
<ul id="menu"></ul>
But I do not know how you have built the your backend. maybe best way add this event on backend side?
I solved the problem by myself, if someone needed here is the code:
var ul = document.getElementById("menu");
var li = document.createElement("li");
$("li").each(function()
{
var $li = $(this);
$li.css("cursor","pointer");
});
var a = document.createElement("a");
var l = array[i];
a.textContent = array[i];
a.addEventListener("click",function(){
$("#cod").val(array[i]);
});
li.appendChild(a);
ul.appendChild(li);

Dynamically inserting elements so they can still be deleted

I want to dynamically add textboxes so each textbox added appears as the last in the list but above the button. I also want a button allowing the deletion of each textbox. The code below adds the textboxes just as I want, but when clicking on "Remove Field" only that text is removed. The textbox associated with that text remains. This DOES work if I don't use "insertBefore" so I'm thinking that messes up what "removalLink" knows what to delete?
<script>
var namesCount = 0;
listNames = function (){
var field_area = document.getElementById("fields");
var li = document.createElement("li");
var input = document.createElement("input");
input.id = "txtName"+namesCount;
input.name = "txtName"+namesCount;
input.type = "text";
li.appendChild(input);
field_area.appendChild(li);
//INSERT ELEMENT JUST BEFORE ADD BUTTON
sp2 = document.getElementById("btnNames");
parentDiv = sp2.parentNode;
parentDiv.insertBefore(input, sp2);
//create the removal link
var removalLink = document.createElement("a");
removalLink.onclick = function(){
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode("Remove Field");
removalLink.appendChild(removalText);
li.appendChild(removalLink);
field_area.appendChild(li);
//INSERT ELEMENT JUST BEFORE ADD BUTTON
var sp2 = document.getElementById("btnNames");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(div, sp2);
namesCount++
}
</script>
<body>
<ul id="fields">
Add More Names
</ul>
</body>
Since you've tagged jQuery, I'd suggest using it to significantly simplify your code.
First, fix your HTML so all the children of the <ul> are <li> tags like this:
<ul id="fields">
<li>Add More Names</li>
</ul>
And, then you can replace the entire listNames() function with this much simpler version that doesn't have your issue. I use the .closest("li") method to find the parent <li> tag to remove no matter how many parents above it is located which helps to prevent simple errors or dependencies on the exact HTML layout (e.g. it makes the code less fragile or prone to mistakes):
<script>
var nameCount = 0;
function listNames() {
var id = "txtName" + nameCount;
var li = $("<li>");
$("<input/>", {type: "text", name: id, id: id}).appendTo(li);
$("<a>Remove Field</a>").click(function() {
$(this).closest("li").remove();
}).appendTo(li);
li.insertBefore("#fields li:last");
nameCount++;
}
</script>
Working demo: http://jsfiddle.net/jfriend00/tjb24/
As I show in the demo link, you can also get rid of the onclick handler from the HTML and just hook up to it with an event listener, otherwise referred to as unobtrusive javascript where you separate the HTML from the javascript.
If you still want it all in plain javascript, you can do this:
<ul id="fields">
<li id="fieldAdd>Add More Names</li>
</ul>
<script>
var nameCount = 0;
document.getElementById("btnNames").addEventListener("click", function(e) {
var id = "txtName" + nameCount;
var li = document.createElement("li");
var input = document.createElement("input");
input.type = "text";
input.name = input.id = id;
li.appendChild(input);
var removeLink = document.createElement("a");
removeLink.innerHTML = "Remove Field";
removeLink.addEventListener("click", function(e) {
this.parentNode.parentNode.removeChild(this.parentNode);
e.preventDefault();
});
li.appendChild(removeLink);
var fields = document.getElementById("fields");
var fieldAdd = document.getElementById("fieldAdd");
fields.insertBefore(li, fieldAdd);
nameCount++;
e.preventDefault();
});
</script>
Working demo: http://jsfiddle.net/jfriend00/gTWqu/

Categories