Javascript get id number from a class name with parseint - javascript

Using Javascript, i am trying to extract a number from an element that looks like this
document.getElementById("mybutton").addEventListener("click", function() {
console.log("Button clicked")
parent = this.parentNode;
console.log(parent);
value = parseInt(parent);
console.log(value);
});
#mybutton {
padding: 20px;
background: gold;
}
<div class="myelement myid-364444-number">
<div id="mybutton">
Button
</div>
</div>
I am getting NaN everytime, where am I goind wrong?

The simplest way, for this specific example is to use a regular expression on the className of the parent node.
document.getElementById("mybutton").addEventListener("click", function() {
console.log("Button clicked")
const parent = this.parentNode;
console.log(parent);
const value = parseInt(parent.className.match(/\d+/));
console.log(value);
});
#mybutton {
padding: 20px;
background: gold;
}
<div class="myelement myid-364444-number">
<div id="mybutton">
Button
</div>
</div>

Related

How do I get the ViewButton to not copy the old note.value

//javascript, this is where I'm having the issue
const form = document.querySelector("#Form");
const note = document.querySelector("#Note");
const table = document.querySelector("#noteTable");
const count = 0;
form.addEventListener("submit", (e) => {
e.preventDefault();
if (note.value !== '') {
const btn = document.createElement("button");
btn.innerHTML = "View Details";
const row = table.insertRow();
const noteRow = row.insertCell();
const viewD = row.insertCell();
noteRow.innerHTML = note.value;
viewD.append(btn);
model.append(note.value);
note.value = "";
btn.addEventListener("click", () => {
model.classList.add("show");
});
const close = document.querySelector("#close");
close.addEventListener("click", () => {
model.classList.remove("show");
});
} else {
alert("Write a note!");
}
});
css button {
color: black;
background-color: green;
}
body {
background-color: rgb(182, 215, 227);
min-height: 100vh;
margin: 0;
}
.model-container {
background-color: rgba(245, 222, 179, 0.38);
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
height: 100vh;
width: 100vh;
opacity: 0;
pointer-events: none;
}
.model {
background-color: white;
}
.model-container.show {
pointer-events: auto;
opacity: 1;
}
.open:hover {
cursor: pointer;
color: white;
}
td {
display: block;
}
<h2>NOTE TAKER</h2>
<h6>Add A New Note:</h6>
<form id="Form" action="#">
<label class="ntag" for="note">Note:</label>
<input class="ntag" name="note" id="Note" type="text" placeholder="Write a note">
<button id="Add">Add Note</button>
</form>
<div class="theTable">
<table id="noteTable">
<tr id="Headers" class="headers">
<th></th>
</tr>
</table>
</div>
<div class="model-container" id="model">
<div class="model">
<button class="close" id="close">Close Me</button>
</div>
</div>
I'm not sure why but the notes repeat in the model-container, after you make another note the first one is still there with the second one right after it.
I thought that it could be the placement, so i put it in the btn function, but it duplicated as well; also sorry for how ugly this is, I'm just focused on the JavaScript
If you inspect the source after adding a few notes, you'll notice that it looks like this, assuming I added notes "one", "two" and "three":
It's putting it there because of this line of javascript:
model.append(note.value);
The .append() method doesn't wipe out anything in the <div id="model">, it just adds on to whatever is in there by dumping it after the button or dumping after any existing text.
To avoid erasing the "Close Me" button you'll probably want another div specifically for the text so that instead of using .append() you can just set the .textContent of the element each time. This would be destructive in a way that you wouldn't want to do this on the parent element, because it would wipe out the button. .append() is what is retaining the previous stuff when you click "View Detail."
<div class="model-container" id="model">
<div class="model">
<button class="close" id="close">Close Me</button>
</div>
<div id="txtDetails"><div>
</div>
So instead of using .append() just set the text of <div id="txtDetails"> to what you want it to say by setting the .textContent.
I also added a "data-text" attribute to the button on creation so it would be easier to fish out the text instead of navigating the parent elements and across elements.
Finally, on the click listener event I made it take whatever is stored in the "data-text" attribute and place that into <div id="txtDetails"> so that each "View Details" click would only show what is relevant for that particular note. This method is destructive in that it wipes out and replaces anything in <div id="txtDetails"> with each click but leaves the button in the modal alone.
const form = document.querySelector("#Form");
const note = document.querySelector("#Note");
const table = document.querySelector("#noteTable");
const count = 0;
form.addEventListener("submit", (e) => {
e.preventDefault();
if(note.value !== '')
{
const btn = document.createElement("button");
btn.innerHTML = "View Details";
btn.setAttribute('data-text', note.value);
const row = table.insertRow();
const noteRow = row.insertCell();
const viewD = row.insertCell();
noteRow.innerHTML = note.value;
viewD.append(btn);
note.value = "";
btn.addEventListener("click", () => {
document.getElementById('txtDetails').textContent = btn.getAttribute('data-text');
model.classList.add("show");
});
const close = document.querySelector("#close");
close.addEventListener("click", () => {
model.classList.remove("show");
});
}
else{
alert("Write a note!");
}
});
https://jsfiddle.net/tnqp8L0x/

