Updating js variables - javascript

I have dynamically updated list. Each list element has text input and delete button. I have 2 problems:
when I delete a list item, leninputs in cloneLi doesn't change
when I enter a text value in the first list item, it is copied also to the new one (i tried also elmtInput.reset(), but no change)
Do you have an idea what's wrong?
html code:
<ul id="sortable">
<li>
<div class="row">
<input type="text" id="item1" name="item1" value="">
<div>
<a class="btn" onclick="this.parentElement.parentElement.parentElement.style.display = 'none';"><i class="fas fa-trash"></i></a>
</div>
</div>
</li>
</ul>
<input type="submit" value="New item" class="btn" onclick="cloneLi()">
js:
function cloneLi() {
leninputs = document.getElementsByTagName("input").length;
if (leninputs < 5) {
var ul = document.getElementById("sortable");
var elmnt = ul.getElementsByTagName("li")[0];
var cln = elmnt.cloneNode(true);
document.getElementById("sortable").appendChild(cln);
var elmtInput = document.getElementsByTagName("input")[leninputs];
elmtInput.setAttribute("name", "item"+(leninputs+1).toString());
elmtInput.setAttribute("id", "item"+(leninputs+1).toString());
elmtInput.setAttribute("value", "");
} else {
alert('Max number of items reached!');
}
}

You need to exclude the button input from gettting selected with the other input elements, so be more precise in your selecting, and that will make your condition to have only five inputs as max instead of four correct because you were counting one plus input, you need to delete the li element instead of just hiding it and that keeps its input element as it is, you need to change the value of each new input cloned to avoid cloning the value as well
var listsContainer = document.querySelector("#sortable");
document.querySelector("#add_item").onclick = function() {
var inputLen = document.querySelectorAll("#sortable input").length, newList;
if(inputLen === 5) {
return alert('Max number of items reached!');
}
newList = document.createElement("li");
newList.innerHTML = `
<div class="row">
<input type="text" id="item${++inputLen}" name="item${inputLen}" value="">
<div>
<a class="btn" onclick="this.parentElement.parentElement.parentElement.remove();"><i class="fas fa-trash"></i></a>
</div>
</div>`;
listsContainer.appendChild(newList);
}
ul {
list-style-type: none;
margin: 0 0 10px 0;
padding: 0;
width: 300px;
}
.row {
background-color: lightgreen;
display: flex;
align-items: center;
border-radius: 10px;
padding: 10px;
margin-bottom: 5px;
}
.row div {
display: inline-block;
}
.row div i {
font-size: 20px;
color: white;
text-shadow: 0 0 5px green;
cursor: pointer;
}
.row input {
width: 85%;
margin-right: 10px;
border: none;
border-bottom: 1px solid #777;
}
#add_item {
display: none;
}
label {
background-color: #ccc;
color: white;
font: bold 24px monospace;
padding: 5px;
border-radius: 5px;
box-shadow: inset 1px 1px 3px #fff;
cursor: pointer;
}
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<ul id="sortable">
<li>
<div class="row">
<input type="text" id="item1" name="item1" value="">
<div>
<a class="btn" onclick="this.parentElement.parentElement.parentElement.remove();"><i class="fas fa-trash"></i></a>
<div>
</div>
</li>
</ul>
<label for="add_item"><input id="add_item" type="submit" class="btn">New item <i class='far fa-plus-square'></i></label>

Related

In Blogger, Hide/Show Quiz Answers based on button click with javascript

