Get Text content of 3rd <p> element inside <div> element - javascript

I have some HTML / JS code looking like this.
var bTags = document.getElementsByClassName("Wrapper");
var kind = bTags[0];
console.log(kind);
console.log(kind.childNodes[4].text);
<div class="Wrapper">
<h3 class="date" id="date">{{date}}</h3>
<div class="descriptionWrapper">
<p class="jobDescription">{{job}}</p>
<p class="jobAreaDescription">{{jobArea}}</p>
<p class="placeDescription">{{ort}}</p>
<p class="kindDescription">{{anstellung}}</p>
</div>
<div class="jobLink">
{{#custom_link jobLink}}
{{linkText}}
{{/custom_link}}
</div>
</div>
In my example the "console.log(kind);" successfully logs the HTML object. Here its not working of course because its not defined.
But somehow the childNodes[0-4].text is undefined. I just want to access the text of the p element with the class "placeDescription" of this specific parentNode.

const el = document.querySelector('.Wrapper p:nth-of-type(3)');
if (el) {
console.log(el.textContent)
}

Related

TypeError: Cannot read properties of null (reading 'addEventListener') javascript

I am trying to add a button but it is showing me this error.
here is my html code
<div card-container>
<template class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</template>
</div>
here is the javascript code
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
You're using the <template> tag, which is an element that holds html markup but it's not rendered on page load.
In order to render its contents, one has to handle the <template> element via javascript, using the html structure as - in fact - a template for filling another structure (a table, a divs grid, etc.).
Since the sub-elements of <template> are not part of the DOM yet, let showDitail = document.querySelector(".btn"); will result in null. That's why you cannot bind events to it.
Either change the tag to something else (a div maybe), or handle the template properly via javascript.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
<div card-container>
<div class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</div>
</div>

Element Created by Javascript is not visually visible

So, recently I made a project where the Javascript just create an element and getting the data from Firebase Firestore database then append it to the body of HTML. This consist of a div which act as the box container with object.className, h4 act as title, some p as texts. But, all of those elements I've added isn't visible on the webpage. But surprisingly, if I open the Inspect element, and call console.log(object) of one of the object, they will show up HTML tag element that exactly what I want and when I hover it, it will show up a highlighted area in the webpage that sized exactly what I want. But, still not visually visible. Actually, in the HTML document, I've added some boxes and element before the element from Javascript, and if I add some new element from the HTML, the element from Javascript is pushed after the newly added element from HTML. So, can someone help me? I'm a newbie in this field. Thank you.
1.) Part of the HTML Element (The Firebase is well set-up here)
<body>
<div class="big-container">
<div class="title">
<span class="title-text">Kompor</span>
</div>
<nav id="wrapper">
<!-- ONE DIV CALLED "IMPORTANT" is necessary for the last box visible -->
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box 2">
<h4 class="title-box">Rinnai 522-A</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div class="box"></div>
<div class="box"></div>
<div class="important"></div>
</nav>
</div>
2.) JS
//DOMstart
const docTarget = document.querySelector('#wrapper');
function insertDoc(doc){
//creation
let box = document.createElement('div');
let header = document.createElement('h4');
let hargaBeli = document.createElement('p');
let p2 = document.createElement('p');
let hargaJual = document.createElement('p');
let p4 = document.createElement('p');
//insertion
header.textContent = doc.data().name;
hargaBeli.innerHTML = "HB";
p2.textContent = doc.data().HB;
hargaJual.innerHTML = "HJ";
p4.textContent = doc.data().HJ;
console.log(box);
console.log(header);
console.log(hargaBeli);
console.log(p2);
console.log(hargaJual);
console.log(p4);
//naming
box.classname = "box";
header.className = "title-box";
hargaBeli.className = "tc-1";
p2.className = "tc-2";
hargaJual.className = "tc-3";
p4.className = "tc-4";
//box-naming plus deletion ops
var hitung = 1;
hitung++;
console.log(hitung);
box.className = "box " + hitung;
box.onclick = function(){
if (confirm('Apa kamu yakin mau menghapus produk ini?')) {
this.parentElement.removeChild(this);
} else {
console.log('Tidak jadi menghapus produk.');
}
}
//appending...
box.appendChild(header);
box.appendChild(hargaJual);
box.appendChild(p2);
box.appendChild(hargaBeli);
box.appendChild(p4);
docTarget.appendChild(box);
console.log(box.className + "Creation Tracker"); //detection
}
//get doc
var doc;
db.collection('Product').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
insertDoc(doc);
})
})
The CSS is connected well and as you can see working well with those elements from HTML document.
As I tried your HTML and javascript code on jsbin, I see that it worked well. The problem is your variable doc, you might add console.log to get the variable again to see why, or you can paste your data structure for further debug.
https://jsbin.com/jeyamoqabu/edit?html,js,output