Move button when clicked

How do I move the button from the div with id of two to the div with id of one when I click the button?
<div id="one">
</div>
<div id="two">
<button onclick="moveMe"></button>
</div>
function moveMe() {
// ??
}
We can do this using removeChild and appendChild js features. Provided an example below with working code.
const one = document.getElementById("one");
const two = document.getElementById("two");
const allButtons = document.getElementsByTagName("button");
for(let i = 0; i < allButtons.length; i++) {
const btn = allButtons[i];
btn.addEventListener("click", function(e) {
const el = e.currentTarget;
const newParent = el.parentNode.id == "one" ? two : one;
el.parentNode.removeChild(el);
newParent.appendChild(el)
});
}
.section {
height: 100px;
width: 150px;
padding: 4px;
margin: 5px;
float: left;
}
#one {
background: #CCC;
}
#two {
background: #eee;
}
button {
margin: 2px;
padding: 4px;
}
<h3>Toggle button between container on click</h3>
<div>
<div class="section" id="one"></div>
<div class="section" id="two"> <button>Move me 1</button> <button>Move me 2</button></div>
</div>
function moveMe() {
const divTwo = document.getElementById("two")
const divOne = document.getElementById("one")
const newButton = document.createElement("button")
newButton.innerText = "Click me"
divOne.appendChild(newButton)
divTwo.children[1].remove()
}
<div id="one">
<p>
div one
</p>
</div>
<div id="two">
<p>
div two
</p>
<button onclick="moveMe()">Click me</button>
</div>
You can try this:
// select the elements
const button = document.querySelector('button');
const firstDiv = document.getElementById('one');
// add eventListener
button.addEventListener('click', moveButton);
// move the button
function moveButton() {
firstDiv.append(button);
}
<div id="one">
</div>
<div id="two">
<button id="btn" onclick="moveMe">MoveMe</button>
</div>
function moveMe() {
var divOne = document.querySelector("#one");
var btn = document.querySelector("#btn");
divOne.appendChild(btn);
}
You can use code below to move the element.
There's some changes that I made on your code,
you can use version 1 or version 2
the changes on first version is i add "id" attribute on the element so we don't resort to use the tag only as selector, of course you can also use #two>button to make it more precise
the changes on second version is i add a parameter to your function this time it will handle the current element using "this" keyword when calling the function
function moveMe(){
// one.appendChild(document.querySelector("button"));
one.appendChild(move);
}
function moveMeV2(element){
one.appendChild(element);
}
<div id="one">
<span>one</span>
</div>
<div id="two">
<span>two</span>
<button id="move" onclick="moveMe()">Move Me</button>
<button onclick="moveMeV2(this)">Move Me V2</button>
</div>

JavaScript delete modal onclick and decrease counter