I have a quiz blog/website on blogger. To show the answers of questions I have following html code:
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
And JavaScript like this:
<script type='text/javascript'>
//<![CDATA[
var acc = document.getElementsByClassName("acc");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var pnl = this.nextElementSibling;
if (pnl.style.display === "block") {
pnl.style.display = "none";
} else {
pnl.style.display = "block";
}
});
}
//]]>
</script>
And CSS like this:
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
If some one clicks on all of the buttons, the buttons are acting as toggles rather than, showing one answer, then when the next button is clicked, hiding the previous answer and showing the new one in its place. What needs to be changed to enable this?
Thanks
Remove the buttons.
Add the following over each .pnl
<!-- #ids must be unique so btn* = btn1, btn2, etc -->
<!-- [for] of label must match #id of input -->
<input id='btn*' class="acc" name='acc' type='radio' hidden>
<label for='btn*'>Show Answer</label>
Explination: A label and a form control (ex. <input>, <select>, etc) can be associated with each other if the form control has an #id and the label has a [for] that match. If one gets clicked, checked, etc then the other one does as well.
Add the following CSS:
.acc:checked+label+.pnl {
display: block
}
Explination: If an input is checked then the .pnl that is front of the label that is in front of the input. Note, when a group of radio buttons share a [name] only one may be checked at a time. Also, the radio buttons are hidden so it looks as if the label is the only tag interacting with the user.
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
.acc:checked+label+.pnl {
display: block
}
label {
display: block
}
<input id='btn1' class="acc" name='acc' type='radio' hidden>
<label for='btn1'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn2' class="acc" name='acc' type='radio' hidden>
<label for='btn2'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn3' class="acc" name='acc' type='radio' hidden>
<label for='btn3'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
Try this one by using a forEach.
var acc = document.getElementsByClassName("acc");
let pn1 = document.getElementsByClassName("pnl");
for (let i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
[...acc].forEach((item,index) =>{
if(item == acc[i]){
pn1[index].style.display = "block";
}else{
pn1[index].style.display = "none";
}
})
})
}
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>

Is there any way to simplify the Javascript part on this Dropdown list example?

