I broke a working javascript script trying to expand it - javascript

The script below was working properly (toggling display on/off) before I added lines 3 to 8 to avoid displaying more than one element at a time (there are hundreds). It still works after adding lines 3 to 8 but it does not toggle back to "display:none;" (there is always one element visible).
I only have basic knowledge of Javascript and I cannot see what I am doing wrong. Can someone give me a hint/solution?
<script type="text/javascript">
function toggle_visibility(id) {
numb = document.forms.length
for(i=1;i<numb+1;i++) {
j="N"+i
elemnt = document.getElementById(j);
elemnt.style.display = "none";
}
var e = document.getElementById(id);
if(e.style.display == 'none')
e.style.display = 'block';
else
e.style.display = 'none';
}
</script>

You are not declaring i as local variable in for -loop.Instead use this.Also you have not declared elemnt variable.Hope you dont want it to be global variable
for(var i=1;i<numb+1;i++) {
j="N"+i
elemnt = document.getElementById(j);
elemnt.style.display = "none";
}

Try declaring all the variables first:
function toggle_visibility(id) {
var i, elemnt, state,
numb = document.forms.length + 1;
for( i = 1; i < numb; i++ ) {
elemnt = document.getElementById( "N" + i );
elemnt.style.display = "none";
}
elemnt = document.getElementById( id );
state = elemnt.style.display === 'none';
elemnt.style.display = state ? 'block' : 'none';
}

Related

how can 2 function share common variable in JavaScript

var ques=["Qno 1", "Qno 2","Qno 3","Qno 4","Qno 5","Qno 6","Qno 7","Qno 8","Qno 9","Qno 10"];
var ans =[1,2,3,4,5,6, 7,8,9,10];
function random()
{
var qno=Math.floor((Math.random() * 10) );
return qno;
}
function validate()//here need help
{
var Rans=document.getElementById("numb").value;
if (Rans == ans[qno])
alert("validated!!!");
else
alert("Not a valid entry.. declined!!!");
}
function execution()
{
var x = document.getElementById("myDIV");
if (x.style.display === "none") { x.style.display = "block";}
else {x.style.display = "none";}
var qno1=random();
document.getElementById("demo").innerHTML = ques[qno1];
var qno2=random();
if(qno1==qno2)
qno2=random();
document.getElementById("demos").innerHTML = ques[qno2];
}
in the above code I am trying to generate random questions. this is only javascript part of my code.
starting with first the 2 arrays are questions and sol respectively. code is executing successfully but I have problem in validation part. for validation i want to pass qno1 value to validation function on pressing of submit button in HTML button tag. please help me with this code to execute and how can we share common variable among 2 functions.
You need to scope the vars to outside of your functions so you can use them in both.
var ques=["Qno 1", "Qno 2","Qno 3","Qno 4","Qno 5","Qno 6","Qno 7","Qno 8","Qno 9","Qno 10"];
var ans =[1,2,3,4,5,6, 7,8,9,10];
//move scope of vars
var qno1
function random()
{
var qno=Math.floor((Math.random() * 10) );
return qno;
}
function validate (qno)// use it here by passing it in
{
var Rans=document.getElementById("numb").value;
if (Rans == ans[qno])
alert("validated!!!");
else
alert("Not a valid entry.. declined!!!");
}
function execution()
{
var x = document.getElementById("myDIV");
if (x.style.display === "none") { x.style.display = "block";}
else {x.style.display = "none";}
// set here
qno1=random();
document.getElementById("demo").innerHTML = ques[qno1];
var qno2=random();
if(qno1==qno2)
qno2=random();
document.getElementById("demos").innerHTML = ques[qno2];
}
// call it wherever
validate(qno1)

addEventListener to a class for hide and show toggle

