I have created the code to load elements from a xml file. But it does not load repeated values in xml file. It only loads one element, others are not loading.
Herewith attached an example.
$(document).ready(function(){
$.ajax({
type:"GET",
url:"data.xml",
dataType:"xml",
success:showdata
});
});
function showdata(xml){
xml = $(xml).children();
$(xml).children().each(function () {
let tag = $(this).prop("tagName");
let to = $(this).find("to").text();
let from =$(this).find("from").text();
let heading = $(this).find("heading").text();
let list = $(this).find("list").text();
let body =$(this).find("body").text();
let html = `<div class="col-md-4" id="random">
<div class="thumbnail">
<a href="#${tag}"><p>${to}</p>
<p>${from}</p>
<p>${heading}</p>
<p>${body}</p></a>
</div>
</div>`;
let popup = `<div id="${tag}" class="overlay">
<div class="popup">
<h6>${heading}</h6>
<a class="close" href="#">×</a>
<ul><li>${list}</li></ul>
</div>
</div>`;
$("#xmldata").append(html);
$("#popup").append(popup);
});
}
http://next.plnkr.co/edit/MVwJnBHypBFvg2Lk?
I saw in your code you are using anchor tag and it is always pointing to #note. I have just append index number and Now it is perfect.
Please Change this line
$(xml).children().each(function (index,item) {
let tag = $(this).prop("tagName")+index;
I have also updated list which was not binding as a li. Now check it will work for you
Complete Code is as follows
function showdata(xml){
xml = $(xml).children();
$(xml).children().each(function (index,item) {
let tag = $(this).prop("tagName")+index;
let to = $(this).find("to").text();
let from =$(this).find("from").text();
let heading = $(this).find("heading").text();
let list = $(this).find("list");
let body =$(this).find("body").text();
let html = `<div class="col-md-4" id="random">
<div class="thumbnail">
<a href="#${tag}"><p>${to}</p>
<p>${from}</p>
<p>${heading}</p>
<p>${body}</p></a>
</div>
</div>`;
var listStr="";
list.each((index,item)=>{
listStr+="<li>"+item.innerHTML+"</li>"
})
let popup = `<div id="${tag}" class="overlay">
<div class="popup">
<h6>${heading}</h6>
<a class="close" href="#">×</a>
<ul>`+listStr+`</ul>
</div>
</div>`;
$("#xmldata").append(html);
$("#popup").append(popup);
});
}
Related
I'm looking for a way to add a div container using template literals. for example.
I have a div in my index.html
<div class="bag">
</div>
Every time the user adds a new item to the bag the following divs' get added inside the bag like so...
<div class="bag">
<div class="bag__item"> // <--- added here
<div class="wrapper--within">
<img src="./assets/images/cookie5-small.jpg" alt="" />
<h3 class="bag__unit-price">$5</h3>
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> // <-- to here
</div>
In my javascript I target my bag container
class Cart {
constructor() {
this.cartContainer = document.querySelector(".bag");
this.events();
}
events() {
this.updateCart();
}
updateCart() {
let newItemDiv = document.createElement("div")
newItemDiv.className = "bag__item"
newItemDiv.createElement("div")
}
}
export default Cart;
I was originally planning to add each div individually but i would like a way where i can do something like..
updateCart() {
let newItemDiv = document.createElement("div")
add `<div class="bag__item"> // <--- added here
<div class="wrapper--within">
<img src="./assets/images/cookie5-small.jpg" alt="" /> // <---image will change depending on item added
<h3 class="bag__unit-price">$5</h3> // price will change depending on item added..
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> `
}
Is this something that can be done?
In your updateCart() method you can write
updateCart() {
let newItemDiv = document.createElement("div")
newItemDiv.className = "bag__item"
newItemDiv.innerHTML = `your markup here with the whole div hierarchy`;
}
You can do this.
If you already added the div.bad
document.getElementsByClassName("bag").innerHTML = `<div> </div>`
or
var elemt = document.createElement("div")
elemt.innerHTML = `<div> </div>`
You can do it like this: (I implemented below example by Cart class because in your question you've been using Cart class to create new Item and I consider that using this class is mandatory, there are other ways to acheive below result with less lines of code)
class Cart {
constructor(img, price) {
this.img = img;
this.price = price;
this.cartContainer = document.querySelector('.bag');
this.events();
}
getTemplate() {
const template = `<div class="bag__item">
<div class="wrapper--within">
<img src="${this.img}" alt="" />
<h3 class="bag__unit-price">${this.price}</h3>
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> `;
return template;
}
events() {
this.updateCart();
}
updateCart() {
const template = this.getTemplate();
let newItemDiv = document.createElement('div');
this.cartContainer.append(newItemDiv);
newItemDiv.outerHTML = template;
}
}
// sample img, price (You can set different values for img, price when you want to create new one, this static content is just for example)
const img = 'https://fakeimg.pl/350x200/000000/?text=Image1';
const price = '100$';
function addBag(){
new Cart(img, price);
}
<button onClick="addBag()">click me</button>
<div class="bag">ba continaer:</div>
I am trying to change the innerHTML of a page twice, more explanation, I am trying to make a single page like app. I'm a newbie. I want to change the inner HTML content of the section after one click then get the classList of the changed inner HTML then change it again, but it does not seem to work, I don't know what I am doing wrong.
my thought process for the code is below
select the whole container which is the features container
on click, change the container innerHTML
on click of the changed container innerHTML, change the inner HTML again but It doesn't work, it keeps giving me the first innerHTML but when i do not display the main container that works, how can i solve this?
const hold = document.querySelector('#features');
const holds = document.querySelector('.features');
let hel;
hold.addEventListener('click', function() {
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector('.ddd');
// console.log(hel.innerText);
hel.addEventListener('click', function() {
// holds.style.display = 'none';
// this.style.display = 'none';
holds.innerHTML = '<div class="q">mess</div>';
console.log(this);
});
});
<section id="features" class="features section-hidden">
<div class="container container-pal1">
<h2 class="features-description highlight">Features</h2>
<div class="features-contain">
<div class="features-text">
<h3 class="features-header">
We are here to provide you with the
<span class="features-highlight">Best</span> services
</h3>
<p class="features-title">
Everything you need in a modern bank and more, get on our waiting list today by clicking the button below
</p>
<a href="" class="hero-cta-1 features-button">View our services <img src="./assets/arrow-right.svg" alt="" />
</a>
</div>
<div class="features-props">
<div class="features-list">
<div class="features-item">
<img src="./assets/fast-delivery.svg" alt="" />
<h5>Swift Delivery 🚀</h5>
<p>No late transfer, get it instantly</p>
</div>
<div class="features-item">
<img src="./assets/0-fees.svg" alt="" />
<h5>$0 Fee's</h5>
<p>No fees on your account like the other banks</p>
</div>
<div class="features-item">
<img src="./assets//0-interest.svg" alt="" />
<h5>Interest %</h5>
<p>
Interest when applying for loans depends on your agreement from the bank
</p>
</div>
<div class="features-item">
<img src="./assets/no-credit-check.svg" alt="" />
<h5>Credit Card</h5>
<p>Credit cards available at your demand</p>
</div>
<div class="features-item">
<img src="./assets/chat-support.svg" alt="" />
<h5>Chat Support</h5>
<p>Chat with a company representative anytime</p>
</div>
<div class="features-item">
<img src="./assets/fixed-payment-option.svg" alt="" />
<h5>Fixed Payment Option</h5>
<p>Payment Options will be provided</p>
</div>
</div>
</div>
</div>
</div>
</section>
Here's a simple example how to switch elements that already exist in the DOM.
Use a data-* attribute to reference the desired ID element to show.
Use classList.toggle to switch the Elements.
const ELS_pages = document.querySelectorAll(".page");
const ELS_buttons = document.querySelectorAll("[data-page]");
const goToPage = (id) => {
ELS_pages.forEach(EL => EL.classList.toggle("u-none", EL.id !== id));
};
ELS_buttons.forEach(EL => EL.addEventListener("click", () => {
goToPage(EL.dataset.page);
}));
nav {display: flex;} nav a {color: #00f; padding: 5px 10px; cursor: pointer; }
/* Utility classes */
.u-none {display: none;}
<div class="page" id="page-login">
<h1>Welcome</h1>
<button type="button" data-page="page-main">ENTER</button>
</div>
<div class="page u-none" id="page-main">
<nav>
<a data-page="page-settings">User Settings</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>MAIN PAGE</h1>
</div>
<div class="page u-none" id="page-settings">
<nav>
<a data-page="page-main">Back to Main</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>SETTINGS PAGE</h1>
</div>
This is basic, and does not change the URI address in the browser. To achieve that some more code should be added to handle such case.
Try keeping a flag(if there are only two different data you want to show) and based on the flag show data or a counter
const hold = document.querySelector('#features');
let count = 0;
hold.addEventListener('click', function() {
switch (count){
case 0:
holds.innerHTML = `<div class="ddd">h is here </div>`;
case 1:
holds.innerHTML = `<div class="ddd">now some other is here </div>`
};
});
and please provide more info for the remaining answer
Simply run your second innerHTML code after the next repaint using requestAnimationFrame and it will work.
const hold = document.querySelector("#features");
const holds = document.querySelector(".features");
let hel;
hold.addEventListener("click", function (e) {
e.preventDefault();
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector(".ddd");
// console.log(hel.innerText);
hel.addEventListener("click", function () {
// holds.style.display = 'none';
// this.style.display = 'none';
requestAnimationFrame(() => {
holds.innerHTML = '<div class="q">mess</div>';
});
console.log(this);
});
});
if you need further information about why it's happening read this article.
I am trying to load search results based on what the user typed (responsive search), I thought it was my event as I wanted it more responsive e.g keyup but it didn't work. Here is working codepen
and following in my code. I had been struggling for hours now. What am I doing wrong?
function generateHTML(el,toggleClass){
const div = document.createElement("div");
const card = div.classList.add("card","col-sm-6", "col-md-6", "col-lg-3", "m-2",toggleClass);
div.innerHTML = `
<a href='#' class="products">
<img src="${el.image}" class="card-img-top rounded" alt="${el.title}">
<div class="card-body">
<h5 class="card-title">${(slicer(el.title))}</h5>
</div>
</a>
`
grid.appendChild(div);
}
This should do what you actually want
//getting the reference to elements
const row = document.querySelector("#search");
const grid = document.querySelector("#grid");
document.addEventListener("DOMContentLoaded", function () {
const div = document.createElement("div");
const formGroup = div.classList.add("form-group");
div.innerHTML = `
<div class="alert alert-primary">
<label for="searchField">Search</label>
<input type="text" class="form-control" id="searchField" placeholder="Type in what your looking for">
</div>
`;
row.appendChild(div);
//fetchData()
//get the reference to form
var input = '';
const myInput = document.getElementById("searchField");
myInput.addEventListener("keyup", function (e) {
input = myInput.value;
console.log(input);
fetch('https://fakestoreapi.com/products/')
//convert the response to JSON
.then(res => res.json())
//use the data to filter if it matches or display all
.then(data => {
grid.innerHTML = '';
data.forEach(el => {
if (el.title.toLowerCase().includes(input.toLowerCase())) {
console.log('h')
generateHTML(el, "block")
}
})
})
});
//get the reference to input
//const input = form.searchField.value.trim();
//add a event to listen on key up
})
function generateHTML(el, toggleClass) {
const div = document.createElement("div");
const card = div.classList.add("card", "col-sm-6", "col-md-6", "col-lg-3", "m-2", toggleClass);
div.innerHTML = `
<a href='#' class="products">
<img src="${el.image}" class="card-img-top rounded" alt="${el.title}" width="100" height="auto">
<div class="card-body">
<h5 class="card-title">${(slicer(el.title))}</h5>
</div>
</a>
`;
grid.appendChild(div);
}
function slicer(str) {
return str.slice(0, 10);
}
<div class="container">
<div class="" id="search">
</div>
<div class="row" id="grid">
</div>
</div>
db.collection('Buses').get().then((snapshot) = > {
snapshot.forEach((busDatas) = > {
busData = busDatas.data()
console.log(busData)
document.getElementById('bus-container-dynamic').innerHTML = `
<div class="single-room-area d-flex align-items-center
mb-50 wow fadeInUp" data-wow-delay="100ms">
<div class="room-thumbnail">
<img src="${busData.ImageLink}" alt="">
</div>
<div class="room-content">
<h2>${busData.TourName}</h2>
<h6>${busData.From} to ${busData.To}</h6>
<h4>₹ ${busData.SeatPrice} </h4>
<div class="room-feature">
<h6>Boarding Point <span>${busData.BoardingTime}</span></h6>
<h6>Dropping Point <span>${busData.DroppingTime}</span></h6>
<h6>Seats Left <span>${busData.SeatsLeft}</span></h6>
<h6>Total Time <span>${busData.TotalTime}</span></h6>
</div>
<a href="#" class="btn view-detail-btn">
View Details
<i class="fa fa-long-arrow-right" aria-hidden="true"></i>
</a>
</div>
</div>`
})})
I am using this code to display my code in html but the only one document is showing on the webpage , but when i print that data in console i am getting all the documents
Do not overwrite the contents of the element on each iteration, append to them.
In fact, use a variable to append to, then assign that to the element, so you only have to manipulate the DOM once.
This line:
document.getElementById('bus-container-dynamic').innerHTML = `...`;
Keeps re-writing the whole contents of #bus-container-dynamic at each iteration.
You could instead store all the data in one variable, then assign that to the element.
A short snippet to illustrate the solution.
const myData = [1,2,3,4,5];
// Create a variable here
let html = '';
myData.forEach( e => {
// Create your element's HTML inside the loop
html += e;
});
// Then assign it to the element
document.getElementById('my-element').innerHTML = html;
<div id="my-element"></div>
And this is how I would modify the code that you posted originally.
db.collection('Buses').get().then((snapshot) = > {
let html = '';
snapshot.forEach((busDatas) = > {
busData = busDatas.data()
console.log(busData)
html += `
<div class="single-room-area d-flex align-items-center
mb-50 wow fadeInUp" data-wow-delay="100ms">
<div class="room-thumbnail">
<img src="${busData.ImageLink}" alt="">
</div>
<div class="room-content">
<h2>${busData.TourName}</h2>
<h6>${busData.From} to ${busData.To}</h6>
<h4>₹ ${busData.SeatPrice} </h4>
<div class="room-feature">
<h6>Boarding Point <span>${busData.BoardingTime}</span></h6>
<h6>Dropping Point <span>${busData.DroppingTime}</span></h6>
<h6>Seats Left <span>${busData.SeatsLeft}</span></h6>
<h6>Total Time <span>${busData.TotalTime}</span></h6>
</div>
<a href="#" class="btn view-detail-btn">
View Details
<i class="fa fa-long-arrow-right" aria-hidden="true"></i>
</a>
</div>
</div>`
document.getElementById('bus-container-dynamic').innerHTML = html;
}) // End foreach
}) // End then
In javascript I want to tell post-container that when I click on it, take the href located at link and go to page X.
There are multiple post-container
My code is this:
<div class="post-container">
<a class="link" href="X">
<h2 class="post-title">Hello, world!</h2>
</a>
<div class="date-posts">...</div>
</div>
I want to be able to click outside the Hello, world! title of my post in any area of post-container and go to page X
Any idea how to do this?
I hope I'm interpreting your question correctly, but you can just rearrange where you're writing your a href tag. Instead, wrap your div inside of it. This will make the entire div element a link.
<a class="link" href="google.com">
<div class="post-container">
<h2 class="post-title">Hello, World!</h2>
<div class="date-posts"></div>
</div>
</a>
This will work.Add Event listener to the parent element (Event Delegation).You can take the href property of the child element and then use window.location.href.You might need to add preventDefault() to avoid default behaviour of a tag
If you have multiple tags with same class name.You have to use querySelectorAll .Either way if you have single elements or multiple elements with same class name use querySelctorAll.
// if you have one tag
let ele = document.querySelectorAll(".post-container")
ele.forEach(element => {
element.addEventListener("click", function(e) {
e.preventDefault();
let href = element.children[0].getAttribute("href")
window.location.href = href;
})
})
.post-container {
background-color: green;
}
<div class="post-container">
<a class="link" href="X">
<h2 class="post-title">Hello, world!</h2>
</a>
<div class="date-posts">...</div>
</div>
Assuming you have multiple .post-containers you would need to iterate over each of them and add an event listener to handle click events. On click, find the a get its href and set the window.location (I just console log it in this demo)
(function(){
let elems = document.querySelectorAll(".post-container");
for (i = 0; i < elems.length; ++i) {
let el = elems[i];
el.addEventListener("click", function(e) {
e.preventDefault();
let href = el.querySelector("a").getAttribute("href");
console.log("href",href);
//window.location.href = href;
})
}
})();
<div class="post-container">
<a class="link" href="X">
<h2 class="post-title">Hello, world!</h2>
</a>
<div class="date-posts">...</div>
</div>
<div class="post-container">
<a class="link" href="Y">
<h2 class="post-title">Goodbye world!</h2>
</a>
<div class="date-posts">...</div>
</div>
Javascript:
var elements = document.getElementsByClassName('post-container');
var loadLink = function() {
var link = this.getElementsByTagName("a")[0].href;
window.location.href = link;
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', loadLink, false);
}
Check working demo
document.getElementsByClassName('post-container')[0].onclick = function(e){
location.href = this.children[0].href;
}