Is there any way to simplify and make the JavaScript part of this code less complicated?
I have a div acting as a dropdown list.
Once the list item is selected, it updates the input text field with the selection, and the dropdown button as well.
$("#dropdown-list-item1").click(function() {
$("#dropdown-value").val("Item1");
$("#dropdown-button-label").text("Item1");
$("#dropdown-list").hide();
$("#dropdown-list-item1").addClass("active");
$("#dropdown-list-item2").removeClass("active");
$("#dropdown-list-item3").removeClass("active");
$("#dropdown-list-item4").removeClass("active");
$("#dropdown-list-item5").removeClass("active");
$("#dropdown-list-item6").removeClass("active");
$("#dropdown-list-item7").removeClass("active");
$("#dropdown-list-item8").removeClass("active");
});
});
https://jsfiddle.net/2reza3L6/2/
Of course.
$("#dropdown-list-item1").click(function() {
$("#dropdown-value").val("Item1");
$("#dropdown-button-label").text("Item1");
$("#dropdown-list").hide();
$("#dropdown-list-item1").addClass("active");
for(var i = 1; i <= 8; i++)
$("#dropdown-list-item"+i).removeClass("active");
});
You can use the selector [id^="dropdown-list-item"] to select all elements which have an ID which starts with dropdown-list-item:
$("#dropdown-list-item1").click(function() {
$("#dropdown-value").val("Item1");
$("#dropdown-button-label").text("Item1");
$("#dropdown-list").hide();
$("[id^='dropdown-list-item']").removeClass("active");
$("#dropdown-list-item1").addClass("active");
});
But it would be better to use classes instead - numeric indexed IDs are quite a code smell.
Or, you could use #dropdown-list > div to select all the children:
<div class="active">
Item1
</div>
<div>
Item2
</div>
<div>
Item3
</div>
and
const items = $("#dropdown-list > div");
items.click(function() {
const index = items.index(this) + 1;
$("#dropdown-value").val("Item" + index);
$("#dropdown-button-label").text("Item" + index);
$("#dropdown-list").hide();
items.removeClass("active");
$(this).addClass('active');
});
$("#dropdown-list").hide();
$("#dropdown-button").click(function() {
$("#dropdown-list").toggle();
});
const items = $("#dropdown-list > div");
items.click(function() {
const index = items.index(this) + 1;
$("#dropdown-value").val("Item" + index);
$("#dropdown-button-label").text("Item" + index);
$("#dropdown-list").hide();
items.removeClass("active");
$(this).addClass('active');
});
#dropdown {
cursor: pointer;
width: 200px;
font-family: sans-serif;
line-height: 21px;
font-size: 14px;
margin-left: calc(50% - 100px);
margin-top: 50px;
}
#dropdown-button {
border: 1px solid #0168FA;
background-color: #0168FA;
color: #FFF;
border-radius: 3px;
text-align: center;
padding: 5px;
}
#dropdown-list {
margin-top: 25px;
background-color: #FFF;
border: 1px solid #8392A545;
text-align: center;
border-radius: 3px;
}
#dropdown-list-item1,
#dropdown-list-item2,
#dropdown-list-item3,
#dropdown-list-item4,
#dropdown-list-item5,
#dropdown-list-item6,
#dropdown-list-item7,
#dropdown-list-item8 {
padding: 5px;
margin: 5px;
border: 1px solid #FFF;
}
#dropdown-list-item1:hover,
#dropdown-list-item2:hover,
#dropdown-list-item3:hover,
#dropdown-list-item4:hover,
#dropdown-list-item5:hover,
#dropdown-list-item6:hover,
#dropdown-list-item7:hover,
#dropdown-list-item8:hover,
.active {
border: 1px solid #0168FA !important;
background-color: #0168FA;
color: #FFF;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="dropdown-value" value="Item1">
<div id="dropdown">
<div id="dropdown-button">
<div id="dropdown-button-label">
Item1
</div>
</div>
<div id="dropdown-list">
<div class="active">
Item1
</div>
<div>
Item2
</div>
<div>
Item3
</div>
<div>
Item4
</div>
<div>
Item5
</div>
<div>
Item6
</div>
<div>
Item7
</div>
<div>
Item8
</div>
</div>
</div>

Item list container problem in javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to arrange the list in such a way that the items only allow to grow the container from the bottom and make scroll bar appear.
CODE : https://codepen.io/Redd_1/pen/qBZWJQG
You can simple set height on ul and set overflow-y: auto to make sure that newly added items are staying within the ul and not moving the whole container.
Demo
//Add item to list
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
form.addEventListener('submit', addItem);
function addItem(e) {
e.preventDefault();
//User input
var newItem = document.getElementById('item').value;
document.getElementById('item').value = ''
if (newItem == '') {
alert('Please enter some value.')
} else {
//Adding values to the list
var li = document.createElement('li');
li.className = 'list-group-item';
li.appendChild(document.createTextNode(newItem));
//Add a delete button
var deletebtn = document.createElement('button');
deletebtn.className = 'btn';
deletebtn.appendChild(document.createTextNode('X'));
//Append button and li to the ul
li.appendChild(deletebtn);
itemList.appendChild(li);
}
}
//Remove item from list
itemList.addEventListener('click', removeItem);
function removeItem(e) {
if (e.target.classList.contains('btn')) {
if (confirm('Are you sure you want to delete the item?')) {
var li = e.target.parentElement;
itemList.removeChild(li);
}
}
}
//Search items
var filter = document.getElementById('filter');
filter.addEventListener('keyup', filterItems);
function filterItems(e) {
var text = e.target.value.toLowerCase();
var items = itemList.getElementsByTagName('li');
Array.from(items).forEach(function(item) {
var itemName = item.firstChild.textContent;
if (itemName.toLowerCase().indexOf(text) != -1) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
})
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Montserrat;
}
header {
background-color: green;
color: white;
margin: 0;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.container {
padding: 20px;
position: fixed;
width: 500px;
left: 50%;
top: 55%;
transform: translate(-50%, -50%);
line-height: 40px;
border: 1px solid black;
border-radius: 10px;
}
ul {
overflow-y: auto;
list-style: none;
padding: 10px;
height: 10em;
}
.list-group-item {
border: 1px solid grey;
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
}
.btn {
background-color: red;
color: white;
border: none;
border-radius: 5px;
padding: 6px;
}
.sbtn {
color: white;
background-color: rgb(46, 46, 46);
text-transform: uppercase;
cursor: pointer;
border: none;
padding: 8px;
}
.sbtn:hover {
background-color: black;
}
button {
float: right;
}
input[type=text] {
padding: 5px;
}
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="itemApp.css">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#300;400;500;600;700&display=swap" rel="stylesheet">
<header>
<h1>Item lister</h1>
<input type="text" class="search-bar" placeholder="Search items..." id="filter">
</header>
<div class="container">
<h3>Add items</h3>
<form id="addForm" name="myForm">
<input type="text" id="item" name="textField">
<input type="submit" class="sbtn" value="submit">
</form>
<h3>Items</h3>
<ul id="items">
<li class="list-group-item">Item 1 <button class=btn>X</button> </li>
<li class="list-group-item">Item 2 <button class=btn>X</button> </li>
<li class="list-group-item">Item 3 <button class=btn>X</button> </li>
<li class="list-group-item">Item 4 <button class=btn>X</button> </li>
</ul>
</div>
<script src="itemApp.js"></script>
</body>
</html>

Showing hidden div isn't pushing down other content but is in another part of the page

I have a simple back-end for a website that contains a todo list, a history of work done in previous months (and a few other things that aren't relevant.
The todo list is made up of multiple elements dynamically loaded in using AJAX, the 'history' works the same way.
For all todo list items that haven't been checked off yet, if the user clicks the checkbox, a form is supposed to slide down below, pushing the other divs further down but for some reason they don't.
I have pretty much the exact same happening for the 'history': If a user clicks a month name, then a table slides down (using jQuery) showing all the work that was done in that month.
I made the 'history' area first and then replicated it for the todo list but for some reason, when the form slides down for a todo list item, it shows the form but sort of on top of the todo list items below. It doesn't push them down at all. Whereas if I 'open' a history table, it pushes down the other history month entries.
Here is the todo list closed and then with one item checked so the form shows (ignore the CSS issues for now, still a WIP):
Closed:
Open:
And here is the history section, first 'closed' and then with one month 'open':
Closed:
Open:
<div id="todoList-container">
<h1>Todo</h1>
<div class="todoList">
<div data-id="1">
<input style="display: none;" type="checkbox" class="todoItemCheckbox" name="todoItem0" />
<span>test 1</span>
<span style="margin-left: 20px;">Development</span>
<div class="todoForm" style="display: none;">
<form class="todoItemCompleteForm" data-id="1">
<input class="todoItemCompleteHours" type="text" placeholder="Hours">
<textarea class="todoItemCompleteDescription" placeholder="description of work"></textarea>
CompleteCancel
</form>
</div>
</div>
<div data-id="2">
<input style="display: none;" type="checkbox" class="todoItemCheckbox" name="todoItem1" />
<span>test 2</span>
<span style="margin-left: 20px;">Research</span>
<div class="todoForm" style="display: none;">
<form class="todoItemCompleteForm" data-id="2">
<input class="todoItemCompleteHours" type="text" placeholder="Hours">
<textarea class="todoItemCompleteDescription" placeholder="description of work"></textarea>
CompleteCancel
</form>
</div>
</div>
</div>
</div>
Relevant JS:
$.ajax({
url: API_URL + "todos/user/",
data: {
token: LOGIN_TOKEN,
sortCompleted: 1
},
type: "GET",
dataType: "json"
})
.done(function(json) {
for(var k = 0; k < json.length; k++) {
//Show todoList strikethrough or with hidden form.
if(json[k].status == "1") {
$('.todoList').append('<div data-id="' + json[k].ID + '"><span><strike>' + json[k].name + '</strike></span><span style="margin-left: 20px;">' + groups[parseInt(json[k].groupID)] + '</span><span style="float:right; margin-right:10px;" class="date">' + json[k].completed + '</span></div>');
}
else {
$('.todoList').append('<div data-id="' + json[k].ID + '"><input style="display: none;" type="checkbox" class="todoItemCheckbox" name="todoItem' + k + '" /><span>' + json[k].name + '</span><span style="margin-left: 20px;">' + groups[parseInt(json[k].groupID)] + '</span><div class="todoForm" style="display: none;"><form class="todoItemCompleteForm" data-id="'+json[k].ID+'"><input class="todoItemCompleteHours" type="text" placeholder="Hours" /><textarea class="todoItemCompleteDescription" placeholder="description of work"></textarea>CompleteCancel</form></div></div>');
}
}
$('.todoList').append('<div><input id="todoAddItemInput" type="text" placeholder="Todo Name" /><select><option>Development</option></select><i class="fa fa-plus"></i></div>');
})
Relevant CSS:
#todoList-container {
width: 80%;
border: 1px solid #CCC;
margin: 20px auto;
border-radius: 10px;
padding: 0 20px 40px;
}
#todoList-container h1 {
margin-top: 10px;
}
#todoList-container .todoList {
list-style-type: none;
}
#todoList-container .todoList div {
font-family: 'Lora', serif;
font-size: 18px;
padding: 2px 4px;
margin: 8px 0;
border-bottom: 1px solid #CCC;
height: 40px;
/* line-height: 40px; */
}
#todoList-container span {
vertical-align: -2px;
margin-left: 52px;
color: #333;
}
#todoList-container .todoBox+span {
margin-left: 0px;
color: #777;
}
#todoList-container .todoBox {
display: inline-block;
height: 30px;
width: 30px;
border: 1px solid #CCC;
margin-right: 20px;
border-radius: 4px;
text-decoration: none;
/* vertical-align: 3px; */
}
#todoList-container .todoBox::after {
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f00c";
color: #CCC;
z-index: 999;
top: 4px;
left: 5px;
position: relative;
font-size: 20px;
}
#todoList-container .todoBoxSelected::after {
color: #6db235;
}
#todoList-container #todoAddItemInput {
margin-left: 48px;
font-family: 'Lora', serif;
border:0;
font-size: 18px;
padding: 2px 4px;
color: #777;
border-right: 1px solid #CCC;
margin-right: 20px;
vertical-align: -4px;
}
I can't see anything different in my css or js/jQuery. Could someone help?
Thanks
Stupidly, I still had a height set for all the div children of .todoList from before I added the form and so that's what was causing the form to not 'push' the rest down.