I want to make a basic inbox function. It contains 3 messages.
So I want to make that when the user click onto the DELETE button, set the msg1's display to none, and decrease the messages value.
Here is the example code:
var x = 2;
function deleteMsg1() {
var msg1 = document.getElementsByClassName("cont");
if (confirm("Are you sure to want to delete this message?")) {
msg1[0].style.display = "none";
x = x-1;
} else {
}
}
function deleteMsg2() {
var msg2 = document.getElementsByClassName("cont2");
if (confirm("Are you sure to want to delete this message?")) {
msg2[0].style.display = "none";
x = x-1;
} else {
}
}
document.getElementById("msgcount").innerHTML = x;
.cont, .cont2 {
background-color: red;
padding: 5px;
width: 100px;
margin: 25px 0;
}
.show {
display: block;
}
<h1>There are <span id="msgcount"></span>messages</h1>
<button onclick="deleteMsg1()">Delete</button>
<div class="cont">
Some text...
</div>
<br><br>
<button onclick="deleteMsg2()">Delete</button>
<div class="cont2">
Some text...
</div>
I know this isn’t the best idea, but I guess it’s bad.
I think I should do this with one function() and try something event listener but I don't really know how to do that.
Any idea or help?
You should wrap each message's HTML in a parent element so that you can then treat each set of elements that comprise a message as a single unit and delete it all at once.
To be able to do this with a single function, you can use this to reference the element that triggered the callback function in the first place and .closest() to access the single parent wrapper.
Notes:
Do not use inline HTML event attributes, like onclick.
Separate your HTML and your JavaScript and use .addEventListener()
to bind elements to event callbacks. Even MDN recommends not using
them.
Do not use .getElementsByClassName() as it is a 25+ year old
API that has significant performance implications. Instead, use the
modern .querySelectorAll() method.
Do not use .innerHTML if you can avoid it as it has security and
performance implications. Since the text you are wanting to update
doesn't have any HTML in it anyway, .innerHTML is not warranted.
Instead, use .textContent.
// Do your event binding in JavaScript, not HTML
document.querySelectorAll("button").forEach(function(element){
element.addEventListener("click", function(){
if (confirm("Are you sure to want to delete this message?")) {
// All you need to do is delete the nearest complete
// ancestor message construct, which can be done with
// the .closest() method
this.closest(".message").remove();
updateMessageCount();
}
});
});
function updateMessageCount(){
// Set the count equal to the length of the
// collection returned by searching for all the
// messages
document.getElementById("msgcount").textContent =
document.querySelectorAll(".message").length;
}
updateMessageCount();
.cont, .cont2 {
background-color: red;
padding: 5px;
width: 100px;
margin: 25px 0;
}
.show {
display: block;
}
<h1>There are <span id="msgcount"></span> messages</h1>
<!-- By wrapping each message, you can treat all its HTML
as one single unit. -->
<div class="message">
<button>Delete</button>
<div class="cont">
Some text...
</div>
</div>
<br><br>
<div class="message">
<button>Delete</button>
<div class="cont">
Some text...
</div>
</div>
Explained
Here's a simple enough solution, you need to update the HTML manually every time you want to update the value of x. That's why I created an updateX function, it'll just take the value & update the DOM, it's quite that simple.
const updateX = (x) => {
document.getElementById("msgcount").innerHTML = x;
};
let x = 2;
const del = (className) => {
const msg = document.getElementsByClassName(className);
if (confirm("Are you sure to want to delete this message?")) {
msg[0].style.display = "none";
x--;
} else {
console.log("===");
}
updateX(x);
};
updateX(x);
.cont,
.cont2 {
background-color: red;
padding: 5px;
width: 100px;
margin: 25px 0;
}
.show {
display: block;
}
<h1>There are <span id="msgcount"></span>messages</h1>
<button onclick="del('cont')">Delete</button>
<div class="cont">
Some text...
</div>
<br/><br/>
<button onclick="del('cont2')">Delete</button>
<div class="cont2">
Some text...
</div>
My advice to you: Never declare events js inside html structure tags! As here:
<button onclick="deleteMsg1()">Delete</button>
This is a very bad practice. This has many disadvantages. And this can lead to bad consequences.
I made a solution for you with the forEach() method, without using javascript in html.
The Delete button is also removed.
let msg = document.querySelectorAll(".cont");
let btn_del = document.querySelectorAll('.btn_del');
let x = 2;
btn_del.forEach(function (btn_del_current, index) {
btn_del_current.addEventListener('click', function () {
if (confirm("Are you sure to want to delete this message?")) {
this.style.display = "none";
msg[index].style.display = "none";
x = x - 1;
document.getElementById("msgcount").innerHTML = x;
} else {}
});
});
.cont, .cont2 {
background-color: red;
padding: 5px;
width: 100px;
margin: 25px 0;
}
.show {
display: block;
}
<h1>There are <span id="msgcount"></span>messages</h1>
<button class="btn_del">Delete</button>
<div class="cont">
Some text...
</div>
<br><br>
<button class="btn_del">Delete</button>
<div class="cont">
Some text...
</div>