Performance wise and fastest way to get all element with Id inside a container element

I am trying to refactor and make a performance wise code.
The idea of the code is to update the id or value of all element with id or value that needs to be updated that happens when an element has been removed / deleted
So what I am trying to do is get all element with Id or value inside a container element (which is possible to be nested in 2 to 4).
At the moment, I am using jQuery to this task. I added a class on every element that has Id and use jQuery .find() to get all of this element using the class I've assign to them .. which is I really hate about my code and wanted to change as well if there's another best way to do it.
So is there a fastest way and performance wise at the same time to do this task?
$("button").on("click", function(){
$($(this).val()).remove();
updateParagraph();
});
function updateParagraph() {
$(".paragraphs").each(function(index, data){
var dataId = data.id.split("-");
var idIndex = dataId[dataId.length-1];
var index = index + 1;
if (index != idIndex) {
dataId.splice(-1, 1);
dataId.push(index);
dataId = dataId.join("-");
$(this).attr("id", dataId);
setChildElementsId($(this), index)
}
});
}
function setChildElementsId(parent, inx) {
$(parent).find(".id-holder").each(function(index, data){
if (data.id) {
var dataId = data.id.split("-");
dataId.splice(-1, 1);
dataId.push(inx);
dataId = dataId.join("-");
$(this).attr("id", dataId);
if(isParagraph(data.tagName)) {
$(this).text(inx);
}
}
else if (data.value) {
var dataValue = data.value.split("-");
dataValue.splice(-1, 1);
dataValue.push(inx);
dataValue = dataValue.join("-");
$(this).val(dataValue);
}
});
}
function isParagraph(tagName){
return tagName == "P";
};
<div id="container-1" class="paragraphs">
<div id="header-container-id-1" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-1" class="id-holder">
<p id="id-1" class="id-holder">1</p>
</div>
<button value="#container-1" class="id-holder">delete</button>
</div>
<div id="container-2" class="paragraphs">
<div id="header-container-id-2" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-2" class="id-holder">
<p id="id-2" class="id-holder">2</p>
</div>
<button value="#container-2" class="id-holder">delete</button>
</div>
<div id="container-3" class="paragraphs">
<div id="header-container-id-3" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-3" class="id-holder">
<p id="id-3" class="id-holder">3</p>
</div>
<button value="#container-3" class="id-holder">delete</button>
</div>
<div id="container-4" class="paragraphs">
<div id="header-container-id-4" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-4" class="id-holder">
<p id="id-4" class="id-holder">4</p>
</div>
<button value="#container-4" class="id-holder">delete</button>
</div>
<div id="container-5" class="paragraphs">
<div id="header-container-id-5" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-5" class="id-holder">
<p id="id-5" class="id-holder">5</p>
</div>
<button value="#container-5" class="id-holder">delete</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If I understand your question correctly, you're looking to more elegantly identify which elements have an id of the form "__-id-#" or simply "id-#".
If this is the case, take a look at some more advanced jQuery selectors. One in particular which might meet your needs is the Attribute Contains Selector.
For instance, I think $(parent).find("[id*='id-']") might do what you're looking to do.
While I understand what you're attempting to do, I don't quite understand why you're doing this in the first place.
Unless there are restrictions that force you to structure your HTML like you did, well, don't. Aim for the simplest structure:
<div id="container-123" class="paragraphs">
<h4>Header</h4>
<p>1</p>
<button type="button">delete</button>
</div>
Remove the <div>s around the <h4> and the <p> unless you need them for some styling reason. The <button> doesn't need to know its ID, because it's a child element of the container, so you're delete handler could make use of that fact:
$(document.body).on("click", "button", function() {
$(this).closest('.paragraphs').remove();
});
If there are outside forces that require a specific ID (e.g. for linking to an anchor), keep that on the top container element. If your CSS targets elements by ID, refactor the CSS.
I would like to answer your question using javascript. In fact you don't need any of those id-s
I hope I'm not too late.
let buttons = Array.from(document.querySelectorAll(".id-holder"));
buttons.forEach(b => {
//for each button add an event listener
b.addEventListener("click", () => {
b.parentElement.parentElement.removeChild(b.parentElement);
resetNums();
});
});
function resetNums(){
// reseting the text inside the p
let btns = Array.from(document.querySelectorAll(".id-holder"));
btns.forEach((bt,i)=>{
let theP = bt.parentElement.querySelector("p");
theP.innerHTML = i+1;
})
}
<div>
<div>
<h4>Header1</h4>
</div>
<div>
<p>1</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header2</h4>
</div>
<div>
<p>2</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header3</h4>
</div>
<div>
<p>3</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header4</h4>
</div>
<div>
<p>4</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header5</h4>
</div>
<div>
<p>5</p>
</div>
<button class="id-holder">delete</button>
</div>

