I'm new to all of this so please bear with me...
I have a Bootstrap 3 modal window that opens up with a few form fields in it. I've managed to append the form fields to the DOM after you click Submit New Appointment. Buuut I can't seem to figure out how to close the modal window after the fields have been appended to the DOM. I'm hoping to achieve this by writing some good ole vanilla JavaScript. (Unfortunately I cannot use any jQuery.)
I have included the vanilla JavaScript code below. (It basically creates an appointment card from the info inputed from the form thats in the modal and then it gets displayed as a card into the DOM.)
Thanks for taking a look!
var form = document.getElementById('addForm');
// element to append the new carousel item to
var itemList = document.querySelector('.carousel-inner');
// form submit event
form.addEventListener('submit', addItem);
// form delete event
itemList.addEventListener('click', removeItem);
// add item Function
function addItem(e) {
e.preventDefault();
// get input value in the modal
var newItem = document.getElementById('item').value;
var newItemTwo = document.getElementById('time').value;
var newItemThree = document.getElementById('name-of-client').value;
var newItemFour = document.getElementById('phone-number-client').value;
var newItemFive = document.getElementById('acces-notes').value;
// create a new li element with the text grab from above
var li = document.createElement('li');
/**
* Set the correct class name for the carousel to work
*/
// li.className = 'list-group-item';
li.className = 'item';
li.style.maxWidth = '95%';
li.style.border = 'solid 1px #d3d3d3';
li.style.padding = '10px';
li.style.height = '150px';
li.style.marginRight = '12%';
li.style.marginLeft = '12%';
li.style.fontWeight = '500';
li.style.fontSize = '14px';
// console.log(li)
// create a new p element with the text grab from above
var pOne = document.createElement('p');
pOne.className = 'items';
pOne.style.fontSize = '12px';
pOne.style.fontWeight = '400';
pOne.style.marginTop = '5px';
var pTwo = document.createElement('p');
pTwo.className = 'items';
pTwo.style.fontSize = '12px';
pTwo.style.fontWeight = '200';
console.log(pTwo)
var pThree = document.createElement('p');
pThree.className = 'items';
pThree.style.fontSize = '12px';
pThree.style.fontWeight = '200';
console.log(pThree)
var pFour = document.createElement('p');
pFour.className = 'items';
pFour.style.fontSize = '12px';
pFour.style.fontWeight = '200';
console.log(pFour)
// add text node with input value
li.appendChild(document.createTextNode(newItem));
pOne.appendChild(document.createTextNode(newItemTwo));
pTwo.appendChild(document.createTextNode(newItemThree));
pThree.appendChild(document.createTextNode(newItemFour));
pFour.appendChild(document.createTextNode(newItemFive));
// create delete BUTTON
var deleteBtn = document.createElement('button');
deleteBtn.style.width = '50px';
deleteBtn.style.float = 'right';
deleteBtn.style.height = '50px';
deleteBtn.style.borderRadius = '50%'
deleteBtn.style.border = 'solid 1px red';
deleteBtn.style.backgroundColor = 'white';
deleteBtn.style.color = 'red';
// add the classes to the delete BUTTON
deleteBtn.className = "btn btn-danger btn-sm float-right delete";
// append the text node
deleteBtn.appendChild(document.createTextNode('X'));
// append delete button into the LI
li.appendChild(deleteBtn);
// append li to list.
/**
* insert the new element at the beginning of the itemList element, not at the end
*/
// itemList.appendChild(li);
itemList.insertBefore(li, itemList.firstChild);
// append p elements into LI; (not sure if this is the best way but its working)
li.appendChild(pOne);
li.appendChild(pTwo);
li.appendChild(pThree);
li.appendChild(pFour);
li.appendChild(pFive);
}
// remove item function
function removeItem(e) {
console.log(e.target)
if (e.target.classList.contains('delete')) {
if (confirm('Are you sure bro?')) {
var li = document.querySelector('.item.active');
itemList.removeChild(li);
document.querySelector('.item').classList.add('active')
}
}
}
Image of the modal from Bootstrap 3
Related
I'm creating some elements using JS, and need to add a class to each item when clicked, but remove it from the non clicked items. I'm sure this is a quick one, but I can't get my head around it.
let data = {
label:label,
somethingElse:"test",
id:id
};
sidebarOptions.push(data);
let ul = document.querySelector(".page-sidebar__options");
sidebarOptions.forEach(sidebarOption => {
let li = document.createElement('li'),
button = document.createElement('button'),
title = document.createElement('span'),
price = document.createElement('span')
ul.appendChild(li);
li.appendChild(button);
button.appendChild(title);
button.appendChild(price);
title.innerHTML = sidebarOption.label + sidebarOption.id;
price.innerHTML = '[Price]';
button.onclick = (event) => {
button.classList.add('selected');
};
})
So find if you have a selected button and remove the class
const currentlySelected = ul.querySelector('button.selected');
if (currentlySelected) currentlySelected.classList.remove('selected');
Now I am doing a shopping cart in my project, when i click the add to cart button, then it will upload the data in localstorage, then i will create an element (product name, price, quantity and two increment and decrement button in the list) and this create process will be looped by the length of localstorage.
When I want to make click event on increment and decrement button, only the last row of increment and decrement button respond. For example, I have 3 rows in shopping cart, only the third row will show the proper result, the first two row have no response.
I would like to ask can you give me some suggestion, how to achieve my goal? Thanks!!!!!!!!!!!!!!
var ul = document.getElementById("cart")
for(var i=0;i<localStorage.length;i++){
var li = document.createElement("li");
var addBtn =document.createElement("BUTTON");
var dropBtn document.createElement("BUTTON");
addBtn.innerHTML = '+';
dropBtn.innerHTML = '-';
addBtn.id='addBtn'
var a = document.getElementById("addBtn")
addBtn.onclick = function(){
alert('here be addBtn');return false;
};
dropBtn.onclick = function(){
alert('here be dropBtn');return false;
};
ul.appendChild(addBtn);
ul.appendChild(dropBtn);
ul.appendChild(li);
}
You need to make some changes to work as expected:
Not to search/find button when you have its reference.
append a button to list i.e. li not to ul (Thanks CBroe).
I've taken some assumption like the localStorage length as 3 and added the text of the cart button.
const ul = document.querySelector("ul#cart");
for (var i = 0; i < 3; i++) {
var li = document.createElement("li");
var addBtn = document.createElement("BUTTON");
var dropBtn = document.createElement("BUTTON");
var text = document.createElement("span");
text.textContent = ` item${i+1} `
addBtn.innerHTML = '+';
dropBtn.innerHTML = '-';
addBtn.id = `addBtn${i+1}`;
dropBtn.id = `dropBtn${i+1}`;
addBtn.addEventListener('click', e => {
alert(`here be addBtn with id ${e.target.id}`);
})
dropBtn.addEventListener('click', e => {
alert(`here be dropBtn with id ${e.target.id}`);
})
li.appendChild(addBtn);
li.appendChild(text);
li.appendChild(dropBtn);
ul.appendChild(li);
}
<ul id="cart"></ul>
Pardon the bad title, it's hard to explain. If you know how to phrase it better, please comment and I will update as soon as I can.
So, I was messing around with a random generator site (perchance.org) and writing my own HTML/Javascript to make my generator work. It has a behavior that is what I want, but that shouldn't be happening according to my knowledge of HTML.
Let me explain with a minimal example.
The example code here is to produce a simple page that has a button.
This button should generate <input>s with <button>s next to them, attached with similar ID's.
The button, when clicked, deletes the <input> and <button>.
Here is a snippet to show you the code/let you reproduce the results:
<html>
<head>
<script>
var current_id = 0;
function add_input () {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + current_id;
delete_button.id = "button_" + current_id;
br.id = "br_" + current_id;
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.onclick = function () {
delete_input(this.id.slice(7)) //To get the numerical ID
}
list.appendChild(input);
list.appendChild(delete_button);
list.appendChild(br);
current_id++;
}
function delete_input (id) {
var input = document.getElementById("input_"+id);
var button = document.getElementById("button_"+id);
var br = document.getElementById("br_"+id);
input.remove();
button.remove();
br.remove();
current_id--;
}
</script>
</head>
<body>
<div id="list">
</div>
<button onclick="add_input()">Add</button>
</body>
</html>
When you add two inputs, then delete the first, and add one more, it leaves you with two inputs using the same ID. It also leaves you with two buttons with the same ID. And yet, both buttons delete their intended target.
Why?
You really should delegate - here I wrap in a div that can be removed in one go
You can rename each input to have incremented IDs but just letting the cnt run, gives you unique IDs
let cnt = 0;
function add_input() {
var list = document.getElementById("list");
var div = document.createElement("div");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + (cnt++)// list.querySelectorAll("div").length
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.classList.add("delete")
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div);
}
window.addEventListener("load", function() {
document.getElementById("list").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("delete")) tgt.closest("div").remove();
})
})
<div id="list">
</div>
<button onclick="add_input()">Add</button>
I changed your code to be more effective.
I'm not using IDs as they aren't adding any benefit instead making it more complex.
Instead I target the element via the event handler and an argument.
I also wrap each set of inputs/buttons in a div so I can just remove that div and it will remove all of the children.
function add_input() {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
delete_button.textContent = "Delete";
delete_button.onclick = function(e) {
e.target.parentNode.remove();
}
var div = document.createElement("div");
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div)
}
<div id="list">
</div>
<button onclick="add_input()">Add</button>
What i want to do is....when the counter button is clicked....increment a span to see how many times its been clicked but also create a new counter with its own incrementor
I have it somewhat working but when i create a new button....the counter doesnt work
anyone help me out with what im missing?
this is also done in vanilla js and html
template:
<div class="container">
<button type="button" id="increase" onClick="increaseCounter()">click</button>
<span id="amount"></span>
</div>
JS:
var counter = 0
function increaseCounter() {
let button = document.getElementById("increase");
let span = document.getElementById("amount");
counter += 1;
span.innerHTML = counter;
createNewButton();
}
function createNewButton() {
let container = document.getElementsByClassName("container")[0];
let btn = document.createElement("button");
btn.innerHTML = "new button";
btn.id = "increase";
container.appendChild(btn);
let span = document.createElement("span");
span.innerHTML = 0;
span.id = "amount";
container.appendChild(span);
}
LINK: https://codepen.io/zomdar/pen/ZEGPxNP?editors=1011
Here is a few things you should look for:
1- The event listener is only affected to the first button you assign as it is an inline event listener. So new buttons won't have the event listener.
2- If you want to have a new span containing the amount everyone, you must have a different ID for each span (or set the innerHTML directly as I did) or it will be the same span changing.
Note - The ID attribute should be unique in the page, every time you create a button the same ID is attributed. You should use the class attribute (non-unique value) or a different ID every time (e.g. "amount"+counter)
function increaseCounter() {
let button = document.getElementById("increase");
let span = document.getElementById("amount");
counter += 1;
// span.innerHTML = counter;
createNewButton();
}
function createNewButton() {
let container = document.getElementsByClassName("container")[0];
let btn = document.createElement("button");
btn.innerHTML = "new button";
btn.id = "increase"; // UNIQUE ID !!!
btn.onclick = increaseCounter;
container.appendChild(btn);
let span = document.createElement("span");
span.innerHTML = counter;
span.id = "amount";
container.appendChild(span);
}
You can pass along the element that was clicked as a parameter of the increaseCounter function and then get the nextElementSibling of that (the span associated with it), grab the innerHTML (current count) of it, then increment it by 1. This will prevent you from having to fetch the elements by id (as mentioned in the answer by clota974, you want your id's to be unique). You were also missing adding the onclick function for the buttons you were creating as well.
References:
https://www.w3schools.com/jsref/prop_element_nextelementsibling.asp
https://www.w3schools.com/jsref/event_onclick.asp
Here's the example code:
function increaseCounter(el) {
/* increment the span associated with this button (nextElementSibling is the span) */
el.nextElementSibling.innerHTML = parseInt(el.nextElementSibling.innerHTML) + 1;
createNewButton();
}
function createNewButton() {
let container = document.getElementsByClassName("container")[0];
let btn = document.createElement("button");
btn.innerHTML = "new button";
btn.onclick = function() {
increaseCounter(this);
};
container.appendChild(btn);
let span = document.createElement("span");
span.innerHTML = 0;
container.appendChild(span);
}
<div class="container">
<button type="button" onClick="increaseCounter(this)">click</button>
<span>0</span>
</div>
Hello i have the following code : http://jsfiddle.net/yw7Zk/
var makeAreaEditable = function(event){
var btn = event.target,
li = btn.parentNode,
p = li.getElementsByClassName('paratext')[0];
p.style.display="none";
btn.innerText="Ok";
btn.onclick = saveEdit;
var textareaEdit = document.createElement('textarea');
textareaEdit.className = 'testarea';
li.appendChild(textareaEdit);
textareaEdit.appendChild(p);
textareaEdit.style.display="block";
};
The problem is that i want the paragraf display: none when i press the button edit but i want it displaied in the textarea.. so please help
Try changing:
textareaEdit.appendChild(p);
into:
textareaEdit.value = p.innerHTML;