I want to create a list of button where once clicked, it will shows the respective div as below. And in the div, there is a few links that user can click, and once they clicked the link and go back, it will bring them back to the previous div instead of the first default div. Codes as below.
<div class="tab">
<a class="tablinks btn" href="#m0" id="t0">Item A</a>
<a class="tablinks btn" href="#m1" id="t1">Item B</a>
<a class="tablinks btn" href="#m2" id="t2">Item C</a>
</div>
<div class="tlist">
<div id="m0" class="tdiv" style="display:block;">
LinkA</div>
<div id="m1" class="tdiv" style="display:none;">
LinkB</div>
<div id="m2" class="tdiv" style="display:none;">
LinkC</div>
</div>
I have Javascript codes that will change the display from none to block when user clicked on the Item.
document.getElementById("m0").style.display = "block";
document.getElementById("t"+i).addEventListener('click',divStyle.bind(this,"m"+i),false);
function divStyle(num) {
var i,tdiv,tablinks;
tdiv = document.getElementsByClassName("tdiv");
for (i=0;i<tdiv.length;i++) {
tdiv[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i=0;i<tablinks.length;i++) {
tablinks[i].className = tablinks[i].className.replace(" active","");
}
document.getElementById(num).style.display = "block";
Event.className += "active";
}
//print tab for Item
function printTab(itemnum) {
for (var y = 0; y < itemnum; y++) {
tabbtn = document.createElement("a");
tabbtn.classList.add("tablinks", "btn", "btn-secondary");
tabbtn.setAttribute("href", "#m" + y);
tabbtn.setAttribute("id", "t" + y);
if (y == 0) {
tabbtn.classList.add("tablinks", "btn", "btn-secondary", "active");
}
tabtxt = document.createTextNode(""); //print Item text here
tabbtn.appendChild(tabtxt);
document.getElementById("tab").appendChild(tabbtn);
}
//print div for Link
function printLink(num) {
var docFrag = document.createDocumentFragment();
for (var i = 0; i < Object.keys(obj).length; i++) {
moddiv = document.createElement("div");
moddiv.setAttribute("id", "m" + num);
moddiv.setAttribute("class", "tdiv");
moddiv.style.display = "none";
for (var i = 0; i < Object.keys(obj).length; i++) {
/*do something here and put link of each item*/
}
moddiv.appendChild(docFrag);
document.getElementById("tlist").appendChild(moddiv);
}
The problem I have now is that when LinkC is clicked, and user then pressed Back button in the browser, browser goes back to the link of the previous specific div, for example, page.html#m2 but shows div m0. I guess this is because I already set document.getElementById("m0").style.display = "block"; by default so it will always go to div m0 but is there other way to make sure the browser will go back to the previous specific div chosen?
My google finding shows people suggesting history.back() but that means I need to create a Back button but I do not want that. I am sure this is not a complicated issue but I can't think anymore on how to solve this.
Any help is very appreciated. Thank you!
Update: I tried to use history.back() and created a button but this also is not working as it still display div m0. :(
Update #2: Tried this on Firefox and it is working though. Is there another way to make sure it can work for different browser?
Please try the bellow code :
<div class="tab">
<a class="tablinks btn active" href="#m0" id="t0">Item A</a>
<a class="tablinks btn" href="#m1" id="t1">Item B</a>
<a class="tablinks btn" href="#m2" id="t2">Item C</a>
</div>
<br>
<div class="tlist">
<div id="m0" class="tdiv" style="display:block;">
LinkA</div>
<div id="m1" class="tdiv" style="display:none;">
LinkB</div>
<div id="m2" class="tdiv" style="display:none;">
LinkC</div>
</div>
<style>
a{color:#333;text-decoration: none;background: #eee;border: 1px solid #333;border-radius:5px;padding:3px;}
.active{color:blue;background: #ccc;}
</style>
<script type="text/javascript">
var tabSelect=(url)=>{
console.log(url);
let hs = url.split('#')[1]||'m0',ts = hs.split('m').join('t');
if(hs!=''){
let tabcs = document.getElementsByClassName('tdiv');
for(let tabc of tabcs){if(tabc.id){tabc.style.display='none';}}
let tabhs = document.getElementsByClassName('tablinks');
for(let tabh of tabhs){if(tabh.id){tabh.className="tablinks btn"}}
let c = document.getElementById(hs);
if(c){c.style.display = 'block';document.getElementById(ts).className="tablinks btn active"}
}
}
window.onhashchange=(i)=>{tabSelect(i.newURL);}
window.onload=()=>{tabSelect(location.href);}
</script>
Hope you will be fine with this code.
Related
I am writing a jquery function to filter products by type. It works perfectly fine but when I filter by type more than once. Html Element of product-box named addToWishlist stop working.
otherwise all products are displayed perfectly fine.
Cant figure out where is the problem.
Here is the code
//load products data in array
var productArray = [];
$("#product-items .col-4").each (function (){
productArray.push($(this)) })
$(".filter-btn").click(function(e) {
var btnId = e.target.id;
var tempArray = [];
for(var i = 0;i < productArray.length; i++){
var type = $(productArray[i]).find('.addToWishlist').data("type");
if(btnId == "fairness-soaps" && type == "Fairness")
tempArray.push(productArray[i])
if(btnId == "deep-clean-soaps" && type == "Deep-Clean")
tempArray.push(productArray[i])
if(btnId == "skin-whitening-soaps" && type == "Skin-Whitening")
tempArray.push(productArray[i])
}
$("#product-items").html(tempArray);
});
<div class="row" id="product-items">
<div class="col-4">
<a href="#">
<div class="product-box">
<div class="product-img">
<img src="images/product-img13.png" alt="">
<a type="button" class="addToWishlist" data-id="13" data-image="images/product-img13.png" data-price="$30"
data-name="Aloe Vera Soap" data-quantity="1" data-weight="50g" data-availability="In Stock" data-type="Fairness">
<i class="wishlist-icon fa fa-heart-o"></i></a>
</div>
<p class="product-name">Aloe Vera Soap</p>
<p class="product-price">$30</p>
</div>
</a>
</div>
and so on....
You're not reordering the product Elements, you're rewriting them. Even though the HTML of the products is the same, the events you attach to them is lost when you call $("#product-items").html(tempArray);. You either need to reapply the events to the "addToWishList" buttons or reorder the elements instead of writing directly to the html.
Here's a contrived example that shows how just because the HTML is the same doesn't mean the event stays:
<div id="container">
<button id="special-button">Click me</button>
</div>
<script>
$("#special-button").on("click", function(){
alert("I've Been clicked!");
});
$("#container").html(`<button id="special-button">Click me</button>`);
</script>
I'm trying to load HTML inside HTML Tabs, I've three tab Report 1, Report 2 and Report 3 Based on each tab selection I would like to show the different html reports but HTML file is not getting loaded when I select the tabs - please find my code below. Am I missing anywhere here and please find my reports file here - https://github.com/mikemarsh27/jest-poc/tree/main/html-report
It would be really appreciated if someone can help me to resolve this issue. Thanks in advance!
reportMain.html
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
<div class="w3-container">
<h2>Reports</h2>
<div class="w3-row">
<a href="javascript:void(0)" onclick="openReport(event, 'Report1');">
<div class="w3-third tablink w3-bottombar w3-hover-light-grey w3-padding">Report 1</div>
</a>
<a href="javascript:void(0)" onclick="openReport(event, 'Report2');">
<div class="w3-third tablink w3-bottombar w3-hover-light-grey w3-padding">Report 2</div>
</a>
<a href="javascript:void(0)" onclick="openReport(event, 'Report3');">
<div class="w3-third tablink w3-bottombar w3-hover-light-grey w3-padding">Report 3</div>
</a>
</div>
<div id="Report1" class="w3-container report" style="display:none">
<h2>Report 1</h2>
<p>First Report</p>
<div w3-include-HTML="report1.html"></div>
</div>
<div id="Report2" class="w3-container report" style="display:none">
<h2>Report 2</h2>
<p>Second Report</p>
<div w3-include-HTML="report2.html"></div>
</div>
<div id="Report3" class="w3-container report" style="display:none">
<h2>Report 3</h2>
<p>Third Report</p>
<div w3-include-HTML="report3.html"></div>
</div>
</div>
<script>
function openReport(evt, reportName) {
getHtml(reportName);
var i, x, tablinks;
x = document.getElementsByClassName("report");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < x.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" w3-border-red", "");
}
document.getElementById(reportName).style.display = "block";
evt.currentTarget.firstElementChild.className += " w3-border-red";
}
function getHtml(id) {
alert(id)
//Get the <div> element
let element = document.querySelector("#" + id)
.querySelector("div");
//Check if it's empty; we don't want to reload twice
if (element.innerHTML.trim() !== "") {
return;
}
//Get the HTML filename from the <div>
let htmlFile = element.getAttribute("w3-include-HTML");
alert(htmlFile)
//Load the HTML file into the page
element.innerHTML =
`<object type="text/html" data="${htmlFile}" ></object>`;
}
</script>
</body>
</html>
The example you provided appears to be from here. They provide additional steps that will probably make your code somewhat functional. I say somewhat because the report files you're looking to load in contain more than just HTML. Therefore, their examples may not ultimately work for you.
Here is a rough, but working solution:
Step 1: Add this function to your code
function getHtml(id){
//Get the <div> element
let element = document.querySelector("#" + id)
.querySelector("div");
//Check if it's empty; we don't want to reload twice
if (element.innerHTML.trim() !== "") {
return;
}
//Get the HTML filename from the <div>
let htmlFile = element.getAttribute("w3-include-HTML");
//Load the HTML file into the page
element.innerHTML=
`<object type="text/html" data="${htmlFile}" ></object>`;
}
Step 2: Call getHtml(...) in openReport(...)
function openReport(evt, reportName) {
getHtml(reportName);
...
}
A modified approach is provided below. In your specific circumstances it may not work, so I would stick with the first one. But for others in a similar situation, it may be more reasonable.
function getHtml(id) {
//Get the <div> element
let element = document.querySelector("#" + id)
.querySelector("div");
//Check if it's empty; we don't want to reload twice
if (element.innerHTML.trim() !== "") {
return;
}
//Get the HTML filename from the <div>
let htmlFile = element.getAttribute("w3-include-HTML");
//Get the HTML file contents
fetch(htmlFile).then(function(data) {
return data.text();
}).then(function(data) {
//Got the HTML file contents; print it to the page
element.innerHTML = data;
}).catch(function(err) {
// Report error here (e.g., console.warn(...))
});
}
The problem is that getelementbyclass is resetting when the add to cart button is clicked its only storing one at a time i want it to store multiple i had similar problem with grand total but fixed it but i cannot use the same logic to it since it will get me nan any help ?
var addtocartbuttons = document.getElementsByClassName(`cart`)
for (let i = 0; i < addtocartbuttons.length; i++) {
var button = addtocartbuttons[i]
button.addEventListener(`click`, lang1)
}
function lang1(event) {
var target = event.srcElement;
var button = event.target
var shopitem = button.parentElement.parentElement.parentElement
var title = shopitem.getElementsByClassName(`title`)[0].innerText;
console.log(title)
res2 = document.getElementsByClassName(`result2`)
res2.textContent = title
console.log(res2)
}
<div class="product-categorie-box">
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade show active" id="grid-view">
<div class="row">
<div class="col-sm-6 col-md-6 col-lg-4 col-xl-4">
<div class="products-single fix">
<div class="box-img-hover">
<img src="../../petuta/pizza/margerita.jpg" class="img-fluid" alt="Image">
<div class="mask-icon">
<ul>
<li><i class="fas fa-eye"></i></li>
<li><i class="fas fa-sync-alt"></i></li>
<li><i class="far fa-heart"></i></li>
</ul>
<a class="cart" href="#">Add to Cart</a> </div>
</div>
<div class="why-text">
<h4 class="title" id="title1"> Kids</h4>
<h5 class = "price"> €6.00</h5>
</div>
</div>
</div>
but when button is pressed the text content in res2 despairs and put the new data any ideas?
Here is the console.log:
(HTMLCollection [div.result2, textContent: "Olives"]
0: div.result2
length: 1
textContent: "Olives")
The array only stays of the length of 1 I want it to keep storing how can I do that? I want to store the text content in res2 even when the button is clicked.
I'm making a website which sends email with an order, and when I send email only the first one get sends and even in the console it appears the length of 1 then gets reset when add to cart button is clicked.
ps.
i have 33 of these product-categorie-box so I would need some fix
I didnt use get element by id i used get element by class yet i still get one only can
ps i tried
for(var i = 0; i < elems.length; i++) {
var elems = elems[i];
element2= elems.getElementsByClassName(`result2`)[0]
console.log(element2)
}
but still same problem
I manged to get a fix with the help of barmar
function lang1(event) {
var target = event.srcElement;
var button =event.target
var shopitem = button.parentElement.parentElement.parentElement
var title = shopitem.getElementsByClassName(`title`)[0].innerText;
var node =document.createElement("LI"); // Create a <li> node
var textnode =(`${title}`)
node.innerHTML=textnode
// Create a text node // Append the text to <li>
var cnode=document.getElementsByClassName("result2")[0]
cnode.prepend(node)
console.log(cnode.textContent)
The HTML is too long. The full. is the only part that really matters
var buttons = document.getElementsByTagName('button');
for (i = 0; i < buttons.length; i++) {
console.log(buttons[i])
buttons[i].onmouseenter = function() {
console.log('hello')
}
}
<div id='buttons'>
<a href='https://discord.com/api/oauth2/authorize?client_id=775316623220277248&permissions=391232&scope=bot' target='_blank'>
<button id='invbutton'><i class="fab fa-discord fa-3x"></i>Invite</button>
</a>
<button>Support</button>
</div>
I have defined the script tag at the end of the HTML file. I have also tried adding event listeners which did not work. However, the 'hello' is console logged when the button is pressed for some reason
You've simply forgotten the closing curly bracket of the for loop.
var buttons = document.getElementsByTagName('button');
for (i = 0; i < buttons.length; i++) {
console.log(buttons[i])
buttons[i].onmouseenter = function() {
console.log('hello')
}
} //This curly bracket was missing in your code!
<div id='buttons'>
<a href='https://discord.com/api/oauth2/authorize?client_id=775316623220277248&permissions=391232&scope=bot' target='_blank'>
<button id='invbutton'><i class="fab fa-discord fa-3x"></i>Invite</button>
</a>
<button>Support</button>
</div>
use onmouseover event.
<button onmouseover="handleHover()">Support</button>
var buttons = document.getElementsByTagName('button');
function handleHover() {
console.log('Hovered');
}
<div id='buttons'>
<a href='https://discord.com/api/oauth2/authorize?client_id=775316623220277248&permissions=391232&scope=bot' target='_blank'>
<button id='invbutton'><i class="fab fa-discord fa-3x"></i>Invite</button>
</a>
<button onmouseover="handleHover()">Support</button>
</div>
var divs = document.getElementsByClassName('clsItemBlock');
for (var i = 0; i < divs.length; i++) {
var iDiv = document.createElement('div');
iDiv.id = 'detail_button';
document.getElementsByClassName('clsItemPublished')[i].appendChild(iDiv);
iDiv.innerHTML = 'View Details';
}
The code above works and adds a 'View Detail' button to every product on a category page. What I'm need to now do with this is get the URL from another element and swap out what is currently ### in the example above.
It is essentially the first href inside of the class "clsItemMoreDetails". I've found chunks of code to do some pieces, but can't seem to piece it all together.
EDIT
Here is the HTML:
<div class="clsItemMoreDetails">
<a title="Strapless Ruffle Dress" class="onlineUser" href="http://www.runwaycrush.com/women/dresses/strapless-ruffle-dress.html">
<p class="clsItemHead">Strapless Ruffle Dress</p>
</a>
<div class="clsCategorydateBlock clsOverflow">
<p class="clsItemCategory">
<a href="http://www.runwaycrush.com/shop/ocean-avenue.html" title="Check out OceanAvenue's store">
<span>OceanAvenue</span>
</a>
</p>
<p class="clsItemPublished">$68.24
<span>USD</span>
</p>
</div>
</div>
Theoretically you should do something like this:
var url = document.getElementById("#id_of_some_element").href;
iDiv.innerHTML = 'View Details';
Presuming that other element has href property.