I have a page with three tables (Table A, Table B, Table C), which I want to display depending on which button the user clicks. I am able to do this just fine with the following script:
var tableA = document.getElementById("tableA");
var tableB = document.getElementById("tableB");
var tableC = document.getElementById("tableC");
var btnTabA = document.getElementById("showTableA");
var btnTabB = document.getElementById("showTableB");
var btnTabC = document.getElementById("showTableC");
btnTabA.onclick = function () {
tableA.style.display = "table";
tableB.style.display = "none";
tableC.style.display = "none"; }
btnTabB.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "table";
tableC.style.display = "none"; }
btnTabC.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "none";
tableC.style.display = "table"; }
However, I also want to include the html code for these tables into this page. I am also able to do this with the following script:
$(function(){ $("#include-tables").load("P1/1_0/table.html"); });
That said I cannot get these to work together. For example, when I combine all of this -- see sample code below -- my tables are included, but the buttons no longer work. If I check the error log in the browser, it says Null is not a object, and so I think the issue is to due with all variables and Id's being defined before the code for the button executes. That said with my (very) limited knowledge of javascript I am have not been able to figure out how to resolve this.
$(function(){
$("#include-tables").load("/1_0/tables.html");
});
var tableA = document.getElementById("tableA");
var tableB = document.getElementById("tableB");
var tableC = document.getElementById("tableC");
var btnTabA = document.getElementById("showTableA");
var btnTabB = document.getElementById("showTableB");
var btnTabC = document.getElementById("showTableC");
btnTabA.onclick = function () {
tableA.style.display = "table";
tableB.style.display = "none";
tableC.style.display = "none";
}
btnTabB.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "table";
tableC.style.display = "none";
}
btnTabC.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "none";
tableC.style.display = "table";
}
#tableA {
}
#tableB {
display: none;
}
#tableC {
display: none;
}
<div id="include-tables"></div>
<div class="button-div">
<input type="button" id="showTableA" value="TableA">
<input type="button" id="showTableB" value="TableB">
<input type="button" id="showTableC" value="TableC">
</div>
<script src="script.js"></script>
.load() is asynchronous, so you can't access the elements until after it completes. Put all your code in its callback function.
$(function(){
$("#include-tables").load("/1_0/tables.html", function() {
var tableA = document.getElementById("tableA");
var tableB = document.getElementById("tableB");
var tableC = document.getElementById("tableC");
var btnTabA = document.getElementById("showTableA");
var btnTabB = document.getElementById("showTableB");
var btnTabC = document.getElementById("showTableC");
btnTabA.onclick = function () {
tableA.style.display = "table";
tableB.style.display = "none";
tableC.style.display = "none";
}
btnTabB.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "table";
tableC.style.display = "none";
}
btnTabC.onclick = function () {
tableA.style.display = "none";
tableB.style.display = "none";
tableC.style.display = "table";
}
});
});
Or you could use event delegation to bind event handlers to dynamically-added elements. See Event binding on dynamically created elements?
Related
I have a photo gallery in JavaScript, using Nuxt.js. For more information, see this post.
Here is the new code :
// Open PopUp
const photoGalleryFullscreen = document.querySelector(".photo-gallery-fullscreen");
const imagesFullscreen = document.querySelectorAll(".slide-container img");
for (let i = 0; i < imagesFullscreen.length; i++) {
photo[i].onclick = function() {
photoGalleryFullscreen.style.display = "block";
imagesFullscreen[i].style.display = "block";
slideIndex = i;
}
// Close PopUp
document.querySelector(".out").onclick = function() {
photoGalleryFullscreen.style.display = "none";
imagesFullscreen[i].style.display = "none";
slideIndex = 1;
};
}
In the last part of the new code (//Close PopUp) this is not working (the rest is working), if you can help (thank you very much) :
imagesFullscreen[i].style.display = "none";
On contrary, if I set manually i, it is working for the selected image
I just had to determine which image is clicked and save it in a variable.
Here is the new code that is working :
const photoGalleryFullscreen = document.querySelector(".photo-gallery-fullscreen");
const imagesFullscreen = document.querySelectorAll(".slide-container img");
for (let i = 0; i < imagesFullscreen.length; i++) {
// Open PopUp
photo[i].onclick = function() {
photoGalleryFullscreen.style.display = "block";
imagesFullscreen[i].style.display = "block";
globalThis.imageClickedNumber = i;
slideIndex = i;
document.body.setAttribute("class", "disable-scroll");
}
// Close PopUp
document.querySelector(".out").onclick = function() {
if (imagesFullscreen[imageClickedNumber].style.display == "block") {
photoGalleryFullscreen.style.display = "none";
imagesFullscreen[imageClickedNumber].style.display = "none";
slideIndex = 1;
document.body.removeAttribute("class");
}
};
}
I have 3 divs each with a distinct id. Based off the value of a dropdown I have, I want to show one of the divs. I created my function and call it, but for some reason no change occurs. The new value of the dropdown is never recorded, when I use console.log. I am unsure what is causing the problem and would appreciate any help.
HTML
<div class="ins-left" id="fifteen">
<p>$15</p>
</div>
<div class="ins-left" id="thirty">
<p>$30</p>
</div>
<div class="ins-left" id="fourtyfive">
<p>$45</p>
</div>
CSS
#fifteen {
display: none;
}
#thirty {
display: none;
}
#fourtyfive {
display: none;
}
JS
var length = document.getElementById('length');
var chosenLength = length.options[length.selectedIndex].value;
var start = document.getElementById('start').innerHTML.split('.').join('').toLocaleLowerCase();
var end = document.getElementById('end').innerHTML.split('.').join('').toLocaleLowerCase();
var time = document.getElementById('time');
time.disabled = true;
function disabled() {
if (chosenLength.value != "") {
time.disabled = false;
}
}
var slotTimes = [];
document.getElementById("length").onchange = function (evt) {
var timeDistance = evt.target.value;
var startMoment = moment(start, "h:mm a");
var endMoment = moment(end, "h:mm a");
slotTimes = [];
while (startMoment.isSameOrBefore(endMoment)) {
slotTimes.push(startMoment.format("h:mm a"));
startMoment = startMoment.add(timeDistance, 'minutes');
}
addDropdown();
price();
};
function price(){
if (chosenLength.value === "") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "30") {
document.getElementById('fifteen').style.display = "block";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "60") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "block";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "90") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "block";
}
}
function addDropdown() {
var doc = '',
times = slotTimes,
i;
for (i = 0; i < times.length; i++) {
doc += "<option value='" + times[i] + "'>" + times[i] + "</option>";
}
document.getElementById('time').innerHTML = doc;
disabled();
}
I made a simple working example for you here, so you can adjust your code based on this:
https://codepen.io/brunomont/pen/WmExvV
I had to remove a couple of broken references since your HTML didn't include everything (like the time elements). Also, make sure you have all the dependencies loading (I noticed you are using moment.js).
The changes I made were:
Adding a document.addEventListener("DOMContentLoaded", function() to make sure your HTML was loaded, before you tyr to run the JavaScript.
Change the way you bind your onChange function to be document.getElementById('length').addEventListener('change', function (evt)
Basically, the addEventListener is more flexible than onChange. You can read more about this change here:
addEventListener vs onclick
Hope it helps :)
I am currently creating a web application.One of the function is to allow the users to create a div and assign a label to it which will be added to the class.The label name will then be displayed at the side based on the div's class name.Problem is I want to change the label name when I change the 's class name.I am unable to change the label for just one if i have multiple divs.
I am using event.target to get the clicked but if clicked on 2 divs separately,both are still selected and both class name will change.
//assign label and display it on the sides
$("#boxContain").click(function (event) {
console.log(event.target.nodeName);
$("#labels").on("change", function () {
var modal = document.getElementById('lblList');
if ($(event.target).attr('name') == null) {
var e = document.getElementById("labels");
var strUser = e.options[e.selectedIndex].text;
console.log(strUser);
var btn = document.getElementById("submitLbl"); //get submit btn
btn.onclick = function () {
event.target.setAttribute('name', strUser); //set the div name to the label
$(event.target).addClass(strUser);
var p = document.createElement("p");
$(p).text(strUser);
$(p).attr('id', strUser);
$(p).attr('class', 'lbl');
$(p).addClass(strUser);
$("#existingLbl").append(p);
modal.style.display = "none";
$('#labels')[0].selectedIndex = 0;
}
} else {
event.target.removeAttribute('ondblclick');
}
});
});
//Edit labels
function edit(e) {
var classname = e.className.split(' ')[4];
return classname;
};
$('#createBoxBtn').click(function () {
$('.box').click(function () {
var currentLbl = edit(this);
console.log(currentLbl);
var element = this;
$('#editLblBtn').on('click', function () {
document.getElementById('errorMessage').style.display = "none";
var modal = document.getElementById('lblList');
var span = document.getElementsByClassName("close")[0];
var btn = document.getElementById('submitLbl');
var edit = document.getElementById('editLbl');
btn.style.display = "none";
edit.style.display = "block";
modal.style.display = "block";
$('#labels').on('change', function () {
var list = document.getElementById("labels");
var newLbl = list.options[list.selectedIndex].text;
$(edit).on('click', function () {
var p = document.getElementById(currentLbl);
if ($(p).attr('id') == currentLbl) {
$(p).text(newLbl);
$(p).removeClass(currentLbl);
$(p).addClass(newLbl);
$(p).attr('id', newLbl);
$(element).removeClass(currentLbl);
$(element).addClass(newLbl);
$(element).attr('name', newLbl);
$('#labels')[0].selectedIndex = 0;
} else if ($(p).attr('id') == "Copyof" + currentLbl) {
$(p).text(newLbl);
$(p).removeClass(currentLbl);
$(p).addClass(newLbl);
$(p).attr('id', 'Copyof' + newLbl);
$(element).removeClass(currentLbl);
$(element).addClass('Copyof' + newLbl);
$(element).attr('name', newLbl);
$('#labels')[0].selectedIndex = 0;
}
}); //end of edit
}); //end of #labels
span.onclick = function () {
modal.style.display = "none";
};
edit.onclick = function () {
modal.style.display = "none";
};
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
$('#labels')[0].selectedIndex = 0;
}); //end of #editLblBtn
}); //end of .box
}); //end of #createBoxBtn
When I edit the label,the div's classname AND name should change to a new label and the corresponding p tag should change as well.What should I do to achieve this?Is there any way to clear the data stored in event when I click on different elements?
i'm currently developing an application that relies on webservice calls in order to create a tree-like "menu", everything works as intended but i realized not all the target audience has a fast internet connection like i have right now on the development environment. my goal is to show a loading "screen" while the javascript function creates and then adds the elements to the DOM, the flowchart is as follows:
user click on the "expand" image of a node
user sees a div loading gif
user is presented with the childnodes
i'm not sure where i should put the timeout
my code:
...
elemento_tema_imagem_esconde_mostra.addEventListener("click", Get_Feat);
...
function Get_Feat(event) {
Tema_Expandido = event.target.parentNode;
if (typeof (Tema_Expandido.getElementsByTagName("ul")[0]) === "undefined") {
sMNID = event.target.parentNode.getElementsByTagName("a")[0].getAttribute("mnid");
var service = new WebJSON;
service.GetFeat(sMNID, SuccessCallback_Get_Feat, OnfailureCallback_Get_Feat);
} else {
//debugger;
var elemento = Tema_Expandido.getElementsByTagName("ul")[0];
var imagem_esconder_mostar = elemento.parentNode.childNodes[0];
var style = window.getComputedStyle(elemento, null);
if (style.display == "block") {
elemento.style.display = "none";
imagem_esconder_mostar.src = "Content/Images/img_abrir_22_22.png";
} else if (style.display == "none") {
elemento.style.display = "block";
imagem_esconder_mostar.src = "Content/Images/img_fechar_22_22.png";
}
}
};
function SuccessCallback_Get_Feat(Resultado_Get_Feat) {
var colleccao_Feat = JSON.parse(Resultado_Get_Feat);
var lista_feat = document.createElement("ul");
lista_feat.setAttribute("class", "lista-sem-bullets");
for (var i = 0; i < colleccao_Feat.length; i++) {
var elemento_feat = document.createElement("li");
var elemento_feat_imagem_esconde_mostra = document.createElement("img");
var elemento_feat_imagem_no = document.createElement("img");
var elemento_feat_link = document.createElement("a");
if (colleccao_Feat[i].FILHOS > 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/img_abrir_22_22.png";
elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Compo);
} else if (colleccao_Feat[i].FILHOS = 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/seta_dir_26_20.png";
}
//elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Feat);
//elemento_feat_imagem_no.src = "Content/Images/feat.png"
elemento_feat_link.setAttribute("FNID", colleccao_Feat[i].FNID);
elemento_feat_link.innerText = colleccao_Feat[i].NAMEDESC;
elemento_feat.appendChild(elemento_feat_imagem_esconde_mostra);
elemento_feat.appendChild(elemento_feat_imagem_no);
elemento_feat.appendChild(elemento_feat_link);
lista_feat.appendChild(elemento_feat);
};
document.getElementById("myModal_Loading").style.display = "none";
Tema_Expandido.appendChild(lista_feat);
Tema_Expandido.childNodes[0].src = "Content/Images/img_fechar_22_22.png";
};
function OnfailureCallback_Get_Feat(error) {
//displaying error on alert box
alert(error);
};
any help will be much appreciated
i am trying to call the function with delay.
window.setInterval(function(){
//$('.product-display').delay(3000).hide();
document.getElementById('product-list-display').style.display = "none";
},3000);
The above code hides the div after 3 seconds, the above snippet is called in show div function. what i need to do is, i want to invoke the the above delay function only when the show div function is called...right now the function executes every 3 secnds i.e i am using setInterval for hiding. but i want to hide after 3 seconds only when show div is called. how can i do this?
can i use jquery?
function showdiv(city, imagesrc, timeout)
{
window.setTimeout(function() {
document.getElementById('city-order').innerHTML = "";
document.getElementById('order-product').innerHTML = "";
$('.product-display').addClass("zoomin");
document.getElementById('product-list-display').style.display = "block";
var order_placed_city = document.getElementById('city-order');
var content = document.createTextNode(city);
order_placed_city.appendChild(content);
var product_order = document.getElementById('order-product');
var elem = document.createElement("img");
product_order.appendChild(elem);
elem.src = imagesrc;
},timeout);
window.setTimeout(function(){
//$('.product-display').delay(3000).hide();
document.getElementById('product-list-display').style.display = "none";
},3000);
}
Move the hide setTimeout 1 line up :
function showdiv(city, imagesrc, timeout)
{
window.setTimeout(function() {
document.getElementById('city-order').innerHTML = "";
document.getElementById('order-product').innerHTML = "";
$('.product-display').addClass("zoomin");
document.getElementById('product-list-display').style.display = "block";
var order_placed_city = document.getElementById('city-order');
var content = document.createTextNode(city);
order_placed_city.appendChild(content);
var product_order = document.getElementById('order-product');
var elem = document.createElement("img");
product_order.appendChild(elem);
elem.src = imagesrc;
window.setTimeout(function(){
//$('.product-display').delay(3000).hide();
document.getElementById('product-list-display').style.display = "none";
},3000);
},timeout);
}
Try using callback function to achieve this.
function showdiv(city, imagesrc, timeout)
{
window.setTimeout(function() {
document.getElementById('city-order').innerHTML = "";
document.getElementById('order-product').innerHTML = "";
$('.product-display').addClass("zoomin");
showDiv(function(){ window.setTimeout(function(){
//$('.product-display').delay(3000).hide();
document.getElementById('product-list-display').style.display = "none";
},3000);});
var order_placed_city = document.getElementById('city-order');
var content = document.createTextNode(city);
order_placed_city.appendChild(content);
var product_order = document.getElementById('order-product');
var elem = document.createElement("img");
product_order.appendChild(elem);
elem.src = imagesrc;
},timeout);
}
function showDiv(callback){
document.getElementById('product-list-display').style.display = "block";
callback();
}