Giving a div a style on click

applying a class to an element only when clicked
You could make 2 different click functions. One for trap and one for the rest.
For that you need to know which ones are the other ( safe ones ). See otherDivsIds in the below code. You find the other id's using the filter function in the idArray and then loop through them ( with forEach or something else ) and add event listeners to each of them.
I would also suggest to ' swap ' the naming of the variables trapBox and trapId. Vice versa would be better
See code below
var idArray = ['one','two','three','four'];
var trapBox = idArray[Math.floor(Math.random() * idArray.length)];
var trapId= document.getElementById(trapBox);
trapId.addEventListener('click', boomClickFunction, false);
var otherDivsIds = idArray.filter(id => id !== trapBox);
otherDivsIds.forEach(id => {
safeBox = document.getElementById(id);
safeBox.addEventListener('click', safeClickFunction, false)
})
var timeoutId = window.setTimeout(ticker, 5000);
function ticker() {
document.getElementById('timesUp').innerHTML = "Time's up!";
document.body.style.backgroundColor = "black";
}
function boomClickFunction() {
this.classList.add('boom')
}
function safeClickFunction() {
this.classList.add('safe')
}
div {
width: 20px;
height: 20px;
background-color: green;
margin: 20px;
float: left;
}
.boom {
background-color: red;
}
.safe {
background-color: lightblue;
}
#timesUp {
color: white;
}
<div id='one'>
</div>
<div id='two'>
</div>
<div id='three'>
</div>
<div id='four'>
</div>
<span id="timesUp">
</span>
You can add a class to an element by using classList.add('classToBeAdded').
In your case, you could put it in your clickFunction:
trapId.classList.add('boom');

How to create a function to get next id of element in jquery and call this function?

I've created a custom function goToNext() it's just supposed to alert the id of the next element that i've clicked on.
I want to call this custom function inside another click function.
For now when I click on first element it alerts id_2 (next from the first, so it's ok) but if you click the second element it doesn't return id_3 (like it's supposed to be) but it return id_2 same if you click on the last element (supposed to alert the first)
this is my jsfiddle example here
function goToNext() {
var get_next_id = $('.btn').next().attr("id");
alert(get_next_id);
}
$('.btn').click(function() {
goToNext();
});
.btn {
width: 50px;
height: 50px;
margin: 10px auto;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="btn" id="id-1">
1
</div>
<div class="btn" id="id-2">
2
</div>
<div class="btn" id="id-3">
3
</div>
Try this
function goToNext($btn){
var get_next_id = $btn.next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext($(this));
});
You have to use this
function goToNext(thisObj){
var get_next_id = $(thisObj).next().attr("id");
if(get_next_id!=undefined)
alert(get_next_id);
else
alert($(thisObj).parents().find("div:first").attr("id"));
}
$('.btn').click(function(){
goToNext(this);
});
.btn{
width:50px;
height:50px;
margin:10px auto;
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class ="btn" id="id-1">
1
</div>
<div class ="btn" id="id-2">
2
</div>
<div class ="btn" id="id-3">
3
</div>
You need to use reference this
function goToNext(e){
var get_next_id = $(e).next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext(this);
});
Updated Fiddle

Categories