btnA.addEventListener('click', function() {
console.log("Answer choice: A")
answerSelected = choiceA.textContent;
checkAnswer(answerSelected);
})
btnB.addEventListener('click', function() {
console.log("Answer choice: B")
answerSelected = choiceB.textContent;
checkAnswer(answerSelected);
})
btnC.addEventListener('click', function() {
console.log("Answer choice: C")
answerSelected = choiceC.textContent;
checkAnswer(answerSelected);
})
btnD.addEventListener('click', function() {
console.log("Answer choice: D")
answerSelected = choiceD.textContent;
checkAnswer(answerSelected);
})
how would i condense this so that its only one "function"? still new to javascript
https://github.com/rahimh5/Zuhair-Problem
as per #Teemu's suggestion, you can use event delegation. when the parent element is click, find its target
document.getElementById("choices").addEventListener("click", function (e) {
if (e.target && e.target.nodeName == "BUTTON") {
console.log(e.target.innerHTML)
}
});
<div id="choices" class="choices">
<button name="btnA">A</button>
<button name="btnB">B</button>
<button name="btnC">C</button>
<button name="btnD">D</button>
</div>
Here is a rewrite of your complete quiz app.
As suggested in the comments I used event delegation for the click event (answers.onclick=ev=>{ ... })
const questions = [{id: 0,question: "6 x 6",ans: "36",A: "48",B: "36",C: "38",D: "26"},{id: 1,question: "3 x 8",ans: "24",A: "28",B: "26",C: "22",D: "24"},{id: 2,question: "4 x 12",ans: "48",A: "60",B: "52",C: "48",D: "36"},{id: 3,question: "1 x 3",ans: "3",A: "5",B: "1",C: "4",D: "3"},{id: 4,question: "6 x 3",ans: "18",A: "18",B: "17",C: "19",D: "16"}],
[qdiv,btnnext,chk]=["question","next-question-btn","checker"].map(id=>document.getElementById(id)),
answers=document.querySelector(".answer-choices"), btns=[...answers.children];
var id=0, Q; // global variables ...
btnnext.onclick=nextQ;
answers.onclick=ev=>{ // delegate click event handler for answer buttons:
if (ev.target.textContent==Q.ans) {
chk.textContent=`Correct - ${Q.question} = ${Q.ans}!`;
btnnext.style.display=""
}
else chk.textContent="Not quite - try again!";
}
function nextQ(){
Q=questions[id];
chk.textContent="";
btnnext.style.display="none";
if (id++<questions.length){ // prepare next question
qdiv.textContent=`What is ${Q.question}?`;
[Q.A,Q.B,Q.C,Q.D].forEach((ans,i)=> btns[i].textContent=ans)
}
else { // wrap up the game:
qdiv.textContent="Game over - thanks for playing!";
answers.textContent=""
}
}
nextQ(); // show initial question
<section class="container">
<div class="title">
<h2>Multiplication Quiz 2022</h2>
<div class="underline"></div>
</div>
</section>
<section class="quiz">
<h3 id="question">Question</h3>
<div class="question"></div>
<div class="answer-choices">
<button id="choice-A" class="btn A">A</button>
<button id="choice-B" class="btn B">B</button>
<button id="choice-C" class="btn C">C</button>
<button id="choice-D" class="btn D">D</button>
</div>
<div class="checker">
<h3 id="checker"></h3>
<button id="next-question-btn" class="btn nextQuestion" style="display: none;">Next Question</button>
</div>
</section>
There are many ways of doing this - and I have played around with several of them until I ended up with the above version.
Related
I'm trying to create a chain of buttons:
First options;
- Button 1
- Button 2
IF chosen Button 1:
- Button 1a
- Button 1b
IF chosen Button 1a:
- Button 1aa
- Button 1ab
IF chosen Button 1b:
- Button 1ba
- Button 1bb
And so on.. same goes for Button 2.
Thus far I got this but my .js is not working out for me.
I tried it in two ways.
WAY 1:
HTML (onclick="nextPush" is going to change in way 2)
<div class="buttons1-2">
<button id="btn1" class="btn btn1" onclick="buttonPushed(this)">Button 1</button>
<button id="btn2" class="btn btn2" onclick="buttonPushed(this)">Button 2</button>
</div>
<div class="buttons1a-b">
<button id="btn1a" class="btn btn1a" onclick="nextPush(this)">Button 1a</button>
<button id="btn1b" class="btn btn1b" onclick="nextPush(this)">Button 1b</button>
</div>
<div class="buttons2a-b">
<button id="btn2a" class="btn btn2a">Button 2a</button>
<button id="btn2b" class="btn btn2b">Button 2b</button>
</div>
<div class="buttons1aa-ab">
<button id="btn1aa" class="btn btn1a">Button 1aa</button>
<button id="btn1ab" class="btn btn1b">Button 1ab</button>
</div>
<div class="buttons1ba-bb">
<button id="btn1ba" class="btn btn2a">Button 1ba</button>
<button id="btn1bb" class="btn btn2b">Button 1bb</button>
</div>
WAY 1: .JS
function buttonPushed(btn) {
var replacewith = "buttons1a-b";
if (btn.id == "btn2") {
replacewith = "buttons2a-b";
}
function nextPush(btn) {
var replacewith = "buttons1aa-ab";
if (btn.id == "btn1b") {
replacewith = "buttons1ba-bb";
}
var allChildren = document.getElementsByClassName('buttons')[0].children;
for (var i = 0; i < allChildren.length; i++) {
var child = allChildren[i];
if (child.className != replacewith) {
child.style.display = "none";
} else {
child.style.display = "inline";
}
}
}
WAY 2: HTML (notice the onclick="nextPush" is gone)
<div class="buttons1-2">
<button id="btn1" class="btn btn1" onclick="buttonPushed(this)">Button 1</button>
<button id="btn2" class="btn btn2" onclick="buttonPushed(this)">Button 2</button>
</div>
<div class="buttons1a-b">
<button id="btn1a" class="btn btn1a" onclick="buttonPushed(this)">Button 1a</button>
<button id="btn1b" class="btn btn1b" onclick="buttonPushed(this)">Button 1b</button>
</div>
<div class="buttons2a-b">
<button id="btn2a" class="btn btn2a">Button 2a</button>
<button id="btn2b" class="btn btn2b">Button 2b</button>
</div>
<div class="buttons1aa-ab">
<button id="btn1aa" class="btn btn1a">Button 1aa</button>
<button id="btn1ab" class="btn btn1b">Button 1ab</button>
</div>
<div class="buttons1ba-bb">
<button id="btn1ba" class="btn btn2a">Button 1ba</button>
<button id="btn1bb" class="btn btn2b">Button 1bb</button>
</div>
WAY 2 .JS
function buttonPushed(btn) {
/* btn = Id: btn1, btn2, btn1a or btn1b */
let replacewith = "buttons1a-b";
if (btn.id == "btn2") {
replacewith = "buttons2a-b";
}
else if (btn.id == "btn1a") {
replacewith = "buttons1aa-ab";
}
else if (btn.id == "btn1b") {
replacewith = "buttons1ba-bb";
}
}
let allChildren = document.getElementsByClassName('buttons')[0].children;
for (let i = 0; i < allChildren.length; i++) {
let child = allChildren[i];
if (child.className != replacewith) {
child.style.display = "none";
} else {
child.style.display = "inline";
}
}
.CSS for BOTH WAYS:
.buttons1a-b {
display: none;
}
.buttons2a-b {
display: none;
}
.buttons1aa-ab {
display: none;
}
.buttons1ba-bb {
display: none;
}
Sorry for the long post, hope you can help me out :) If you know a better way to do this, please also do let me know.
Building on your example, and the one from Michael, you could also use another approach of declaring what div you want displayed by attaching an attribute to the button, and then add an event listener to all buttons with that attribute. This makes the HTML slightly smaller and more declarative, and makes it easier to switch what element you want to display next instead of relying on a particular schema of id's.
(function(document) {
// get all buttons that have the attribute data-next
const buttons = document.querySelectorAll('[data-next]');
for (const item of buttons) {
// get references to the parent item and next item to hide/show
const parentId = item.getAttribute('data-parent');
const parent = document.querySelector(`#${parentId}`);
const nextDivId = item.getAttribute('data-next');
const nextDiv = document.querySelector(`#${nextDivId}`);
if (!nextDiv) {
console.error('could not find next div for button ', item);
}
// attach an event listener for click that toggles visibility of the above elements
item.addEventListener('click', function() {
nextDiv.classList.toggle('hidden');
parent.classList.toggle('hidden');
});
}
})(document);
.hidden {
display: none;
}
<div id="base">
<button data-next="option-a" data-parent="base">Option A</button>
<button data-next="option-b" data-parent="base">Option B</button>
</div>
<div id="option-a" class="hidden">
<p>Option A</p>
</div>
<div id="option-b" class="hidden">
<p>Option B</p>
</div>
If you want to add new buttons dynamically (or change what your next items should be) you will need to attach the event listener when you create your other buttons. For instance, you can do something like the following:
(function(document) {
function onButtonClicked(event) {
const item = event.target;
// get references to the next item to show
const nextDivId = item.getAttribute('data-next');
const nextDiv = document.querySelector(`#${nextDivId}`);
if (!nextDiv) {
console.error('could not find next div for button ', item);
}
// The function toggle on classList either removes a class if it exists
// or adds it if it does not exist in the list of classes on the element
nextDiv.classList.toggle('hidden');
// check if container has an attribute for loading next buttons lazily
const lazyLoadLevel = nextDiv.getAttribute('data-level');
// if we found the attribute, load the contents
if (lazyLoadLevel) {
// cast lazyLoadedLevel to an integer (with +) since getAttribute returns a string
loadLevel(+lazyLoadLevel, nextDiv);
// since we have populated the container we can remove the attribute so that elements do not get added again
nextDiv.removeAttribute('data-level');
}
// get references to the parent item to hide
const parentId = item.getAttribute('data-parent');
const parent = document.querySelector(`#${parentId}`);
if (parent) {
parent.classList.toggle('hidden');
}
}
function addButton(parent, nextElementId, text) {
const newItem = document.createElement('button');
newItem.setAttribute('data-next', nextElementId);
newItem.setAttribute('data-parent', parent.getAttribute('id'));
newItem.textContent = text;
newItem.addEventListener('click', onButtonClicked);
parent.appendChild(newItem);
}
function loadLevel(level, container) {
switch (level) {
// depending on level you can define other buttons to add here
case 2:
{
addButton(container, 'option-a', 'Goto option a');
break;
}
}
}
// get all *existing* buttons that have the attribute data-next
// this is run once when the script loads, and will not attach listeners to dynamically created buttons
const buttons = document.querySelectorAll('[data-next]');
for (const item of buttons) {
// attach an event listener for click that toggles visibility of parent and next elements
// notice that we pass a reference to onButtonClicked. Even though it is a function we shouldn't call it *here*
item.addEventListener('click', onButtonClicked);
}
})(document);
.hidden {
display: none;
}
<div id="base">
<button data-next="option-a" data-parent="base">Option A</button>
<button data-next="option-b" data-parent="base">Option B</button>
</div>
<div id="option-a" class="hidden">
<p>Option A</p>
<button data-next="option-b" data-parent="option-a">Option B</button>
</div>
<div id="option-b" class="hidden" data-level="2">
<p>Option B. The contents of this div is loaded lazily based on the value of the attribute data-level</p>
</div>
At first, I was thinking this should be done entirely dynamically -- where the next container of buttons is created and inserted into the DOM when the button is clicked. But judging by your current attempts, it seems like you want to have all the buttons hardcoded into the source, hidden with CSS, and shown with DOM during the click event. Here is one way you can achieve that:
function handleButtonClick(button) {
const clickedID = button.id.substring(3);
const nextDiv = document.getElementById("buttons" + clickedID);
if (nextDiv) {
nextDiv.style.display = "block";
}
}
.hidden {
display: none;
}
<div id="buttons">
<button id="btn1" onclick="handleButtonClick(this)">Button 1</button>
<button id="btn2" onclick="handleButtonClick(this)">Button 2</button>
</div>
<div id="buttons1" class="hidden">
<button id="btn1a" onclick="handleButtonClick(this)">Button 1a</button>
<button id="btn1b" onclick="handleButtonClick(this)">Button 1b</button>
</div>
<div id="buttons2" class="hidden">
<button id="btn2a" onclick="handleButtonClick(this)">Button 2a</button>
<button id="btn2b" onclick="handleButtonClick(this)">Button 2b</button>
</div>
<div id="buttons1a" class="hidden">
<button id="btn1aa" onclick="handleButtonClick(this)">Button 1aa</button>
<button id="btn1ab" onclick="handleButtonClick(this)">Button 1ab</button>
</div>
<div id="buttons1b" class="hidden">
<button id="btn1ba" onclick="handleButtonClick(this)">Button 1ba</button>
<button id="btn1bb" onclick="handleButtonClick(this)">Button 1bb</button>
</div>
<div id="buttons2a" class="hidden">
<button id="btn2aa" onclick="handleButtonClick(this)">Button 2aa</button>
<button id="btn2ab" onclick="handleButtonClick(this)">Button 2ab</button>
</div>
<div id="buttons2b" class="hidden">
<button id="btn2ba" onclick="handleButtonClick(this)">Button 2ba</button>
<button id="btn2bb" onclick="handleButtonClick(this)">Button 21bb</button>
</div>
This just identifies which button was clicked, and uses that information to determine the next div to show, until there are no more divs that correspond to the one that was clicked.
I have a grid of 4 buttons and once one of them is clicked it will call a function called doSearch which checks which button was clicked and based on that assigns a string to the last_search value.
However, when I click any of the four buttons, I always seem to only press the edm button and reads 'i am edm' to console.
Could anyone explain why that is?
html
<!-- grid for music -->
<ng-container *ngIf="show" >
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="edm-btn" type="submit" (click)="doSearch($event)">EDM</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="house-btn" type="submit" (click)="doSearch($event)">House</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="pop-btn" type="submit" (click)="doSearch($event)">Pop</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="dubstep-btn" type="submit" (click)="doSearch($event)">Dubstep</button>
</div>
</div>
</ng-container>
function code
doSearch(event): void {
if (document.getElementById('edm-btn')) {
this.last_search = 'edm';
console.log('i am edm');
} else if (document.getElementById('house-btn')) {
this.last_search = 'house';
console.log('i am house');
} else if (document.getElementById('pop-btn')) {
this.last_search = 'pop';
console.log('i am pop');
} else if (document.getElementById('dubstep-btn')) {
this.last_search = 'dubstep';
console.log('i am dubstep');
}
}
FIX:
instead of passing the id of the button, I decided to pass a string directly into the function call of doSearch
html
<!-- grid for music -->
<ng-container *ngIf="show" >
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="edm-btn" type="submit" (click)="doSearch('edm')">EDM</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="house-btn" type="submit" (click)="doSearch('house')">House</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="pop-btn" type="submit" (click)="doSearch('pop')">Pop</button>
</div>
<div class="mdl-cell mdl-cell--1-col">
<button mat-button id="dubstep-btn" type="submit" (click)="doSearch('dubstep')">Dubstep</button>
</div>
</div>
</ng-container>
function
doSearch(category): void {
console.log(JSON.stringify(category, null, 2));
if (category === 'edm') {
this.last_search = 'edm';
console.log('i am edm');
} else if (category === 'house') {
this.last_search = 'house';
console.log('i am house');
} else if (category === 'pop') {
this.last_search = 'pop';
console.log('i am pop');
} else if (category === 'dubstep') {
this.last_search = 'dubstep';
console.log('i am dubstep');
}
}
It's because no matter what event you pass, your 1st condition is always true. You are passing an event, not the actual data, as well as checking if an element exists even if it already is.
You actually don't need here if and else, it's enough:
public doSearch(category: string) {
this.last_search = category;
}
I'm a beginner to JavaScript. The lines of code that I've written in JavaScript are working for individual actions that happens in the HTML part but I want to make it as a single function which can handle all the cases actions that happens in the HTML part.
How to make one JavaScript function which can be used for different separate actions which has similar lines of code but different HTML classes?
HTML -
<div class="first" class="row">
<div>
<div class="first1">
<img class="first_img" src="assets/imgs/01.png"/>
</div>
<div class="first2">
<h4 class="first_title"><b> life... </b></h4>
<p class="first_content"> thinking, feelings, emotions, meanings, and values. </p>
<button class="btn"> <img src="assets/imgs/Icons-06.png"> </button>
<button class="btn_replace"> <img src="assets/imgs/Icons-07.png"> </button>
</div>
</div>
</div>
<div class="second" class="row">
<div class="second1">
<div class="second2">
<div class="second_title">
<h5><b> questions... </b></h5>
</div>
<div class="second_content" style="">
<div>
<p> Human thinking involves asking questions and getting answers.
</p>
</div>
<button class="second-btn" style=""> <img src="assets/imgs/Icons-06.png"> </button>
<button class="secondbtn_replace"> <img src="assets/imgs/Icons-07.png"> </button>
</div>
</div>
</div>
<div>
<img class="second_img" src="assets/imgs/02.png" style="" />
</div>
</div>
Javascript -
$(document).ready(function () {
$('.firstsub').hide();
$('.second-sub').hide();
$('.firstbtn').click (function (event)
{
$('.firstsub').toggle('show');
});
// if (javascript(window).width() > 500) {
$('.second-btn').click (function (event)
{
$('.second-sub').toggle('show');
});
});
$(document).ready(function () {
$('.firstbtn_replace').hide();
$('.secondbtn_replace').hide();
$('.firstbtn').click (function (event)
{
$('.firstbtn').addClass('hide');
$('.firstbtn_replace').show();
});
$('.firstbtn_replace').click (function (event)
{
$('.firstsub').toggle('show');
$('.firstbtn').removeClass('hide');
$('.firstbtn_replace').hide();
});
// if (javascript(window).width() > 500) {
$('.second-btn').click (function (event)
{
$('.second-btn').addClass('hide');
$('.secondbtn_replace').show();
});
$('.secondbtn_replace').click (function (event)
{
$('.second-sub').toggle('show');
$('.second-btn').removeClass('hide');
$('.secondbtn_replace').hide();
});
});
First off, You have to clean up your code. Everything there can be written in one $(document).ready()
$(document).ready(function () {
$('.firstsub').hide();
$('.second-sub').hide();
$('.firstbtn_replace').hide();
$('.secondbtn_replace').hide();
$('.firstbtn').click (function (event) {
$('.firstsub').toggle('show');
$('.firstbtn').addClass('hide');
$('.firstbtn_replace').show();
});
$('.firstbtn_replace').click (function (event) {
$('.firstsub').toggle('show');
$('.firstbtn').removeClass('hide');
$('.firstbtn_replace').hide();
});
// if (javascript(window).width() > 500) {
$('.second-btn').click (function (event) {
$('.second-sub').toggle('show');
$('.second-btn').addClass('hide');
$('.secondbtn_replace').show();
});
$('.secondbtn_replace').click (function (event) {
$('.second-sub').toggle('show');
$('.second-btn').removeClass('hide');
$('.secondbtn_replace').hide();
});
});
Second, You can pass parameters to functions that happen often. For example
function hideClasses(classes) {
for(var i = 0; i < classes.length; i++ ) {
$(classes[i]).hide();
}
}
Call it like this, passing in the classes to be hidden as an array.
hideClasses(['.firstsub', '.second-sub']);
or take for example the click action of each button.
function buttonClicked(class) {
$(class).toggle('show');
$(class).removeClass('hide');
$(class).hide();
}
So your $('.firstbtn_replace').click() can be this
$('.firstbtn_replace').click (function (event) {
buttonClicked('.firstbtn_replace');
});
The same goes for $('.secondbtn_replace').click()
$('.secondbtn_replace').click (function (event) {
buttonClicked('.firstbtn_replace');
});
You can do the same for $('.firstbtn').click() and $('.secondbtn').click()
The ending result will be
$(document.ready(function() {
function hideClasses(classes) {
for(var i = 0; i < classes.length; i++ ) {
$(classes[i]).hide();
}
}
function replaceButtonClicked(className) {
$(className).toggle('show');
$(className).removeClass('hide');
$(className).hide();
}
function normalButtonClicked(className) {
$(className).toggle('show');
$(className).addClass('hide');
$(className).hide();
}
hideClasses(['.firstsub', '.second-sub', '.firstbtn_replace', '.secondbtn_replace']);
$('.firstbtn').click (function (event) {
normalButtonClicked('.firstbtn');
}
$('.secondbtn').click (function (event) {
normalButtonClicked('.secondbtn');
}
$('.firstbtn_replace').click (function (event) {
normalButtonClicked('.firstbtn_replace');
}
$('.secondbtn_replace').click (function (event) {
replaceButtonClicked('.secondbtn_replace');
}
});
Or instead of writing the classes each time you can the function, you can pass in the jQuery object itself.
Ending in this as a final result.
$(document.ready(function() {
function hideClasses(classes) {
for(var i = 0; i < classes.length; i++ ) {
$(classes[i]).hide();
}
}
// obj refers to the jQuery object the clicked was called on
function replaceButtonClicked(obj) {
obj.toggle('show');
obj.removeClass('hide');
obj.hide();
}
// obj refers to the jQuery object the clicked was called on
function normalButtonClicked(class) {
obj.toggle('show');
obj.addClass('hide');
obj.hide();
}
hideClasses(['.firstsub', '.second-sub', '.firstbtn_replace', '.secondbtn_replace']);
// this refers to the jQuery object the clicked was called on
$('.firstbtn').click (function (event) {
normalButtonClicked(this);
}
// this refers to the jQuery object the clicked was called on
$('.secondbtn').click (function (event) {
normalButtonClicked(this);
}
// this refers to the jQuery object the clicked was called on
$('.firstbtn_replace').click (function (event) {
normalButtonClicked(this);
}
// this refers to the jQuery object the clicked was called on
$('.secondbtn_replace').click (function (event) {
replaceButtonClicked(this);
}
});
You could do something similar to below. the event parameter that gets passed with a click event has a plethora of information. Use it and a switch statement to determine what you want to do.
$(document).ready(function() {
$('.firstsub').hide();
$('.second-sub').hide();
$('.firstbtn').click(clickHandler(event));
$('.second-btn').click(clickHandler(event));
});
function clickHandler(event){
//event param will have all the details about who and what was clicked
switch(/*event or something in event*/){ //switch over details of the event and manage them all here
}
}
<div class="first" class="row">
<div>
<div class="first1">
<img class="first_img" src="assets/imgs/01.png"/>
</div>
<div class="first2">
<h4 class="first_title"><b> life... </b></h4>
<p class="first_content"> thinking, feelings, emotions, meanings, and values. </p>
<button class="btn"> <img src="assets/imgs/Icons-06.png"> </button>
<button class="btn_replace"> <img src="assets/imgs/Icons-07.png"> </button>
</div>
</div>
</div>
<div class="second" class="row">
<div class="second1">
<div class="second2">
<div class="second_title">
<h5><b> questions... </b></h5>
</div>
<div class="second_content" style="">
<div>
<p> Human thinking involves asking questions and getting answers.
</p>
</div>
<button class="second-btn" style=""> <img src="assets/imgs/Icons-06.png"> </button>
<button class="secondbtn_replace"> <img src="assets/imgs/Icons-07.png"> </button>
</div>
</div>
</div>
<div>
<img class="second_img" src="assets/imgs/02.png" style="" />
</div>
</div>
I have got following code (i shorted it to make it more readable)
And I would like to ask if it is possible to do not write almost the same code for every button? How can I do it the easiest way? I have got 6 buttons and code would be quite long.
<script>
$(document).ready(function(){
$("#option1").click(function(){
if($(".option1").is(":visible")){
$(".option1").hide("slow",function(){});
}
else{
$(".option2, .option3").hide("slow",function(){});
$(".option1").show("slow",function(){});
}
});
$("#option2").click(function(){
if($(".option2").is(":visible")){
$(".option2").hide("slow",function(){});
}
else{
$(".option1, .option3").hide("slow",function(){});
$(".option2").show("slow",function(){});
}
});
$("#option3").click(function(){
if($(".option3").is(":visible")){
$(".option3").hide("slow",function(){});
}
else{
$(".option1, .option2").hide("slow",function(){});
$(".option3").show("slow",function(){});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
</body>
Without the need to change much of your html, add a common class option to all your option1, option2, ... :
<div class ="option option1">a</div>
<div class ="option option2">b</div>
<div class ="option option3">c</div>
and then you can use this below:
Array.from(document.getElementsByTagName('button')).forEach(function(btn){
btn.addEventListener('click', function(e){
if($("." + e.target.id).is(":visible")){
$("." + e.target.id).hide("slow",function(){});
}
else{
$(".option").hide("slow",function(){});
$("." + e.target.id).show("slow",function(){});
}
});
});
DEMO
You can reduce the code to just one click listener. Try this:
<script>
$(document).ready(function() {
$(".btn-primary").click(function() {
var option = $(this).data("option");
if ($(".option." + option).is(":visible")) {
$(".option." + option).hide("slow", function() {});
} else {
$(".option").not("." + option).hide("slow", function() {});
$(".option." + option).show("slow", function() {});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" data-option="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" data-option="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" data-option="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
<!-- common class option added -->
<div class="options">
<div class="option option1"></div>
<div class="option option2"></div>
<div class="option option3"></div>
</div>
</body>
I added a common class to all the options, and a data-option attribute to your buttons.
You don't need to check to see whether the current button is visible. It's visible because it was just clicked on.
All you need to do is show the other buttons that weren't clicked on and hide the one that was. To do this, assign the same class to all 3 buttons. In the example below, I added the class "myBtn" to all 3 buttons.
$(".myBtn").click(function () {
var id = $(this).attr('id');
$(".myBtn:not(#"+id+")").show("slow", function () {});
$(this).hide();
});
JSFiddle demo.
I've be looking for how to execute this but I can't find anything related so far, :(
I could nest both functions yes but I'm just wondering if this is possible?
I'd like to do this literally:
<td><button class="btn" ng-click="edit($index) open()">Open me!</button></td>
My JS code at the moment:
$scope.open = function () {
$scope.shouldBeOpen = true;
};
$scope.edit = function(index){
var content_1, content_2;
content_1 = $scope.people[index].name;
content_2 = $scope.people[index].age;
console.log(content_1);
};
I'd like to call two functions with just one click, how can I do this in angularJS?
I thought it'd be straight forward like in CSS when you add multiple classes...but it's not :(
You have 2 options :
Create a third method that wrap both methods. Advantage here is that you put less logic in your template.
Otherwise if you want to add 2 calls in ng-click you can add ';' after edit($index) like this
ng-click="edit($index); open()"
See here : http://jsfiddle.net/laguiz/ehTy6/
You can call multiple functions with ';'
ng-click="edit($index); open()"
A lot of people use (click) option so I will share this too.
<button (click)="function1()" (click)="function2()">Button</button>
The standard way to add Multiple functions
<button (click)="removeAt(element.bookId); openDeleteDialog()"> Click Here</button>
or
<button (click)="removeAt(element.bookId)" (click)="openDeleteDialog()"> Click Here</button>
Try this:
Make a collection of functions
Make a function that loops through and executes all the functions in the collection.
Add the function to the html
array = [
function() {},
function() {},
function() {}
]
function loop() {
array.forEach(item) {
item()
}
}
ng - click = "loop()"
Follow the below
ng-click="anyFunction()"
anyFunction() {
// call another function here
anotherFunction();
}
<!-- Button trigger modal -->
<button type="button" (click)="open(content)" style="position: fixed; bottom: 0; right: 130px;"
class="btn col-sm-1 btn-Danger" >
Reject
</button>
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Profile update</h4>
<button type="button" class="btn-close" aria-label="Close" (click)="modal.dismiss('Cross click')"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="bg-danger text-light" for="Reject">Reason For reject</label>
<textarea matInput placeholder=" Reject" [(ngModel)]="asset_note">{{note}}</textarea>
</div>
</div>
<div class="modal-footer">
<!-- -->
<button type="button" class="btn btn-outline-dark" (click)="reject();modal.close('Save click') ">Save</button>
</div>
</ng-template>
**.ts file**
open(content: any) {
this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
close()
{
this.getDismissReason(ModalDismissReasons.ESC);
}
Which of the following is best practice (option1 or option2)
<button (click)="removeAt(element.bookId); openDeleteDialog()"> Click Here
<button (click)="removeAt(element.bookId)" (click)="openDeleteDialog()"> Click Here
ng-click "$watch(edit($index), open())"