jquery get value of next instance of class

I am trying to use jQuery to get the value of the divs with the classes of more_details_con, more_details_desc and more_details_res and when edit_entry is clicked but I don't think I am traversing the DOM correctly because the alert just says undefined.
The HTML
<div class="details">
<span class="id">1234</span>
<span class="contact">account name</span>
</div>
<div class = "more_details">
<div class = "more_details_btns">
<div class="go_account">Go to Account</div>
<div class="edit_entry">Edit</div>
<div class="delete_entry">Delete</div>
</div>
<div class="container">
<div class="more_details_title">Contact:</div>
<div class="more_details_con">Contact name</div>
<p class="clear"></p>
</div>
<div class="container">
<div class="more_details_title">Description:</div>
<div class="more_details_desc">Actual Description</div>
<p class="clear">
</div>
<div class="container">
<div class="more_details_title">Resolution:</div>
<div class="more_details_res">Actual Resolution</div>
<p class="clear">
</div>
</div>
The jQuery I've tried
$("#results").on("click", ".edit_entry", function() {
var contact = $(this).next(".more_details_con").html();
var desc = $(this).next(".more_details_desc").html();
var res = $(this).next(".more_details_res").html();
alert(contact+desc+res);
});
The issue is because the elements you're looking for are not siblings of the one which raised the event. You instead could use closest() to find the nearest common parent element, .more_details, and then find() to get the element you want. Try this:
$("#results").on("click", ".edit_entry", function() {
var $parent = $(this).closest('.more_details');
var contact = $parent.find(".more_details_con").text();
var desc = $parent.find(".more_details_desc").text();
var res = $parent.find(".more_details_res").text();
console.log(contact, desc, res);
});

How to find data from html and store it using jQuery

My HTML
<div class="product">
<img src="#">
<div class="priceStore">
<p data="40">Item 1</p>
</div>
</div>
How, using jQuery would I retrieve the data and store it?
My attempt:
$('.product').mousedown(function(event) {
var x = $('.priceStore').parent().find(data);
console.log(x);
});
Thanks!
There are a few different ways to write the selector but to get the value of an attribute you can use .attr()
Something like this works for this case
$('.product').mousedown(function(event) {
var x = $('.priceStore p').attr('data');
console.log(x);
});
Personally I would rewrite your HTML as follows:
<div class="product">
<img src="#">
<div class="priceStore">
<p id="data" data="40">Item 1</p>
</div>
</div>
And then access the data element like this within your Javascript:
document.getElementById("data").getAttribute('data');
Advantages:
- You don't need jQuery for this, it's basic javascript.
- You can apply an identifier to multiple elements and access/manipulate data
- Adding a second or third P tag won't break your code.
Ergo if you wanted to do so...
<div class="product">
<img src="#">
<div class="priceStore">
<p id="apple" data="40">Item 1</p>
<p id="orange" data="50">Item 2</p>
<p id="grape" data="80">Item 3</p>
</div>
</div>
You could then:
document.getElementById("apple").getAttribute('data');
document.getElementById("orange").getAttribute('data');
document.getElementById("grape").getAttribute('data');

Categories