var my_toggle = document.getElementsByClassName('my_toggle');
var my_toggle_button = document.getElementsByClassName('my_toggle_button');
var my_toggle_array = [];
var i;
for(i = 0; i < my_toggle.length; i++){
//my_toggle_array.push(0);
my_toggle[i].style.display = "none";
my_toggle_button[i].addEventListener("click", function(){
if(my_toggle[i].style.display == "none" /* || my_toggle_array[i] == 0 */){
my_toggle[i].style.display = "block";
my_toggle_button[i].innerHTML = "- show less";
//my_toggle_array[i] = 1;
} else {
my_toggle[i].style.display = "none";
my_toggle_button[i].innerHTML = "+ show more";
//my_toggle_array[i] = 0;
}
});
}
<div class="my_toggle">
<p class="lead"></p>
</div>
<button class="my_toggle_button"></button>
<!-- and so on 11 times <div class="my_toggle><p class="lead"></p></div><button class="my_toggle_button"></button> -->
This code doesn't work when I upload it in cPanel or at least not all of it, it works until these lines
for(i = 0; i < my_toggle.length; i++){
//my_toggle_array.push(0);
my_toggle[i].style.display = "none";
So basically the eventListener doesn't work, I tried like 2 hours in a script tag inside the page I wanted to do this toggle in but didn't work, then I put this code inside an external js file and I get like an error message "do not use functions inside a loop", why not using functions inside a loop?I commented out this code and used like this code which works but is way too long...
var my_toggle = document.getElementsByClassName('my_toggle');
var my_toggle_button = document.getElementsByClassName('my_toggle_button');
var my_toggle_id = [];
var my_toggle_button_id = [];
var i;
for(i = 0; i < my_toggle.length; i++){
my_toggle[i].setAttribute("id", "my_toggle_" + i.toString());
my_toggle_id.push("my_toggle_" + i.toString());
my_toggle_button[i].setAttribute("id", "my_toggle_button_" + i.toString());
my_toggle_button_id.push("my_toggle_button_" + i.toString());
}
function function1(){
let x = document.getElementById(my_toggle_id[0]);
let y = document.getElementById(my_toggle_button_id[0]);
if (x.style.display === "none") {
x.style.display = "block";
y.innerHTML = "- mostra di meno";
} else {
x.style.display = "none"; y.innerHTML = "+ scopri di più";
}
}
/* [...] and so on until */
function function11(){
let x = document.getElementById(my_toggle_id[10]);
let y = document.getElementById(my_toggle_button_id[10]);
if (x.style.display === "none") {
x.style.display = "block";
y.innerHTML = "- mostra di meno";
} else {
x.style.display = "none"; y.innerHTML = "+ scopri di più";
}
}
How can I add the EventListener to all classes without writing 130 lines of code?Is javascript the problem?Should I use PHP perhaps?Why?
The problem here is use of var.
The var statement declares a function-scoped or globally-scoped variable
Read about var and let
When you declare var i , increment it inside the loop to make it 1 and then click function is called, the value of i remains 1 and hence my_toggle[i] becomes undefined and my_toggle[i].style would throw an error "Cannot read property 'style' of undefined". Use let for your index i to keep it block scoped. See below code:
<!DOCTYPE html>
<head>
<title>The Alphabet</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="my_toggle">
<p class="lead">And so on 11 times</p>
</div>
<button class="my_toggle_button"></button>
</body>
<script type="text/javascript">
var my_toggle = document.getElementsByClassName('my_toggle');
var my_toggle_button = document.getElementsByClassName('my_toggle_button');
var my_toggle_array = [];
for(let i = 0; i < my_toggle.length; i++){
//my_toggle_array.push(0);
my_toggle[i].style.display = "none";
my_toggle_button[i].addEventListener("click", function(){
if(my_toggle[i].style.display == "none" /* || my_toggle_array[i] == 0 */){
my_toggle[i].style.display = "block";
my_toggle_button[i].innerHTML = "- show less";
//my_toggle_array[i] = 1;
} else {
my_toggle[i].style.display = "none";
my_toggle_button[i].innerHTML = "+ show more";
//my_toggle_array[i] = 0;
}
});
}
</script>
</html>

Displaying div based on dropdown value

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 :)

Whats wrong with me code (dom+onclick+li+display)?

Working
tutorial.onclick = function(){
var tutorial = document.getElementById("tutorials-ul");
tutorial.style.display = "list-item";
}
Not working
news.onclick = function(){
var news = document.getElementById("news-ul");
if(news.style.display == "none") {
news.style.display = "list-item";
}
else if(news.style.display == "list-item") {
news.style.display = "none";
}
}
Any answer or opinion is accepted.
I assume the outer news is a button that has already been assigned to a variable (or the default global via its ID).
The issue is if the element itself does not have a display set in its style attribute, then its initial value will be "" instead of whatever was given in CSS.
Therefore instead of comparing to "none", compare to "".
news.onclick = function() {
var news = document.getElementById("news-ul");
if (news.style.display == "") {
news.style.display = "list-item";
} else {
news.style.display = "";
}
}
#news-ul {
display: none
}
<button id=news>CLICK FOR NEWS</button>
<ul id="news-ul">
<li>TEST
</ul>
I figured it out using this stack overflow Get a CSS value with JavaScript
The correct code for showing and hiding the nested uls is
news.onclick = function(){
var news = document.getElementById("news-ul");
function compareDisplayValue(){
var element = document.getElementById("news-ul");
var style = window.getComputedStyle(element);
var display = style.getPropertyValue('display');
if(display == "none"){
news.style.display = "list-item";
}
else if (display == "list-item"){
news.style.display = "none";
}
}
compareDisplayValue();
}

Create an array of a parents children in javascript

I am trying to create an array of a parent div's (id="lol") children and them fetch them to change display:none; except for the child with id="a". I've tried this but it doesn't work. How can I improve this to get it to work?
function myFunction() {
var x = document.getElementById('a');
var children = [].slice.call(document.getElementById('lol').getElementsByTagName('*'),0);
var arrayLength = children.length;
for (var i = 0; i < arrayLength; i++) {
var name = children[i].getAttribute('id');
var z = document.getElementById(name);
z.style.display = 'none';
}
x.style.display = 'block';
}
If every child has an id attribute than it will work. Otherwise, some children might not have id attribute, in that case variable z will be undefined and accessing style property over z which is undefined will give error. Simple fix would be just handling undefined variable:
if(z)
z.style.display = 'none';
Same goes with variable x, too.
function myFunction() {
var children = [].slice.call(document.getElementById('lol').getElementsByTagName('*'),0);
var arrayLength = children.length;
for (var i = 0; i < arrayLength; i++) {
children[i].style.display = 'none';
}
document.getElementById('a').style.display = 'block';
}
How about using jQuery?
$('#lol').children(':not(#a)').hide();
If jQuery is not an option you can do this:
var lol = document.getElementById('lol');
var children = lol.querySelectorAll(':not(#a)');
for(var i=0;i<children.length;i++) {
children[i].style.display = 'none';
}
Even more "low-level":
var lol = document.getElementById('lol');
var children = lol.childNodes;
for(var i=0;i<children.length;i++){
if(children[i].id != 'a') {
children[i].style.display = 'none';
}
}

Categories

Resources