How do I put the created input into the other div in situation I presented below? If I introduce divs in js like this - '<div class="monday_input"><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>' removing the whole element is not working for some reason in this specific case. Answering the question. No I cannot create div in parent in html because input won't magically suit to created div . Please help me somehow, thank you!
HTML:
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus"></i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
JavaScript:
Function to adding:
function add_monday() {
if (monday_sub_count < 5) {
monday_sub_count++;
{
const mon = document.createElement('div');
mon.className = 'subcategory';
mon.innerHTML = '<textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" />';
monday_id_count++;
document.getElementById('mon').appendChild(mon);
}
}
}
Function to removing:
function removeMon(mon) {
document.getElementById('mon').removeChild(mon.parentNode);
monday_sub_count--;
monday_id_count--;
};
with your own HTML
function add_monday() {
var monday_sub_count = 0;
var a;
while (monday_sub_count < 5) {
a = '<div><textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>';
monday_sub_count++;
$('#mon').append(a);
}
}
Here is working, "proper" version of your code. I think your problem may come from over-complicating the removal process.
function add_monday()
{
let monday_count = 0;
// Use DocumentFragment for marginal optimizations
let fragment = new DocumentFragment();
while(monday_count < 5)
{
let monday = document.createElement('div');
monday.classList.add('subcategory');
let textarea = document.createElement('textarea');
textarea.classList.add('subcategory_text');
textarea.name = "monday_"+monday_count;
textarea.placeholder = "Type anything you want here";
let removeBtn = document.createElement('input');
removeBtn.type = "button";
removeBtn.classList.add('remove_button');
removeBtn.value = "-";
removeBtn.addEventListener('click', removeMon.bind(null, removeBtn));
monday.append(textarea, removeBtn);
fragment.appendChild(monday);
monday_count++;
}
document.getElementById('mon').appendChild(fragment);
}
function removeMon(button)
{
button.parentElement.remove();
}
I simplified your script a little and changed your name attributes: Instead of assigning individual names I simply gave all textareas the name monday[]. When posting this to a PHP page the values will be pushed into an array with the same name and in case you want to harvest the values with JavaScript, then this can be done easily too.
function add_monday(){
$("#mon").append('<div><textarea name="monday[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/></div>'.repeat(5))
}
$("#mon").on("click","input[type=button]",function(){$(this).parent(). remove()})
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
And here a non-jQuery version:
const ad=document.querySelector(".alldays");
ad.innerHTML=
"Mon,Tues,Wednes,Thurs,Fri,Satur,Sun".split(",").map(d=>`
<div class="day">
<div class="day_info"><p>${d}day</p></div>
<div class="add">
<div class="button">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="${d.toLowerCase().substr(0,3)}">
<div style="clear:both"></div>
</div>`).join("");
function add2day(el,n){
const wd=el.closest(".day"),
d=wd.querySelector("p").textContent.toLowerCase(),
html=`<textarea name="${d.toLowerCase()}[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/>`;
while (n--) {
let div= document.createElement("div");
div.innerHTML=html;
wd.nextElementSibling.appendChild(div);
}
}
ad.addEventListener("click",function(ev){
const el=ev.target;
switch(el.tagName){
case "INPUT": // remove field
el.parentNode.remove(); break;
case "I": // add new fields
add2day(el,3); break;
}
})
<div class="alldays"></div>
I extended the second script to make it work for any day of the week.
Related
I want to insert the card into container using javascript. How do I do it. or make those card display in flex. So it's not like shown in below pic. I have used insertAdjancentHTML to insert the data in note class using javascript. However i'm unable to put them in container.
const addBtn = document.getElementById("add");
const addNewNote = (text = "") => {
const note = document.createElement("div");
note.classList.add("note");
const htmlData = `<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-primary">
<i class="bi bi-trash"></i>
</button>
</span>
</div>
<hr />
<p class="card-text">
Some quick example text to build on the card title and make up the
bulk of the card's content.
</p>
</div>
</div>`;
note.insertAdjacentHTML("afterbegin", htmlData);
console.log(note);
document.body.appendChild(note);
};
addBtn.addEventListener("click", () => {
addNewNote();
});
Firstly, just use innerHTML - it's an empty element:
note.innerHTML = htmlData;
Secondly, you need to select the element to append this note to. Add an ID:
<div class="container d-flex" id="noteContainer">
And append it like so:
document.getElementById("noteContainer").appendChild(note);
You can add an identifier to the div an use the appendChild to this div instead of the body of the document
<div id="myDiv" class="container d-flex"></div>
And at the end of your function
document.getElementById("myDiv").appendChild(note);
Working example
const button = document.getElementById("addButton")
const addNote = () => {
const myElement = document.createElement('p')
myElement.innerHTML = "Hello world !"
const div = document.getElementById("myDiv")
div.appendChild(myElement)
}
button.addEventListener("click", addNote)
<button id="addButton">Add element</button>
<div id="myDiv"></div>
Cache the container element.
Return the note HTML from the function (no need to specifically create an element - just wrap the note HTML in a .note container), and then add that HTML to the container.
(In this example I've used unicode for the icons, and a randomiser to provide some text to the note.)
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
function createNote(text = '') {
return`
<div class="note">
<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">🖉</button>
<button class="btn btn-primary">🗑</button>
</span>
</div>
<hr />
<p class="card-text">${text}</p>
</div>
</div>
</div>
`;
};
function rndText() {
const text = ['Hallo world', 'Hovercraft full of eels', 'Two enthusiastic thumbs up', 'Don\'t let yourself get attached to anything you are not willing to walk out on in 30 seconds flat if you feel the heat around the corner'];
const rnd = Math.round(Math.random() * ((text.length - 1) - 0) + 0);
return text[rnd];
}
addBtn.addEventListener('click', () => {
const note = createNote(rndText());
container.insertAdjacentHTML('afterbegin', note);
});
<div>
<button type="button" class="add">Add note</button>
<div class="container"></div>
</div>
When I create a form with the write () command, then I want to delete it, but I can't. What is the cause of this problem?
In order to do this correctly, what command should I use or what should I change in my code?
var btn = document.querySelector('#btn');
var btn_alert = document.querySelector('#btn-alert');
var content = document.querySelector('.popup-container');
var div1 = document.getElementById('div1');
function message(message, btn) {
document.write('<div id="div1"><div id="content" class="popup-container"><div class="box-item"><div class="icon-success"><span class="span1"></span> <span class="span2"></span><div class="ring"></div></div><h2 class="alert-title">Good job!</h2><div class="alert-content">' + message + '</div><div class="actions-btn"><button onclick="ok()" class="btn-alert" id="btn-alert">' + btn + '</button></div></div></div></div>')
}
function ok() {
div1.removeChild(content);
}
<button class="btn-alert" id="btn">OK</button>
<!-- <div id="content" class="popup-container dis-active">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">is ok.</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">OK</button>
</div>
</div>
</div> -->
<script src="script.js"></script>
<script>
message("خوش اومدی!", "کلیک کن");
</script>
document.write is really outdated. In your script you write the elements to the document after you're trying to retrieve them. That won't work.
Here is an example snippet using insertAdjacentHTML to create a message element with a button to remove it.
It is generally not a good idea to use inline event handlers. The snippet uses event delegation to handle button clicks.
It may be wise to first learn more about html document manipulation or javascript.
document.addEventListener(`click`, handle);
const create = () => message(`خوش اومدی!`,`کلیک کن`);
create();
function handle(evt) {
if (evt.target.id === `btn-alert`) {
document.getElementById('div1').remove();
}
if (evt.target.id === `recreate`) {
create();
}
}
function message(message, btnTxt) {
document.body.insertAdjacentHTML(`beforeEnd`, `
<div id="div1">
<div id="content" class="popup-container">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">${message}</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">${btnTxt}</button>
</div>
</div>
</div>
</div>`);
}
<button id="recreate">(re)create message</button>
again, probably a terrible title - but what I'm trying to do is to make a simple search feature on my website. You click a nav button, which updates the search bar, whi in turn triggers an onchange event to update the current appended list.
function update() {
var list = $("#comic__modern-list");
list.empty();
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var filter = comics[this].type;
var publisher = comics[this].publisher;
if (search == "") {
if(filter == "modern") {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
} else if (search == publisher) {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
});
}
The current list is generated by this, which works fine:
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var currentObject2 = comics[this].type;
console.log(currentObject2);
if (search == "") {
if(currentObject2 == "modern") {
var list = $("#comic__modern-list");
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
}
});
From what I can gather, this has to do with the keyword "this" no longer meaning what it did when it was outside of the function, so I'm assuming the fix will be to do with bind(), but I can't make heads nor tails of it.
p.s, if there's an easier/simpler way to set up a search system, please enlighten me!
I'm trying to make each button increase the numbers in the input in his own div but doesn't work.
var c = 0;
$(".up").click(function() {
var vote = document.getElementById('vote');
$(vote).find(".counter").val(c);
c++;
});
$(".down").click(function() {
var vote = document.getElementById('vote');
$(vote).find(".counter").val(c);
c = c - 1;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div id="vote">
<button class="up">up</button>
<input class="counter">
<button class="down">down</button>
</div>
<div id="vote">
<button class="up">up</button>
<input class="counter">
<button class="down">down</button>
</div>
</div>
To group multiple elements, use class property.
Your code seemed to had multiple errors, I've resolved them by using .siblings() and .closest() methods!
$(".up").click(function() {
var vote = $(this).closest('.vote'); // find the closest div
var c = $(this).siblings('.counter').val(); // get current value
$(vote).find(".counter").val(++c); // increment and set again
});
$(".down").click(function() {
var vote = $(this).closest('.vote'); // find the closest div
var c = $(this).siblings('.counter').val(); // get current value
$(vote).find(".counter").val(--c); // decrement and set again
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div class="vote"> <!-- use class instead of id -->
<button class="up" id='1'>up</button>
<input class="counter" value='0'> <!-- Set initial value to 0 -->
<button class="down">down</button>
</div>
<div class="vote"> <!-- use class instead of id -->
<button class="up" id='2'>up</button>
<input class="counter" value='0'> <!-- Set initial value to 0 -->
<button class="down">down</button>
</div>
</div>
An id should be unique per page, so you should only have one. The getElementById method is returning the first value of vote that it finds since it's only expecting one.
I've added a few modifications to your code to separate the two fields. I did it a bit of a long way just to help with understanding. I gave your elements each an id to make them all unique from one another. I also moved your calculations up in your click handlers so you don't get the weird add/subtract behavior.
var c1 = 0;
$("#up1").click(function() {
var vote1 = document.getElementById('vote1');
c1++;
$(vote1).find("#counter1").val(c1);
});
$("#down1").click(function() {
var vote1 = document.getElementById('vote1');
c1 = c1 - 1;
$(vote1).find("#counter1").val(c1);
});
var c2 = 0;
$("#up2").click(function() {
var vote2 = document.getElementById('vote2');
c2++;
$(vote2).find("#counter2").val(c2);
});
$("#down2").click(function() {
var vote2 = document.getElementById('vote2');
c2 = c2 - 1;
$(vote2).find("#counter2").val(c2);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="votewrap">
<div id="vote1">
<button id="up1">up</button>
<input id="counter1">
<button id="down1">down</button>
</div>
<div id="vote2">
<button id="up2">up</button>
<input id="counter2">
<button id="down2">down</button>
</div>
</div>
It might sound stupid , but i didn't find the correct way to achieve this . I want to create an element(in our example a div element) and add to it the textarea value . In my example it seems that the element is created but i cant embed it into the #notesPosition . I achieve this with JQuery but i`am not sure whats the best way to do it with pure Javascript.
var notesPositionToAdd = document.getElementById('notesPosition');
var notesTextareaBtn = document.getElementById('btnAddNotes');
notesTextareaBtn.addEventListener('click', function(e) {
e.preventDefault();
var notesTextarea = document.getElementById('addNotesTextarea').value;
console.log(notesTextarea);
var newEl = document.createElement('div');
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
console.log(newEl);
});
<div class="row ">
<div class="col-lg-4 col-md-4 col-sm-4 col-12 offset-md-8 ">
<form id="newNoteForm">
<div class="form-group offset-lg-6">
<i class="fa fa-times text-md-right " aria-hidden="true"></i>
<label for="addNotesTextarea">Add notes !</label>
<textarea class="form-control" id="addNotesTextarea" rows="3"></textarea>
<input class="btn btn-danger btn-sm" type="submit" value="Add" id="btnAddNotes">
</div>
</form>
</div>
</div>
<div class="row" id="notesPosition">
</div>
Hello
Check if this helps:
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
console.log(newEl);
to:
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
notesPositionToAdd.append(newEl);
console.log(newEl);
I hope it helped you!
If you want to addTextNode() then you can...
var div = document.createElement('div');
var txt = document.createTextNode('Whatever Text');
div.appendChild(txt);
alternatively
var div = document.createElement('div')
div.innerHTML = 'Whatever Text' // Whatever text parsed, <p>Words</p> is OK
alternatively
var div - document.createElement('div')
div.textContent = 'Whatever' // Not parsed as HTML