jQuery: Can't select a new element after append

I created a structure to represent the UI Tree using jQuery. I added the ability to add a new element at any level (The "add new" button is activated when you select a level for adding).
But in my example, I can not add a new element to the newly created element. I tried different ways, but it does not work.
I'll be happy for the tips on how I can fix this problem
$(function() {
const newElement = $('#new-element');
let targetButton;
function indexOfChildren() {
$('li').prepend(function() {
let countOfChildren = $(this).children().find(">li").length;
let targetSpan = $(this).find('button>:first-child');
targetSpan.text(countOfChildren);
});
};
indexOfChildren();
$('li>button').on('focus', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$('[name="new-button"]').on('click', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
newElement.click(function() {
let name = prompt("Please enter name of new element");
let parentTargetButton = targetButton.closest('li');
let indexTargetSpan = parseInt(targetButton.find(':first-child').text());
if (name != null) {
if (indexTargetSpan == 0) {
parentTargetButton.append('<ul><li><button class="btn mb-3 mt-1" name="new-button">' + name + '<span></span></button></li></ul>');
} else {
parentTargetButton.children('ul').append('<li><button class="btn mb-3 mt-1" name="new-button">' + name + ' <span></span></button></li>');
}
}
indexOfChildren();
targetButton.focus();
});
});
body {
background-color: #f5f6f8;
}
.main-content {
background: #fff;
box-shadow: 0 5px 20px 0 #c8d2dd6e;
-webkit-box-shadow: 0 5px 20px 0 #c8d2dd6e;
border-radius: 5px;
}
.top-level {
border-bottom: 1px solid #dadee7;
}
ul {
list-style-type: none;
}
ul>li>ul {
border-left: 1px solid #eee;
margin-left: 60px;
}
ul>li>ul>li:before {
border-left: 1px solid;
}
#new-element {
background-color: #33b5ff;
color: #fff;
border-radius: 40px;
}
.main-content .btn {
box-sizing: content-box;
width: 140px;
padding: 14px;
text-align: left;
background-color: #f5f6f8;
border-radius: 7px;
}
span {
float: right;
color: #fff;
line-height: 1.4;
border-radius: 0.8em;
-moz-border-radius: 0.8em;
-webkit-border-radius: 01em;
text-align: center;
font-size: 0.9em;
width: 1.4em;
background-color: #33b5ff;
}
.btn:focus,
.btn:hover,
#new-element {
-webkit-box-shadow: 0 5px 25px 0 #9dabbb69;
*/ box-shadow: 0 5px 25px 0 #9dabbb69;
}
.main-content .btn:focus {
color: #fff;
background-color: #0095ff!important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container project-item my-3 pt-5">
<div class="row top-level pb-4">
<h3 class="col-sm-9 pl-0">New Project</h3>
<div class="col-sm-3 pr-0">
<button type="button" class="btn float-right" id="new-element" disabled>+ Add new element</button>
</div>
</div>
</div>
<div class="container main-content pt-5 mt-5 pb-5">
<ul>
<li>
<button class="btn mb-3 mt-1">Project <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">Web Design <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">CSS <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">XHTML <span></span></button>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
You can bind the .on event to the already existing parent element.
$('li').on('focus', 'button', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$(function() {
const newElement = $('#new-element');
let targetButton;
function indexOfChildren() {
$('li').prepend(function() {
let countOfChildren = $(this).children().find(">li").length;
let targetSpan = $(this).find('button>:first-child');
targetSpan.text(countOfChildren);
});
};
indexOfChildren();
$('li').on('focus', 'button', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$('[name="new-button"]').on('click', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
newElement.click(function() {
let name = prompt("Please enter name of new element");
let parentTargetButton = targetButton.closest('li');
let indexTargetSpan = parseInt(targetButton.find(':first-child').text());
if (name != null) {
if (indexTargetSpan == 0) {
parentTargetButton.append('<ul><li><button class="btn mb-3 mt-1" name="new-button">' + name + '<span></span></button></li></ul>');
} else {
parentTargetButton.children('ul').append('<li><button class="btn mb-3 mt-1" name="new-button">' + name + ' <span></span></button></li>');
}
}
indexOfChildren();
targetButton.focus();
});
});
body {
background-color: #f5f6f8;
}
.main-content {
background: #fff;
box-shadow: 0 5px 20px 0 #c8d2dd6e;
-webkit-box-shadow: 0 5px 20px 0 #c8d2dd6e;
border-radius: 5px;
}
.top-level {
border-bottom: 1px solid #dadee7;
}
ul {
list-style-type: none;
}
ul>li>ul {
border-left: 1px solid #eee;
margin-left: 60px;
}
ul>li>ul>li:before {
border-left: 1px solid;
}
#new-element {
background-color: #33b5ff;
color: #fff;
border-radius: 40px;
}
.main-content .btn {
box-sizing: content-box;
width: 140px;
padding: 14px;
text-align: left;
background-color: #f5f6f8;
border-radius: 7px;
}
span {
float: right;
color: #fff;
line-height: 1.4;
border-radius: 0.8em;
-moz-border-radius: 0.8em;
-webkit-border-radius: 01em;
text-align: center;
font-size: 0.9em;
width: 1.4em;
background-color: #33b5ff;
}
.btn:focus,
.btn:hover,
#new-element {
-webkit-box-shadow: 0 5px 25px 0 #9dabbb69;
*/ box-shadow: 0 5px 25px 0 #9dabbb69;
}
.main-content .btn:focus {
color: #fff;
background-color: #0095ff!important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container project-item my-3 pt-5">
<div class="row top-level pb-4">
<h3 class="col-sm-9 pl-0">New Project</h3>
<div class="col-sm-3 pr-0">
<button type="button" class="btn float-right" id="new-element" disabled>+ Add new element</button>
</div>
</div>
</div>
<div class="container main-content pt-5 mt-5 pb-5">
<ul>
<li>
<button class="btn mb-3 mt-1">Project <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">Web Design <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">CSS <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">XHTML <span></span></button>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>

Categories

Resources