I've been studying javaScript for two weeks now and I know there must be a better wayf doing what is shown bellow.
This is what happens:
The function myId() call another function and receives back a parameter that can be mk-prod06, mk-prod05, mk-prod04, mk-prod03. But I was wondering if I can make this function more flexible by accepting any parameter (mk-prod0x) where x can be any number. I don't' want to hand write every "if" for it. Is that even possible in this case? Thank you.
//Hides and shows product boxes
function myId() {
adjustStyle();
var showProduct6, showProduct5, showProduct4, showProduct3, hideProduct6, hideProduct5, hideProduct4, hideProduct3;
if (oProdId === "mk-prod06") {
showProduct6 = document.getElementById("mk-prod06");
showProduct5 = document.getElementById("mk-prod05");
showProduct4 = document.getElementById("mk-prod04");
showProduct3 = document.getElementById("mk-prod03");
showProduct6.style.display = "inline";
showProduct5.style.display = "inline";
showProduct4.style.display = "inline";
showProduct3.style.display = "inline";
}
if (oProdId === "mk-prod05") {
hideProduct6 = document.getElementById("mk-prod06");
hideProduct6.style.display = "none";
showProduct5 = document.getElementById("mk-prod05");
showProduct4 = document.getElementById("mk-prod04");
showProduct3 = document.getElementById("mk-prod03");
showProduct5.style.display = "inline";
showProduct4.style.display = "inline";
showProduct3.style.display = "inline";
}
if (oProdId === "mk-prod04") {
hideProduct6 = document.getElementById("mk-prod06");
hideProduct5 = document.getElementById("mk-prod05");
hideProduct6.style.display = "none";
hideProduct5.style.display = "none";
showProduct4 = document.getElementById("mk-prod04");
showProduct3 = document.getElementById("mk-prod03");
showProduct4.style.display = "inline";
showProduct3.style.display = "inline";
}
if (oProdId === "mk-prod03") {
hideProduct6 = document.getElementById("mk-prod06");
hideProduct5 = document.getElementById("mk-prod05");
hideProduct4 = document.getElementById("mk-prod04");
hideProduct6.style.display = "none";
hideProduct5.style.display = "none";
hideProduct4.style.display = "none";
showProduct3 = document.getElementById("mk-prod03");
showProduct3.style.display = "inline";
}
if (oProdId === "mk-prod02") {
hideProduct6 = document.getElementById("mk-prod06");
hideProduct5 = document.getElementById("mk-prod05");
hideProduct4 = document.getElementById("mk-prod04");
hideProduct3 = document.getElementById("mk-prod03");
hideProduct6.style.display = "none";
hideProduct5.style.display = "none";
hideProduct4.style.display = "none";
hideProduct3.style.display = "none";
}
}
Well, you basically have written out a loop. And it's quite trivial to formulate that loop explicitly:
function myId() {
adjustStyle();
var x = // the number, wherever you got it from. Maybe:
// parseInt(oProdId.slice(7), 10)
for (var i=6; i>2; i--) {
var product = document.getElementById("mk-prod"+("0"+i).slice(-2));
product.style.display = i > x ? "none" : "inline";
}
}
Something like this should work:
function hideShow(id) {
var upTo = id.match(/md-prod0(\d)/)[1];
for (var i = 3; i < 6; i++) {
var element = document.getElementById('md-prod0' + i);
if (i <= upTo) element.style.display = 'inline';
else element.style.display = 'none';
}
}
You have to adjust it slightly if more elements will be added.
Basically it loops over 3 to 6 and checks whether the current element is less than or equal to the given ID. In that case it shows the element. Otherwise it hides it.
Related
When I click on the link for "id2", it executes the filter function for every link, ending with "id5" as the visible filtered list on my page.
<script>
window.onload = function() {
var a = document.getElementById("id1");
var b = document.getElementById("id2");
var c = document.getElementById("id3");
var d = document.getElementById("id4");
var e = document.getElementById("id5");
var x = document.getElementsByClassName("className")
a.onclick = filter(a.id);
b.onclick = filter(b.id);
c.onclick = filter(c.id);
d.onclick = filter(d.id);
e.onclick = filter(e.id);
function filter(tag) {
for (var i = 0; i < x.length; i++)
if (tag === "view all") {
x[i].style.display = "block";
}
else {
if (tag.toLowerCase() === x[i].getAttribute('alt').toLowerCase())
x[i].style.display = "block";
else
x[i].style.display = "none";
}
return false;
}
}
The top part where I have set up my links appears as follows:
View All
ID 2
ID 3
ID 4
ID 5
The filter works correctly, the only issue is that it is executing the function for all links!
Thank you in advance for the help.
What is happening is your functions are executing as soon as you are trying to assign the event handler.
Any function with (); after it will get executed.
You can use the concept of closures and return a new function. Use a function wrapper which returns a new function for each of your tag.
a.onclick = filter(a.id);
b.onclick = filter(b.id);
c.onclick = filter(c.id);
d.onclick = filter(d.id);
e.onclick = filter(e.id);
function filterWrapper(tag) {
var tagValue = tag;
return function filter() {
let tag = tagValue;
for (var i = 0; i < x.length; i++)
if (tag === "view all") {
x[i].style.display = "block";
}
else {
if (tag.toLowerCase() === x[i].getAttribute('alt').toLowerCase())
x[i].style.display = "block";
else
x[i].style.display = "none";
}
return false;
}
}
}
Obviously, you could have fetched the value of id attribute inside the function itself. this inside event handler belongs to the element itself.
a.onclick = filter;
b.onclick = filter;
c.onclick = filter;
d.onclick = filter;
e.onclick = filter;
function filter() {
let tag = this.getAttribute('id');
for (var i = 0; i < x.length; i++)
if (tag === "view all") {
x[i].style.display = "block";
}
else {
if (tag.toLowerCase() === x[i].getAttribute('alt').toLowerCase())
x[i].style.display = "block";
else
x[i].style.display = "none";
}
return false;
}
}
I have built out an example of what I'm trying to accomplish. I want to be able to make an array of passwords where if one is correct, then they are all sent to another page. However, in the following example it is not working. If I input the name that is suppose to pop up with a hello message it states its wrong when I have it in an Array.
let textarea = document.getElementById('banner');
let okbutton = document.getElementById('btn');
let form = document.getElementById('user-form');
let textBox = document.getElementById('text-box');
let spanMe = document.getElementById('spans');
let userNameIs = ['marquise', 'quise', 'tom'];
textarea.style.display = 'none';
spanMe.style.display = 'none';
textarea.style.display = 'none';
okbutton.addEventListener('click', function() {
if (textBox.value.length <= 4) {
spanMe.style.display = 'block';
spanMe.style.color = 'red';
} else if (textBox == userNameIs[1]) {
spanMe.style.display = 'none';
textarea.style.display = "block"
textarea.innerText = 'hello' + ' ' + textBox.value;
} else if (textBox != userNameIs[1])
spanMe.style.display = 'block';
spanMe.style.color = 'red';
});
Yesterday I was trying to make a slider on radio buttons with JavaScript and after few hours finished with code cited below. I'm quite new to JavaScript but know that repeating actions should be placed in a loop. So is there any chance to do that?
var slide = document.getElementsByClassName('slide');
var radio = document.querySelectorAll('.slider-form [type="radio"]');
var x = function () {
for( var i = 0; i < slide.length; i += 1) {
if(radio[i].checked === true) {
slide[i].style.display = "flex";
}
}
}
x();
radio[0].addEventListener('change', function () {
slide[0].style.display = "flex";
slide[1].style.display = "none";
slide[2].style.display = "none";
});
radio[1].addEventListener('change', function () {
slide[0].style.display = "none";
slide[1].style.display = "flex";
slide[2].style.display = "none";
});
radio[2].addEventListener('change', function () {
slide[0].style.display = "none";
slide[1].style.display = "none";
slide[2].style.display = "flex";
});
And the second question is, can I somehow bind my radio[number] with slide[same number], so I could just change classes like in this example:
$("input[type=radio]:not(:checked)").addClass("hiddenRadio");
Again, I'm interested in minimizing my code (because there could be ten or more buttons), so is there any way to apply changing of the class in 1-2 lines of code or in a loop.
Try below solution. I think this will solve your problem.
var slides = document.querySelectorAll('.slide');
var radios = document.querySelectorAll('.slider-form [type="radio"]');
function hideAllSlide() {
slides.forEach(function(slide) {
slide.style.display = 'none';
});
}
radios.forEach(function(radio, index) {
if(radio.checked){
slides[index].style.display = 'flex';
}
radio.addEventListener('change', function() {
hideAllSlide();
slides[index].style.display = 'flex';
});
});
I am currently running a page that requires a drop-down menu and three radio buttons for user selections. Each time the user changes their selection, a div is displayed based on their selection while all other divs are hidden. My current JavaScript works, but it's a massive, and probably inefficient mess.
EX:
function enrollmentChange() {
var enrollmentChoice = document.getElementById("enrollmentChoice");
if (document.getElementById("onC").checked) {
if (enrollmentChoice.options[enrollmentChoice.selectedIndex].text === "Please select enrollment status") {
document.getElementById("full-timeOn").style.display = "none";
document.getElementById("three-quarter-timeOn").style.display = "none";
document.getElementById("half-timeOn").style.display = "none";
document.getElementById("less-than-half-timeOn").style.display = "none";
document.getElementById("full-timeOff").style.display = "none";
document.getElementById("three-quarter-timeOff").style.display = "none";
document.getElementById("half-timeOff").style.display = "none";
document.getElementById("less-than-half-timeOff").style.display = "none";
document.getElementById("full-timeComm").style.display = "none";
document.getElementById("three-quarter-timeComm").style.display = "none";
document.getElementById("half-timeComm").style.display = "none";
document.getElementById("less-than-half-timeComm").style.display = "none";
}
You can see it all here http://jsfiddle.net/5h3kL/2/.
Is there a way for me to condense this into some type of loop? I have played around with a few loops, but I'm uncertain of how to make the loop consider both the radio button selection and drop-down menu selection.
I think this might shorten things a bit:
function enrollmentChange() {
var id = document.getElementById, // short hand
choice = id("enrollmentChoice").options[id("enrollmentChoice").selectedIndex].text,
which = id("onC").checked ? "On" :
id("offC").checked ? "Off" :
id("comm").checked ? "Comm" : "";
if (which !== "") {
["On", "Off", "Comm"].forEach(function(w) {
id("full-time" + w).style.display = "none";
id("three-quarter-time" + w).style.display = "none";
id("half-time" + w).style.display = "none";
id("less-than-half-time" + w).style.display = "none";
});
if (choice === "Full Time (12 or More Credit Hours)") {
id("full-time" + which).style.display = "block";
} else if (choice === "Three-Quarter Time (9-11 Credit Hours)") {
id("three-quarter-time" + which).style.display = "block";
} else if (choice === "Half Time (6-8 Credit Hours)") {
id("half-time" + which).style.display = "block";
} else {
id("less-than-half-time" + which).style.display = "block";
}
}
}
You can do something like that:
var enrollmentChoice = document.getElementById("enrollmentChoice");
var arraymap = ['Please select enrollment status',''],
['Full Time (12 or More Credit Hours)','three-quarter-timeOn'],
['Half Time (6-8 Credit Hours)','half-timeOn'] ... ;
var inputs = document.getElementsByTagName('input');
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].type.toLowerCase() == 'radio') {
for(var ii=0;ii<arraymap.length;ii++){
if(arraymap[ii][0] == enrollmentChoice.options[enrollmentChoice.selectedIndex].text && arraymap[ii][1] == inputs[i].id){
inputs[i].style.display = 'block';
}else{
inputs[i].style.display = 'none';
}
}
}
}
This works fine at all times except for the first time tab_toggle(0) is called.
when the first time this function is called the #box_home has display:block; so the function shouldn't do anything but whats happening is #box_port(the next div) is getting display:block; and #box_home remaining display:block as before. why is this happening. is it because when the function is called the variable has value undefined so doing some random thing.
Please answer this in javascript only, dont answer in jquery.
i couldnt make it work just this part in jsfiddle so i am sharing the entire webpage code
http://goo.gl/dhTUDH
<!-- Javascript -->
<script>
function tab_toggle(x) {
console.log("tab_toggle");
var home = document.getElementById("box_home").style;
var port = document.getElementById("box_port").style;
var about = document.getElementById("box_about").style;
var contact = document.getElementById("box_contact").style;
var box = [home,port,about,contact];
switch (x) {
case 0:
if (home.display == "block") {
console.log('end');
} else if (port.display == "block") {
box[0].display = "block";
box[1].display = "none";
} else if (about.display == "block") {
box[1].display = "block";
box[2].display = "none";
} else {
box[2].display = "block";
box[3].display = "none";
}
break;
default:
if (home.display == "block") {
box[0].display = "none";
box[1].display = "block";
} else if (port.display == "block") {
box[1].display = "none";
box[2].display = "block";
} else if (about.display == "block") {
box[2].display = "none";
box[3].display = "block";
} else {}
break;
}
}
<!-- HTML -->
◀
▶
<div id="box_home"></div>
<div id="box_port"></div>
<div id="box_about"></div>
<div id="box_contact"></div>
<!-- CSS -->
#box_home{display:block;}\
#box_port{display:none;}
#box_about{display:none;}
#box_contact{display:none;}
You can't access a style directly as a property, as in
home.display
Instead, use the getComputedStyle() method
getComputedStyle(home).display
element.style will get the element's inline style. Try getComputedStyle or add a class.
getComputedStyle(box[0]).getPropertyValue("display")
Not sure what would you achieve, but this should work:
var currentElement = 0;
(tab_toggle = function (x) {
var home = document.getElementById("box_home").style;
var port = document.getElementById("box_port").style;
var about = document.getElementById("box_about").style;
var contact = document.getElementById("box_contact").style;
var box = [home, port, about, contact];
if (currentElement + x < 0 || currentElement + x > box.length - 1)
return;
currentElement += x;
console.log("toggled " + currentElement);
for (var i = 0; i < box.length; i++) {
box[i].display = "none";
}
box[currentElement].display = "block";
})(0);