Avoiding repetitive onclick statements
up vote
2
down vote
favorite
I have a website that has loads of questions. When you click the question, you get the answer. My code looks a little like this:
$(document).on('click','#panel1question1',function(){
if (oneone % 2 == 0) {
$(this).html(answerarraylvl1_js[2]);
oneone++;
console.log(oneone);}
else {
$(this).html(questionarraylvl1_js[2]);
oneone++;
console.log(oneone);
}
});
The problem is that I can have upto 75 questions displayed.
I don't want to have to copy and paste a snippet for each of those div elements. It's going to generate a massive file. I also don't want to have a toggle variable for each question. I'd end up with a lot of variables.
I do however, have naming conventions. Is there a way to say : do this code for panelxquestiony and specify x and y?
EDIT: A little more detail. The code is supposed to run this site (http://ticktockmaths.co.uk/ticktockquestions/index.php?id=1&sid=5 -> practise questions). The user gets some questions (from an array) and they can click to see an answer (from an array).
The user will be able to add questions to the screen (up to a maximum of about 20).
I want every question to have a on click listener. So the next question would need to have the following code.
$(document).on('click','#panel1question2',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>2. </strong>' + answerarraylvl1_js[3]);
oneone++;
console.log(oneone);}
else {
$(this).html('<strong>2. </strong>' + questionarraylvl1_js[3]);
oneone++;
console.log(oneone);
}
});
I was wondering if I could do something like
$(document).on('click','#panel1questionN',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>N. </strong>' + answerarraylvl1_js[N+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>N. </strong>' + questionarraylvl1_js[N+1]);
NN++;
console.log(NN);
}
});
for N where N is the number of questions the user has asked for
javascript jquery
|
show 1 more comment
up vote
2
down vote
favorite
I have a website that has loads of questions. When you click the question, you get the answer. My code looks a little like this:
$(document).on('click','#panel1question1',function(){
if (oneone % 2 == 0) {
$(this).html(answerarraylvl1_js[2]);
oneone++;
console.log(oneone);}
else {
$(this).html(questionarraylvl1_js[2]);
oneone++;
console.log(oneone);
}
});
The problem is that I can have upto 75 questions displayed.
I don't want to have to copy and paste a snippet for each of those div elements. It's going to generate a massive file. I also don't want to have a toggle variable for each question. I'd end up with a lot of variables.
I do however, have naming conventions. Is there a way to say : do this code for panelxquestiony and specify x and y?
EDIT: A little more detail. The code is supposed to run this site (http://ticktockmaths.co.uk/ticktockquestions/index.php?id=1&sid=5 -> practise questions). The user gets some questions (from an array) and they can click to see an answer (from an array).
The user will be able to add questions to the screen (up to a maximum of about 20).
I want every question to have a on click listener. So the next question would need to have the following code.
$(document).on('click','#panel1question2',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>2. </strong>' + answerarraylvl1_js[3]);
oneone++;
console.log(oneone);}
else {
$(this).html('<strong>2. </strong>' + questionarraylvl1_js[3]);
oneone++;
console.log(oneone);
}
});
I was wondering if I could do something like
$(document).on('click','#panel1questionN',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>N. </strong>' + answerarraylvl1_js[N+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>N. </strong>' + questionarraylvl1_js[N+1]);
NN++;
console.log(NN);
}
});
for N where N is the number of questions the user has asked for
javascript jquery
1
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
1
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15
|
show 1 more comment
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I have a website that has loads of questions. When you click the question, you get the answer. My code looks a little like this:
$(document).on('click','#panel1question1',function(){
if (oneone % 2 == 0) {
$(this).html(answerarraylvl1_js[2]);
oneone++;
console.log(oneone);}
else {
$(this).html(questionarraylvl1_js[2]);
oneone++;
console.log(oneone);
}
});
The problem is that I can have upto 75 questions displayed.
I don't want to have to copy and paste a snippet for each of those div elements. It's going to generate a massive file. I also don't want to have a toggle variable for each question. I'd end up with a lot of variables.
I do however, have naming conventions. Is there a way to say : do this code for panelxquestiony and specify x and y?
EDIT: A little more detail. The code is supposed to run this site (http://ticktockmaths.co.uk/ticktockquestions/index.php?id=1&sid=5 -> practise questions). The user gets some questions (from an array) and they can click to see an answer (from an array).
The user will be able to add questions to the screen (up to a maximum of about 20).
I want every question to have a on click listener. So the next question would need to have the following code.
$(document).on('click','#panel1question2',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>2. </strong>' + answerarraylvl1_js[3]);
oneone++;
console.log(oneone);}
else {
$(this).html('<strong>2. </strong>' + questionarraylvl1_js[3]);
oneone++;
console.log(oneone);
}
});
I was wondering if I could do something like
$(document).on('click','#panel1questionN',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>N. </strong>' + answerarraylvl1_js[N+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>N. </strong>' + questionarraylvl1_js[N+1]);
NN++;
console.log(NN);
}
});
for N where N is the number of questions the user has asked for
javascript jquery
I have a website that has loads of questions. When you click the question, you get the answer. My code looks a little like this:
$(document).on('click','#panel1question1',function(){
if (oneone % 2 == 0) {
$(this).html(answerarraylvl1_js[2]);
oneone++;
console.log(oneone);}
else {
$(this).html(questionarraylvl1_js[2]);
oneone++;
console.log(oneone);
}
});
The problem is that I can have upto 75 questions displayed.
I don't want to have to copy and paste a snippet for each of those div elements. It's going to generate a massive file. I also don't want to have a toggle variable for each question. I'd end up with a lot of variables.
I do however, have naming conventions. Is there a way to say : do this code for panelxquestiony and specify x and y?
EDIT: A little more detail. The code is supposed to run this site (http://ticktockmaths.co.uk/ticktockquestions/index.php?id=1&sid=5 -> practise questions). The user gets some questions (from an array) and they can click to see an answer (from an array).
The user will be able to add questions to the screen (up to a maximum of about 20).
I want every question to have a on click listener. So the next question would need to have the following code.
$(document).on('click','#panel1question2',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>2. </strong>' + answerarraylvl1_js[3]);
oneone++;
console.log(oneone);}
else {
$(this).html('<strong>2. </strong>' + questionarraylvl1_js[3]);
oneone++;
console.log(oneone);
}
});
I was wondering if I could do something like
$(document).on('click','#panel1questionN',function(){
if (oneone % 2 == 0) {
$(this).html('<strong>N. </strong>' + answerarraylvl1_js[N+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>N. </strong>' + questionarraylvl1_js[N+1]);
NN++;
console.log(NN);
}
});
for N where N is the number of questions the user has asked for
javascript jquery
javascript jquery
edited Nov 9 at 15:14
asked Nov 9 at 14:53
Richard Tock
278
278
1
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
1
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15
|
show 1 more comment
1
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
1
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15
1
1
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
1
1
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15
|
show 1 more comment
4 Answers
4
active
oldest
votes
up vote
1
down vote
accepted
While you do need to store the question's id
in the question element somehow (edit: or determine it inside the click handler), using lots of ids with running numbers is a waste.
Here's example code where the id and the current state is stored in the question element's dataset. When the questions element is clicked, a single handler function reads the state and index, changes the state, then sets the text accordingly:
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
Why$(this).data("index");
? Assigningdata
to achieve its index seems ugly solution. You can simply use$(this).index()
.
– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to usevar i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still usesoneone
as state variable for all questions.
– Chris G
Nov 9 at 15:32
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
|
show 4 more comments
up vote
0
down vote
So use data attributes to determine what is clicked. You can than use that attribute to get the number.
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
add a comment |
up vote
0
down vote
You can simply use a for loop:
for(let i=0; i<questions.length; i++){
$(this).html(questions[i]+answers[i])
}
Here, I'll suppose questions and answers are array of html elements containing questions and answers respectively.
However, we don't know if this answer will satisfy your question because of insufficient query from the post. But I hope, it will be a little help at least for you to go in advance.
As per your update, I can think that you want to achieve like this:
$(document).on('click','.panel1questionN',function(){
// giving a common class ^^ instead
var NN = $(this).index(); // if you have parent element
// var NN = $(this).index(this); // if buttons are anywhere
// but be sure this class only exists for such buttons only
if (oneone % 2 == 0) {
$(this).html('<strong>' + NN + '</strong>' + answerarraylvl1_js[NN+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>' + NN + '</strong>' + questionarraylvl1_js[NN+1]);
NN++;
console.log(NN);
}
});
But I'm still not sure if you want to achieve like this. Please let us know if you need anything further that could be a help for you.
add a comment |
up vote
-2
down vote
Make two delegate event bindings, and toggle a class to control which one executes.
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
While you do need to store the question's id
in the question element somehow (edit: or determine it inside the click handler), using lots of ids with running numbers is a waste.
Here's example code where the id and the current state is stored in the question element's dataset. When the questions element is clicked, a single handler function reads the state and index, changes the state, then sets the text accordingly:
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
Why$(this).data("index");
? Assigningdata
to achieve its index seems ugly solution. You can simply use$(this).index()
.
– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to usevar i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still usesoneone
as state variable for all questions.
– Chris G
Nov 9 at 15:32
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
|
show 4 more comments
up vote
1
down vote
accepted
While you do need to store the question's id
in the question element somehow (edit: or determine it inside the click handler), using lots of ids with running numbers is a waste.
Here's example code where the id and the current state is stored in the question element's dataset. When the questions element is clicked, a single handler function reads the state and index, changes the state, then sets the text accordingly:
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
Why$(this).data("index");
? Assigningdata
to achieve its index seems ugly solution. You can simply use$(this).index()
.
– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to usevar i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still usesoneone
as state variable for all questions.
– Chris G
Nov 9 at 15:32
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
|
show 4 more comments
up vote
1
down vote
accepted
up vote
1
down vote
accepted
While you do need to store the question's id
in the question element somehow (edit: or determine it inside the click handler), using lots of ids with running numbers is a waste.
Here's example code where the id and the current state is stored in the question element's dataset. When the questions element is clicked, a single handler function reads the state and index, changes the state, then sets the text accordingly:
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
While you do need to store the question's id
in the question element somehow (edit: or determine it inside the click handler), using lots of ids with running numbers is a waste.
Here's example code where the id and the current state is stored in the question element's dataset. When the questions element is clicked, a single handler function reads the state and index, changes the state, then sets the text accordingly:
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
const questionarraylvl1_js = ["Question 1", "Question 2", "Question 3"];
const answerarraylvl1_js = ["Answer 1", "Answer 2", "Answer 3"];
// add click handler
$(document).on("click", "#questions span", function () {
// question index
var i = $(this).data("index");
// question? (or answer?)
var is_q = $(this).data("is_q");
// change it
is_q = !is_q;
// set new text
$(this).html(is_q ? questionarraylvl1_js[i] : answerarraylvl1_js[i]).data({ is_q });
});
// build question HTML
questionarraylvl1_js.forEach((q, i) => {
// store index and id in element
var $q = $("<span>").text(q).data({ index: i, is_q: true });
$(questions).append($("<p>").append($("<strong>").text(i + 1 + ". ")).append($q));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions"></div>
edited Nov 9 at 15:30
answered Nov 9 at 15:21
Chris G
5,8822821
5,8822821
Why$(this).data("index");
? Assigningdata
to achieve its index seems ugly solution. You can simply use$(this).index()
.
– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to usevar i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still usesoneone
as state variable for all questions.
– Chris G
Nov 9 at 15:32
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
|
show 4 more comments
Why$(this).data("index");
? Assigningdata
to achieve its index seems ugly solution. You can simply use$(this).index()
.
– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to usevar i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still usesoneone
as state variable for all questions.
– Chris G
Nov 9 at 15:32
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
Why
$(this).data("index");
? Assigning data
to achieve its index seems ugly solution. You can simply use $(this).index()
.– Bhojendra Rauniyar
Nov 9 at 15:24
Why
$(this).data("index");
? Assigning data
to achieve its index seems ugly solution. You can simply use $(this).index()
.– Bhojendra Rauniyar
Nov 9 at 15:24
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
@BhojendraRauniyar You sure? Try for yourself: jsfiddle.net/khrismuc/y3fqc2u6 (In general, yes, I know, I can determine the index without storing it. But the way I'm using here will never fail, regardless of the circumstances)
– Chris G
Nov 9 at 15:29
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
Yeah, I'm pretty sure about index. But all you need is to have a parent element for this to get the correct index...
– Bhojendra Rauniyar
Nov 9 at 15:30
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to use
var i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still uses oneone
as state variable for all questions.– Chris G
Nov 9 at 15:32
@BhojendraRauniyar I know how index() works. Your first comment's suggestion doesn't work as-is though. I'd have to use
var i = $("#questions span").index(this);
Your proposed solution otoh will not work at all, because it still uses oneone
as state variable for all questions.– Chris G
Nov 9 at 15:32
1
1
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
Why are you nitpicking my working answer while yours remains unusable?
– Chris G
Nov 9 at 15:34
|
show 4 more comments
up vote
0
down vote
So use data attributes to determine what is clicked. You can than use that attribute to get the number.
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
add a comment |
up vote
0
down vote
So use data attributes to determine what is clicked. You can than use that attribute to get the number.
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
add a comment |
up vote
0
down vote
up vote
0
down vote
So use data attributes to determine what is clicked. You can than use that attribute to get the number.
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
So use data attributes to determine what is clicked. You can than use that attribute to get the number.
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
$(document).on('click','[data-num]',function (){
var button = $(this);
var num = +button.data("num")
console.log(num)
button.text(num)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-num="1">Button</button>
<button data-num="2">Button</button>
<button data-num="3">Button</button>
<button data-num="4">Button</button>
<button data-num="5">Button</button>
answered Nov 9 at 15:36
epascarello
150k13129178
150k13129178
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
add a comment |
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
Why not simply use index?
– Bhojendra Rauniyar
Nov 9 at 15:37
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
because I chose not too.... that is a personal opinion.... lol
– epascarello
Nov 9 at 15:38
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
You made my life. lol
– Bhojendra Rauniyar
Nov 9 at 15:39
add a comment |
up vote
0
down vote
You can simply use a for loop:
for(let i=0; i<questions.length; i++){
$(this).html(questions[i]+answers[i])
}
Here, I'll suppose questions and answers are array of html elements containing questions and answers respectively.
However, we don't know if this answer will satisfy your question because of insufficient query from the post. But I hope, it will be a little help at least for you to go in advance.
As per your update, I can think that you want to achieve like this:
$(document).on('click','.panel1questionN',function(){
// giving a common class ^^ instead
var NN = $(this).index(); // if you have parent element
// var NN = $(this).index(this); // if buttons are anywhere
// but be sure this class only exists for such buttons only
if (oneone % 2 == 0) {
$(this).html('<strong>' + NN + '</strong>' + answerarraylvl1_js[NN+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>' + NN + '</strong>' + questionarraylvl1_js[NN+1]);
NN++;
console.log(NN);
}
});
But I'm still not sure if you want to achieve like this. Please let us know if you need anything further that could be a help for you.
add a comment |
up vote
0
down vote
You can simply use a for loop:
for(let i=0; i<questions.length; i++){
$(this).html(questions[i]+answers[i])
}
Here, I'll suppose questions and answers are array of html elements containing questions and answers respectively.
However, we don't know if this answer will satisfy your question because of insufficient query from the post. But I hope, it will be a little help at least for you to go in advance.
As per your update, I can think that you want to achieve like this:
$(document).on('click','.panel1questionN',function(){
// giving a common class ^^ instead
var NN = $(this).index(); // if you have parent element
// var NN = $(this).index(this); // if buttons are anywhere
// but be sure this class only exists for such buttons only
if (oneone % 2 == 0) {
$(this).html('<strong>' + NN + '</strong>' + answerarraylvl1_js[NN+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>' + NN + '</strong>' + questionarraylvl1_js[NN+1]);
NN++;
console.log(NN);
}
});
But I'm still not sure if you want to achieve like this. Please let us know if you need anything further that could be a help for you.
add a comment |
up vote
0
down vote
up vote
0
down vote
You can simply use a for loop:
for(let i=0; i<questions.length; i++){
$(this).html(questions[i]+answers[i])
}
Here, I'll suppose questions and answers are array of html elements containing questions and answers respectively.
However, we don't know if this answer will satisfy your question because of insufficient query from the post. But I hope, it will be a little help at least for you to go in advance.
As per your update, I can think that you want to achieve like this:
$(document).on('click','.panel1questionN',function(){
// giving a common class ^^ instead
var NN = $(this).index(); // if you have parent element
// var NN = $(this).index(this); // if buttons are anywhere
// but be sure this class only exists for such buttons only
if (oneone % 2 == 0) {
$(this).html('<strong>' + NN + '</strong>' + answerarraylvl1_js[NN+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>' + NN + '</strong>' + questionarraylvl1_js[NN+1]);
NN++;
console.log(NN);
}
});
But I'm still not sure if you want to achieve like this. Please let us know if you need anything further that could be a help for you.
You can simply use a for loop:
for(let i=0; i<questions.length; i++){
$(this).html(questions[i]+answers[i])
}
Here, I'll suppose questions and answers are array of html elements containing questions and answers respectively.
However, we don't know if this answer will satisfy your question because of insufficient query from the post. But I hope, it will be a little help at least for you to go in advance.
As per your update, I can think that you want to achieve like this:
$(document).on('click','.panel1questionN',function(){
// giving a common class ^^ instead
var NN = $(this).index(); // if you have parent element
// var NN = $(this).index(this); // if buttons are anywhere
// but be sure this class only exists for such buttons only
if (oneone % 2 == 0) {
$(this).html('<strong>' + NN + '</strong>' + answerarraylvl1_js[NN+1]);
NN++;
console.log(NN);}
else {
$(this).html('<strong>' + NN + '</strong>' + questionarraylvl1_js[NN+1]);
NN++;
console.log(NN);
}
});
But I'm still not sure if you want to achieve like this. Please let us know if you need anything further that could be a help for you.
edited Nov 9 at 15:43
answered Nov 9 at 15:01
Bhojendra Rauniyar
49.6k1977120
49.6k1977120
add a comment |
add a comment |
up vote
-2
down vote
Make two delegate event bindings, and toggle a class to control which one executes.
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
add a comment |
up vote
-2
down vote
Make two delegate event bindings, and toggle a class to control which one executes.
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
add a comment |
up vote
-2
down vote
up vote
-2
down vote
Make two delegate event bindings, and toggle a class to control which one executes.
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
Make two delegate event bindings, and toggle a class to control which one executes.
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
$(document).on('click','#panel1question1:not(.answer)',function(){
$(this).addClass('answer').html(answerarraylvl1_js[2]);
});
$(document).on('click','#panel1question1.answer',function(){
$(this).removeClass('answer').html(questionarraylvl1_js[2]);
});
answered Nov 9 at 14:59
Taplar
14.8k21529
14.8k21529
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
add a comment |
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
1
1
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
This answer completely ignores the question's main issue: having to write 75 event handlers. You are basically telling him to write 150 instead.
– Chris G
Nov 9 at 15:06
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
I didn't tell him that at all. All he needs is these two handlers. If you're referring to his use of an id, all he has to do is use a common class rather than that id and all he needs is the two handlers. The point of the answer was to demonstrate the use of delegates, paired with a toggled class, vs a variable. @ChrisG
– Taplar
Nov 9 at 15:39
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228086%2favoiding-repetitive-onclick-statements%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Can you show a second copy of the listener so we can see what things change and what things are the same?
– Nicholas Tower
Nov 9 at 14:56
This should be very simple using one click event listener and indexing the question elements or using data attributes. Please provide a Minimal, Complete, and Verifiable example
– charlietfl
Nov 9 at 14:58
1
This is known as the DRY principle and is a core concept of programming. The entire point of using functions in the first place is to avoid repetitive code. You also don't need tons of ids with a number in them, that's what classes and selectors are for. Please add a Minimal, Complete, and Verifiable example to your question that shows two questions and their answers.
– Chris G
Nov 9 at 14:58
Without knowing what your code is supposed to do we can't really give you an example, however it sounds like you need to use the 'answer' arrays more effectively by joining them in to a single data structure, such as an object, and then keying that by the question id. Also, if this is supposed to have any level of security I'd suggest not putting the answers client-side as it would be trivial to bypass. Put all the question/answer and verification logic on the server instead.
– Rory McCrossan
Nov 9 at 15:08
hi guys. thanks for taking the time to respond. i have added an edit to my original post. hopefully it clears up what i am trying to say
– Richard Tock
Nov 9 at 15:15