I have a sequence of button groups that will change depending on what button was clicked before. I have the first group to choose the type of the piece the user is creating (for example a shirt or a hoodie), and depending on what type the user chooses it will generate a different group to choose its design.
To do that I created a button group with only one hidden button on my HTML file, when the user chooses a type a for loop creates the next group cloning the hidden button, displaying it, and inserting some text.
JavaScript
var designs = {
shirt : ['Simple', 'V-Neck', 'Polo'],
hoodie : ['Sweater', 'Hoodie'],
}
function chooseType(type) {
var btnGroup = document.getElementById('btn-group');
var btn = document.getElementById('design-btn');
for (k in designs){
if (type == k) {
for (i=0; i < designs[k].length; i++) {
var clone = btn.cloneNode(true);
btnGroup.appendChild(clone);
clone.classList.remove('d-none');
clone.innerHTML = designs[k][i];
}
}
}
}
However, in order to generate the next step, I would have to know what design the user chose to put it as a parameter on my chooseDesign(design) function on the same way I had type as a parameter on my chooseType(type) function.
HTML
<div id="design" class="d-none">
<p>Design da peça:</p>
<div class="btn-group" role="group" id="btn-group">
<button onclick="chooseDesign()" type="button" class="d-none" id="design-btn"></button>
</div>
</div>
Is there a way to insert a different parameter on the chooseDesign(design) function to each button after it was cloned?
This uses event delegation to listen for clicks. NOTE: I had to add the Shirt and Hoodie to demonstrate.
var designs = {
shirt : ['Simple', 'V-Neck', 'Polo'],
hoodie : ['Sweater', 'Hoodie'],
}
const createButton = (style) => {
let button = document.createElement('button');
button.dataset.style = style;
button.innerText = style;
return button;
}
function chooseType(type) {
let btnGroup = document.getElementById('btn-group');
btnGroup.innerHTML = "";
designs[type].forEach(s => {
btnGroup.appendChild(createButton(s));
});
}
document.addEventListener('click', (e) => {
if(e.target.matches('.design-select')) {
chooseType(e.target.id);
}
});
<div id="design" class="d-none">
<p>Design da peça:</p>
<button id="shirt" class="design-select">Shirt</button>
<button id="hoodie" class="design-select">Hoodie</button>
<div class="btn-group" role="group" id="btn-group">
</div>
</div>
Related
I am very new to javascript I have been working on a to-do app for the last couple of days, for a coding Bootcamp project and I have updated my coding format so that it is easier to read than what I had before but now the edit and delete functions are not working.
I set up the id and elements for the tasks.
const createTask = () => {
const id = createId()
const task = elements.input.value;
const date = elements.cal.value;
if(!task && !date) return alert("Please fill in task and select date");
if(!task) return alert("Please fill in task");
if(!date) return alert("Please select date");
const tasks = document.createElement("div");
tasks.innerHTML = `
<button class = "sort" data-id="${id}">Sort</button>
<div class="task" date-id = "${id}">
<div class="content">
<input type ="checkbox" class="tick">
<input type ="text" class = text id = "text" data-id="" readonly>${task}
<label class = "due-date" for ="text">${date}</label>
<input type ="date" class = date id = "date">
</div>
<div class = "actions">
<button class="edit" data-id="${id}">Edit</button>
<button class="delete" data-id="${id}">Delet</button>
</div>
</div>
`
elements.list.appendChild(tasks)
return tasks
}
I set up the event listener for the submit, edit and delete. The add list button works fine but the edit and delete button are not working.
elements.list.addEventListener('click',event => {
const {target} = event;
const {id} = target.dataset
const task = id ? document.querySelector('[data-id="${id}"]'): null
const type = {
edit: event.target.classList.contains('edit'),
delete: event.target.classList.contains('delete'),
}
const isFromSaveLabel = target.innerText.toLowerCase() === 'save'
if(tasks && type.edit && isFromSaveLabel){
const text = task.querySelector('text')
target.innerText = 'Edit'
text.addAttribute('readonly')
return
}
if(tasks && type.edit){
const text = task.querySelector('text')
target.innerText = 'Save'
text.removeAttribute('readonly')
text.focus()
return
}
if(tasks && type.delete){
return
}
});
const submitHandler = (event) =>{
event.preventDefault();
createTask();
}
elements.form.addEventListener("submit", submitHandler);
Is it possible for someone to help me to have the following implemented in my code that does the following:
Sort the list alphabetically
can edit the calendar as well when you edit the list you want to change
save the user list using local storage.
It is just those 3 things that need to be added. I code almost every single day for hours and javascript is a bit challenging for me and I do struggle sometimes and this project is due on Friday.
I don't think this is a proper question but ill ask it anyway. I have multiple paragraphs and buttons dedicated to each paragraph. When a button is clicked it adds the name of the paragraphs id into an array. if I press another button it would add that one to the array and so on. how would I then show each paragraph in the order of they are in the array.
how would i show the hidden paragraphs and put them in the order as shown in the array.
var order = [];
document.getElementById("par1Button").onclick = function() {
var value = document.getElementById("par1Button").value
order.push(value);
alert(order)
}
document.getElementById("par2Button").onclick = function() {
var value = document.getElementById("par2Button").value
order.push(value);
alert(order)
}
document.getElementById("par3Button").onclick = function() {
var value = document.getElementById("par3Button").value
order.push(value);
alert(order)
}
<button id="par1Button" value="Par1">Par1</button>
<button id="par2Button" value="Par2">Par2</button>
<button id="par3Button" value="Par3">Par3</button>
<p id="par1" style="display:none;">This is text par1</p>
<p id="par2" style="display:none;">this is the par 2</p>
<p id="par1" style="display:none;">and this is par 3</p>
</body>
On every click , append the id to a hidden feild or an array with ',' or seperation symbols
Also on everyclick remove the button, else the same id will be added, which will be more difficult to manage...
finally split the hidden values and take your ids add display the paragraphs in order
its going to take some time so, please try yourself
Your question is not clear. From my understanding I hope this is what you are looking for.
<body>
<button name="toggle" id="par1Button" value="par1">Add Paragraph 1</button>
<button name="toggle" id="par2Button" value="par2">Add Paragraph 2</button>
<p id="par1" style="display:none;">This is text par1</p>
<p id="par2" style="display:none;">this is the par 2</p>
<button id="show">Show Paragraphs</button>
<script>
var listOfParagraphs = [];
document.getElementsByName('toggle').forEach(function(btn) {
btn.addEventListener('click', function(event) {
listOfParagraphs.push(event.target.value)
})
})
document.getElementById('show').addEventListener('click', function(e){
if(listOfParagraphs.length >= 1) {
listOfParagraphs.forEach(function(id) {
document.getElementById(id).style.display = "block"
})
}
})
</script>
</body>
I wouldn't bother with CSS display property. Just mapping the paragraph textContent accordingly is sufficient. When you click a button it will add the corresponding paragraph at the end of the array and will display the paragraphs in the order they exist in parray array. A second click of a button will remove the corresponding paragraph from the list.
var pars = {
par1: {id: "par1", textContent: "This is paragraph one"},
par2: {id: "par2", textContent: "This is paragraph two"},
par3: {id: "par3", textContent: "This is paragraph three"}
},
prgs = document.getElementsByTagName("p"),
buttons = document.getElementsByTagName("button"),
parray = [];
function displayPars(){
var i = 0;
for(var pel of prgs){
parray[i] ? pel.textContent = parray[i].textContent
: pel.textContent = "";
i++;
}
}
for(var button of buttons){
button.addEventListener("click", function(e){
var pid = e.currentTarget.id.substr(0,4),
pix = parray.findIndex(p => p.id === pid);
pix !== -1 ? parray.splice(pix,1)
: parray.push(pars[pid]);
displayPars();
});
}
<button id="par1Button" value="Par1">Par1</button>
<button id="par2Button" value="Par2">Par2</button>
<button id="par3Button" value="Par3">Par3</button>
<p id="par1"></p>
<p id="par2"></p>
<p id="par3"></p>
I'm trying to use localStorage to remember if the user has already voted. I have 5 buttons — all with a unique ID to help me keep track of things.
When a user clicks on one of these buttons (e.g., button-1), I store the ID of that button with a value. So in localStorage, it looks something like this: key: button-1, value: clicked.
If the user has already clicked (voted) on that button, it needs to display a message, something like "Thank you for your vote." Otherwise it should keep that button active.
I'm struggling to do this systematically if I have multiple buttons. Do I store a separate key for each button in localStorage? Do I append them under one key? I am not sure.
My JSFiddle is here as an example with 3 buttons http://jsfiddle.net/d8kt69rp
HTML
<div id="button-1">
<button value="yes" onclick="recordFeedback(1, this);">Button 1</button>
</div>
<div id="button-2">
<button value="yes" onclick="recordFeedback(2, this);">Button 2</button>
</div>
<div id="button-3">
<button value="yes" onclick="recordFeedback(3, this);">Button 3</button>
</div>
JS
// If user has already voted, just display them a 'thanks' message
if (localStorage.getItem('button-1')) {
var div = document.getElementById('button-1');
div.innerHTML = 'Thank for your feedback';
}
// Record user feedback based on the button they clicked
function recordFeedback(id, response) {
userResponse = response.value;
var div = document.getElementById('button-' + id);
if (userResponse === 'yes') {
div.innerHTML = 'Thanks for your feedback.';
console.log('button-' + id + ' was clicked.');
localStorage.setItem('button-' +id, 'clicked');
}
}
You can do something like this:
Fiddle: http://jsfiddle.net/AtheistP3ace/d8kt69rp/2/
HTML (added class to divs):
<div class="button-div" id="button-1">
<button value="yes" onclick="recordFeedback(1, this);">Button 1</button>
</div>
<div class="button-div" id="button-2">
<button value="yes" onclick="recordFeedback(2, this);">Button 2</button>
</div>
<div class="button-div" id="button-3">
<button value="yes" onclick="recordFeedback(3, this);">Button 3</button>
</div>
JS:
// Wait for DOM to be ready
document.addEventListener('DOMContentLoaded',
function() {
document.removeEventListener('DOMContentLoaded', arguments.callee, false);
// Get all the button divs
var buttons = document.getElementsByClassName('button-div');
var index = 0, length = buttons.length;
for (; index < length; index++) {
// For each one check if it has a localStorage value
if (localStorage.getItem(buttons[index].id) == 'clicked') {
buttons[index].innerHTML = 'Thank for your feedback';
}
}
}, false
);
As for having a key for each or keeping them all together. That's personal preference. Me, I would prefer keeping them together. Feels cleaner although a little more code.
Fiddle: http://jsfiddle.net/AtheistP3ace/d8kt69rp/4/
function recordFeedback(id, response) {
userResponse = response.value;
var div = document.getElementById('button-' + id);
if (userResponse === 'yes') {
div.innerHTML = 'Thanks for your feedback.';
// Get storage and parse it to an object
var storage = JSON.parse(localStorage.getItem('userResponses'));
// If storage doesn't exist initialize it
if (!storage) storage = {};
storage['button-' + id] = 'clicked';
// Make it a string and set it
localStorage.setItem('userResponses', JSON.stringify(storage));
}
}
document.addEventListener('DOMContentLoaded',
function() {
document.removeEventListener('DOMContentLoaded', arguments.callee, false);
var storage = JSON.parse(localStorage.getItem('userResponses'));
// Don't waste time finding or looping if no votes
if (storage) {
var buttons = document.getElementsByClassName('button-div');
var index = 0, length = buttons.length;
for (; index < length; index++) {
if (storage[buttons[index].id] == 'clicked') {
buttons[index].innerHTML = 'Thank for your feedback';
}
}
}
}, false
);
I have the following setup - http://codepen.io/anon/pen/WvjmLv?editors=100 and am trying to output text depending on which button is clicked
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button">2</button>
<button class="wrongAnswer" type="button">5</button>
<button class="right-answer" type="button">6</button>
<button class="wrong-answer" type="button">10</button>
<script>
var text;
var wrongAnswer = document.getElementsByClassName("wrongAnswer").addEventListener("click");
var rightAnswer = document.getElementsByClassName("rightAnswer").addEventListener("click");
if (wrongAnswer) {
text = "Incorrect!";
text = "Wrong!";
text = "Try Again!";
}
if (rightAnswer) {
text = "Correct!";
}
document.getElementById("answer").innerHTML = text;
</script>
</div>
<div>
<p id="answer"></p>
</div>
If the user selects the wrong answer, it should either read Wrong!, Incorrect! or Try Again! (without repeating the same text output if their next guess is also wrong)
If they get the answer right, it should just simply read Correct!
As I'm fairly new to JavaScript, I feel as though I'm a little bit off with my solution and was wanting to know how can I make this function work?
Thanks.
Easiest and fastest way to get the result you want is by adding onclick-eventhandlers to your buttons.
<button onclick="somefunction()"></button>
After that you can easily handle what should happen after that click.
In your case I would check what's in the class attribute of the button you clicked.
By doing this you can print the results to your #answer-container.
With a simple array and a global variable of which index is next you can output different "false"-messages.
var _i = 0;
var _wrongs = ['Incorrect!', 'Wrong!', 'Try Again!'];
function showResult(b) {
var res = document.getElementById('answer');
if (b.classList.contains('right-answer')) {
res.innerHTML = 'Correct'
} else {
res.innerHTML = _wrongs[_i];
_i = _i > 1 ? 0 : _i + 1;
}
}
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" onclick="showResult(this)">2</button>
<button class="wrongAnswer" onclick="showResult(this)">5</button>
<button class="right-answer" onclick="showResult(this)">6</button>
<button class="wrong-answer" onclick="showResult(this)">10</button>
</div>
<div>
<p id="answer"></p>
</div>
Demo on Codepen
Well, there are a couple things that you need to do:
You do not have a separate click handler function defined.
You need to properly add the event function to the addEventListener call.
You cannot attach an event to multiple elements at once. You need to loop over them.
Why do you have two different classes? i.e. 'wrongAnswer' and 'wrong-answer'? Please make sure that you stick with one convention.
I added an onReady() to wait for the DOM to load before accessing and adding listeners to the elements.
Addition Information
Below, I have wrapped the document.getElementsByClassName(className) call with [].slice.call(scope, [begin[, end]]) because the result of getElementsByClassName is a NodeList. You cannot treat a list like an array in JavaScript. Since I used Array.prototype.forEach to loop over the elements, they needed to transformed into an array. This is simply syntactic sugar in order to make the code look more aesthetically pleasing and readable.
This could have easily been accomplished with a for-loop:
var nodes = document.getElementsByClassName("rightAnswer");
for (var i = 0; i < nodes.length; i++) {
var el = nodes[i];
el.addEventListener('click', clickHandler);
}
Code
var wrongTextArr = ['Try Again!', 'Wrong!', 'Incorrect!'];
var guesses = 0;
onReady(function() {
// Set the number of guesses equal to the number of questions - 1.
guesses = document.querySelectorAll('.question button').length - 1;
[].slice.call(document.getElementsByClassName('wrongAnswer')).forEach(function(el) {
el.addEventListener('click', clickHandler);
});
[].slice.call(document.getElementsByClassName('rightAnswer')).forEach(function(el) {
el.addEventListener('click', clickHandler);
});
});
function clickHandler(e) {
var text = '';
var target = e.target;
var targetClass = target.className;
if (guesses < 1) {
text = 'You have reached the max number of attempts!';
} else if (targetClass === 'wrongAnswer') {
text = wrongTextArr[--guesses]; // Decrement guesses.
} else if (targetClass === 'rightAnswer') {
text = 'Correct!';
} else {
text = 'Unexpected Error!';
}
document.getElementById('answer').innerHTML = text;
}
function onReady(callback) {
var intervalID = window.setInterval(function() {
if (document.getElementsByTagName('body')[0] !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}, 1000);
}
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button">2</button>
<button class="wrongAnswer" type="button">5</button>
<button class="rightAnswer" type="button">6</button>
<button class="wrongAnswer" type="button">10</button>
</div>
<div>
<p id="answer"></p>
</div>
In the code above, I tried not to stray too far away from your original code, I just simply pointed out things that made your code not work and fix them with the minimalist amount of effort. Here is my solution that I would go with.
var wrongTextArr = ['Try Again!', 'Wrong!', 'Incorrect!'];
var guesses = 0;
onReady(function() {
// Set the number of guesses equal to the number of questions - 1.
guesses = document.querySelectorAll('.question button').length - 1;
addEventListeners('button[class$="Answer"]', 'click', function(e) {
document.getElementById('answer').innerHTML = getText(e.target.className.split());
});
});
function getText(classList) {
if (guesses < 1) {
return 'You have reached the max number of attempts!';
} else if (classList.indexOf('wrongAnswer') > -1) {
return wrongTextArr[--guesses]; // Decrement guesses.
} else if (classList.indexOf('rightAnswer') > -1) {
return 'Correct!';
} else {
return 'Unexpected Error!';
}
}
// Generic functions.
function addEventListeners(selector, event, listenerFn) {
[].slice.call(document.querySelectorAll(selector)).forEach(function(el) {
el.addEventListener(event, listenerFn);
});
}
function onReady(callback) {
var intervalID = window.setInterval(function() {
if (document.getElementsByTagName('body')[0] !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}, 1000);
}
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button">2</button>
<button class="wrongAnswer" type="button">5</button>
<button class="rightAnswer" type="button">6</button>
<button class="wrongAnswer" type="button">10</button>
</div>
<div>
<p id="answer"></p>
</div>
Lots of good answers.. Here is another approach,
HTML:
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button" onclick="checkAnswer(this)">2</button>
<button class="wrongAnswer" type="button" onclick="checkAnswer(this)">5</button>
<button class="rightAnswer" type="button" onclick="checkAnswer(this)">6</button>
<button class="wrongAnswer" type="button" onclick="checkAnswer(this)">10</button>
</div>
<div>
<p id="answer"></p>
</div>
JS:
<script>
var count = 0;
var wrongtext = ["Incorrect!", "Wrong!", "Try Again!"];
function checkAnswer(el) {
if (el.classList.contains('wrongAnswer')) {
count++;
if(count === 3)
count = 0;
alert(wrongtext[count])
}
if (el.classList.contains('rightAnswer')) {
alert('correct');
}
}
</script>
Demo:
https://jsfiddle.net/cubq361t/22/
I am not totally sure how to make it so it will say different things like "wrong" and "incorrect" but I hope this will point you in the right direction:
<!DOCTYPE html>
<html lang="en">
<body>
<div class="section">
<p>How many sides does a hexagon have?</p>
<input type="button" onClick="wrongAnswer()" value="2">
<input type="button" onClick="wrongAnswer()" value="5">
<input type="button" onClick="rightAnswer()" value="6">
<input type="button" onClick="wrongAnswer()" value="10">
<p id="text"></p>
</div>
<script>
function wrongAnswer() {
document.getElementById('text').innerHTML = "Wrong";
}
function rightAnswer() {
document.getElementById('text').innerHTML = "Correct!";
}
</script>
</body>
</html>
Here is an updated version of your code. The main issue you had was mixing up your variable and function names.
Here is a
Fiddle
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button">2</button>
<button class="wrongAnswer" type="button">5</button>
<button class="rightAnswer" type="button">6</button>
<button class="wrongAnswer" type="button">10</button>
</div>
<div>
<p id="answer"></p>
</div>
<script>
var text;
var wrongAnswers = document.getElementsByClassName("wrongAnswer");
var rightAnswers = document.getElementsByClassName("rightAnswer");
for (var i = 0; i < wrongAnswers.length; i++) {
// alert( wrongAnswers[i]);
wrongAnswers[i].addEventListener('click', printWrongAnswer);
}
for (var i = 0; i < rightAnswers.length; i++) {
rightAnswers[i].addEventListener('click', printRightAnswer);
}
function printRightAnswer() {
text = "Correct!";
printAnswer();
};
function printWrongAnswer() {
text = "Incorrect!";
text += "Wrong!";
text += "Try Again!";
printAnswer();
}
function printAnswer() {
document.getElementById("answer").innerHTML = text;
}
</script>
In addition to the answers of Mr. Polywhirl and Bellash:
If you are new to JavaScript you should try to understand how the EventBindings are working. Every binding in JavaScript is an event, so if you click somewhere the Browser will check if he will find a binding which is listening to the event "click". So its irrelevant when you bind the event but it has to be before the click. However you have to tell JavaScript which function he has to call if someone clicks your button! Thats because events are kinda "floating" in you browser scope, they are present but know one knows when they are actually be triggered but if they are getting triggered the script have to know what gets triggered or in other words: which functionality should be triggered now?
Your lines
var wrongAnswer = document.getElementsByClassName("wrongAnswer").addEventListener("click");
var rightAnswer = document.getElementsByClassName("rightAnswer").addEventListener("click");
are wrong because you never told the event "click" what functionality should be executed if the button is clicked.
The call or one type of a correct call would be:
var someFunction = function() { // DO YOUR AWESOME WORK PLS! }
var rightAnswer = document.getElementsByClassName("rightAnswer").addEventListener("click", someFunction);
and in addition to that:
I don't know how experienced you are in programming but this lines
text = "Incorrect!";
text = "Wrong!";
text = "Try Again!";
will override each other, because you are using the same variable in all 3 rows ;)
Mr. Polywhirl and Bellash posted you some good example to begin with. Try them out and try to understand them!
Hope this makes it a bit clearer!
cheers,
Sebastian
Here's a rewrite of your code, providing comments as a sort of tutorial:
Update: added random response generation.
HTML:
<div class="question">
<p>How many sides does a hexagon have?</p>
<!--
Use a common class ('answer-button' used here) for all buttons
so that clicks can be easily handled with a single listener.
Since you know any answers that aren't right are wrong, you can
simply add a 'right-answer' class for that one and leave the
others as is.
-->
<button class="answer-button" type="button">2</button>
<button class="answer-button" type="button">5</button>
<button class="answer-button right-answer" type="button">6</button>
<button class="answer-button" type="button">10</button>
</div>
<div>
<!--
Using an id is often unnecessary, so I'd switch this to a class.
Since the above buttons represent answers, using an "answer" class
on this paragraph can bring confusion, so I'd recommend using something
more accurate, such as "response".
-->
<p class="response"></p>
</div>
<!--
Generally you'll want your js in a separate file. If you include the script, whether
inline or separate, at the bottom of the body element, as you did initially, it will
automatically execute after the dom has initialized, which is good.
-->
JavaScript:
// Wrap in an immediately invoking function expression
// to keep your variables off the global scope.
(function() {
// Capture all of your response phrases in an object.
var responses = {
correct: [
"Correct!"
],
incorrect: [
"Wrong!",
"Try Again!",
"Incorrect!"
]
};
// Get the element that will display your answer.
// getElementsByClassName returns an array, so get the
// first element in the array.
var response = document.getElementsByClassName('response')[0];
// Get all of the answer buttons.
var answerButtons = document.getElementsByClassName('answer-button');
// Set a listener on each answerButton element.
for (var i = 0; i < answerButtons.length; i++) {
// Add the event listener to the element. When the event occurs,
// the checkAnswer function will run, and will be passed an event object.
answerButtons[i].addEventListener('click', checkAnswer);
}
// event is an object that is automatically passed in
// when the listener calls this function, and event.target
// is the element where the event occurred.
function checkAnswer(event) {
// initialize a variable for the message
var message;
// get the element where the event occurred
var element = event.target;
// get all classes from target element
var classes = event.target.className;
// classes will be in a space-separated string, so
// we convert that to an array
classes = classes.split(' ');
// check if a specific class is in the array
if (classes.indexOf('right-answer') >= 0) {
// if the 'right-answer' class is there, they
// clicked the right answer.
message = getRandomArrayElement(responses.correct);
} else {
// otherwise, they clicked the wrong answer
message = getRandomArrayElement(responses.incorrect);
}
// set the target element's content to the message
response.textContent = message;
}
function getRandomArrayElement(array) {
// This function picks a random element from an array and
// returns it.
// You're going to want to pick one of these array items by their
// index, so we'll set up variables to capture the lowest and
// highest possible numbers that can be used.
var min = 0;
var max = array.length - 1;
// Javascript provides random numbers using the Math.random function,
// wich gives a random float between 0 and 1. The expression below
// uses that to generate a random number within a given range - in this
// case, between min and max.
var index = Math.floor(Math.random() * (max - min + 1)) + min;
return array[index];
}
})();
I have edited your code to help you understand how you could deal with .getElementsByClassName
<div class="question">
<p>How many sides does a hexagon have?</p>
<button class="wrongAnswer" type="button">2</button>
<button class="wrongAnswer" type="button">5</button>
<button class="rightAnswer" type="button">6</button>
<button class="rightAnswer" type="button">10</button>
</div>
<div>
<p id="answer">ok</p>
</div>
<script>
var text="...",
wrongs=document.getElementsByClassName("wrongAnswer"),
rights=document.getElementsByClassName("rightAnswer"),
wrongTexts=["Incorrect","Try Again","Wrong!"],
i=0;
for(var i=0; i< wrongs.length; i++){
wrongs[i].addEventListener("click",function(e){
text = "Incorrect!";
DisplayText();
});
}
for(var i=0; i< rights.length; i++){
rights[i].addEventListener("click",function(e){
text = "Correct!";
DisplayText();
});
}
function DisplayText(){
i=i%wrongTexts.length;
text=text=="Correct"?text:wrongTexts[i++];
document.getElementById("answer").innerHTML = text;
}
</script>
Make a function first and the assign it to the buttons like
<button onclick="myFunction()">Click me</button>
<p class="demo"></p>
Then in the JS
function myFunction() {
document.getElementByClassName("demo").innerHTML = "Hello World";
}
in your pen make a function add all the logic in it and call it on button click
I have a simple product page with a few sizes and an add to cart button. I want to use jquery to $("").toggle(); a message saying "choose a size" if a size isn't selected onClick of the Add to Cart button.
Here is my code:
ryan.js
function ryanClicked(id, b, c){
b = b || null;
c = c || null;
document.getElementById(id).style.borderColor = "black";
document.getElementById(b).style.borderColor = "#e0e0e0";
document.getElementById(c).style.borderColor = "#e0e0e0";
}
html.html
<div class="pp">
<div id ="sizeButton1"class="sizeButton" onclick="ryanClicked('sizeButton1','sizeButton2','sizeButton3')"> S </div>
<div id ="sizeButton2"class="sizeButton" onclick="ryanClicked('sizeButton2','sizeButton1','sizeButton3')"> M </div>
<div id ="sizeButton3"class="sizeButton" onclick="ryanClicked('sizeButton3','sizeButton1','sizeButton2')"> L </div>
</div> <br>
//I want to prevent the onClick from happening if size is not selected
<p class="ryanAddButton" onclick="simpleCart.add('quantity=1','name=Black Gold','price=58','image=images/thumbs/blackGold.jpg');return false;" >Add to Cart</p>
<p class ="hiddenTilClicked"> You must select a size! </p>
I want the onclick to be called when a size is selected and I want a jquery toggle to be called if a size is not selected.
How can I do this? I can just use js if statement but I don't know how to use JS to display html.
edit: can i pass in a function to be called in js? is that a callback? the simplecart.add() will have different parameters for each item
You need to set a style and width on your border.
Use a variable to track if a style was selected or not.
b = b || null isnt needed because you always pass in a parameter
var sizeSelected = false;
function ryanClicked(id, b, c) {
sizeSelected = true;
document.getElementById(id).style.border = "1px solid black";
document.getElementById(b).style.border = "1px solid #e0e0e0";
document.getElementById(c).style.border = "1px solid #e0e0e0";
}
function addClicked() {
if (sizeSelected) {
document.getElementById('hiddenTilClicked').style.display = 'none';
simpleCart.add('quantity=1', 'name=Black Gold', 'price=58', 'image=images/thumbs/blackGold.jpg');
} else {
document.getElementById('hiddenTilClicked').style.display = 'block';
}
}
.hiddenTilClicked {
display: none;
}
<div class="pp">
<div id="sizeButton1" class="sizeButton" onclick="ryanClicked('sizeButton1','sizeButton2','sizeButton3')">S</div>
<div id="sizeButton2" class="sizeButton" onclick="ryanClicked('sizeButton2','sizeButton1','sizeButton3')">M</div>
<div id="sizeButton3" class="sizeButton" onclick="ryanClicked('sizeButton3','sizeButton1','sizeButton2')">L</div>
</div>
<br>
<p class="ryanAddButton" onclick="addClicked();">Add to Cart</p>
<p id="hiddenTilClicked" class="hiddenTilClicked">You must select a size!</p>
You can simply add a flag that tells if a button has been clicked or not. And instead of directly calling the add function of the simpleCart you can make a new function for the click and wrap your product addition to the cart happen only when a button has been clicked.
You also need to set the hidden element hidden by style and toggle the style to visible only when the customer tries to add a product to the cart without selecting a size.
HTML:
<div class="pp">
<div id ="sizeButton1"class="sizeButton" onclick="ryanClicked(this.id)"> S </div>
<div id ="sizeButton2"class="sizeButton" onclick="ryanClicked(this.id)"> M </div>
<div id ="sizeButton3"class="sizeButton" onclick="ryanClicked(this.id)"> L </div>
</div> <br>
//I want to prevent the onClick from happening if size is not selected
<p class="ryanAddButton" onclick="simpleCart.add('quantity=1','name=Black Gold','price=58','image=images/thumbs/blackGold.jpg');return false;" >Add to Cart</p>
<p id="hiddenTilClicked" style={ visibility: none }> You must select a size! </p>
JS:
var sizeSelected = false;
function ryanClicked(id){
// set the flag that some size has been selected
sizeSelected = true;
// hide the warning since a size was selected
$('#hiddenTilClicked').css('visibility', 'hidden');
// add the border colors
$('.sizeButton').each(function(i, element) {
if(element.id == id) {
element.style.borderColor = "black";
} else {
element.style.borderColor = "#e0e0e0";
}
});
}
function addToCart() {
// add to cart only when a size was selected
if(sizeSelected) {
simpleCart.add('quantity=1','name=Black Gold','price=58','image=images/thumbs/blackGold.jpg')
} else {
$('#hiddenTilClicked').css('visibility', 'visible');
}
}
Here is a fiddle where you can test it: http://jsfiddle.net/sqkosy0b/
You can set a flag and put this simpleCart.add('quantity=1','name=Black Gold','price=58','image=images/thumbs/blackGold.jpg');return false;" inside JS:
HTML:
<p class="ryanAddButton" onclick="checkIfSel()" >Add to Cart</p>
JS:
var flag=0;
function ryanClicked(id, b, c){
b = b || null;
c = c || null;
document.getElementById(id).style.borderColor = "black";
document.getElementById(b).style.borderColor = "#e0e0e0";
document.getElementById(c).style.borderColor = "#e0e0e0";
flag=1;
}
function checkIfSel(){
if(flag==1){
simpleCart.add('quantity=1','name=Black Gold','price=58','image=images/thumbs/blackGold.jpg');
$('.hiddenTilClicked').hide();
}
else{
$('.hiddenTilClicked').show(); //OR document.getElementsByClassName('hiddenTilClicked')[0].style.display="block";
}
}
You'll have to set a variable in ryanclicked that will check if a button has been clicked:
add this line to ryan clicked:
sizeselect = false;
function ryanClicked(id, b, c) {
sizeselect = true;
}
You can associate a function with the onclick button like this:
<p class="ryanAddButton" onclick="checkforclick()" >Add to Cart</p>
And you can define your function like this:
function checkforclick()
{
if(sizeselect)
{
simpleCart.add('quantity=1', 'name=Black Gold', 'price=58', 'image=images/thumbs/blackGold.jpg');
}
else
{
document.getElementsByClassName('hiddenTilClicked')[0].style.display = 'block';
}
}