How to add many functions in ONE ng-click? - javascript

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())"

Related

anyway to condense this? trying to make a multiple choice questions

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.

How to change click event of button according to different situations on Angular 9

I use Angular 9 to develop a web application. So I need to use Bootstrap Modals
like as
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{MODAL_TITLE}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>{{MODAL_BODY}}</p>
</div>
<div class="modal-footer">
<button type="button" (click)="function_1()" class="btn btn-primary">SUBMIT</button>
</div>
</div>
</div>
</div>
I called a function when I clicked the Submit button. Well, I just want to change the function that submit function called in different cases.
So the thing that I just want to do in ts file:
MODAL_BODY = "BODY STRING";
MODAL_TITLE: FUNCTION ;
modal.show();
function1(){
console.log("function 1 works"}
}
function2(){
console.log("function 2 works")
}
I want to use function2() instead of function1() sometimes.
Then I want to change function that submit button called in different situations just like as:
<button type="button" (click)="function_1()" class="btn btn-primary">SUBMIT</button>
//some times i need to use this button below. so I need to change it from ts file
<button type="button" (click)="function_2()" class="btn btn-primary">SUBMIT</button>
Is there anyway to do that? from ts file or dynamically?
Thanks in advance.
If we want to change dynamically the button itself in the template the *ngIf structural directive can be used. (As chrnx writes in the question comment.)
To have an example for this take a look at the example below.
In Angular template code:
<p>
Used button
<br />
<button *ngIf="displayedButton === 1" (click)="onButtonOneClick()">
ButtonOne
</button>
<button *ngIf="displayedButton === 2" (click)="onButtonTwoClick()">
ButtonTwo
</button>
</p>
<p>
Change button state
<br />
<button (click)="onChangeStateClick()">Change</button>
</p>
In component code:
import { Component } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
displayedButton = 1;
onButtonOneClick() {
console.log("Button 1 click");
}
onButtonTwoClick() {
console.log("Button 2 click");
}
onChangeStateClick() {
this.displayedButton = this.displayedButton === 1 ? 2 : 1;
}
}
Stackblitz example:
https://stackblitz.com/edit/angular-ivy-irmbkk?file=src/app/app.component.ts

Javascript/Angular 5 - clicking multiple buttons only affects one

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;
}

How a modal see the row's index Reactjs

I'm having difficulty on passing the index from button to button so here is my code. Tthe first one is the render loop that shows all my rows and its button the button at the delete part is calling the index from the row.
renderItem(d, i) {
return <tr key={i} >
<td> {d.Employee_ID} </td>
<td>{d.Employee_Name}</td>
<td>{d.Address }</td>
<td><center><button className ="btn btn-info" onClick={this.handleOnclick.bind(this, d.Employee_ID, d.Employee_Name, d.Address , d.Department)} data-toggle="modal" data-target="#UpdateEmployee">Edit</button></center></td>
// this part is calling button is calling the {i} or what we call the index
<td><center><button className ='btn btn-danger' onClick={this.handleOnclick.bind(this, d.Employee_ID , d.Employee_Name,i)} data-toggle="modal" data-target="#DeleteEmployee"> Delete</button></center></td>
</tr>
}
this is where it proceed to my modal
{/*Delete*/}
<div className="modal fade" id="DeleteEmployee" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Delete Employee</h4>
</div>
<div className="container">
<div className="modal-body">
Are you sure you want to delete {this.state.Employee_Name}?
</div>
</div>
<div className="modal-footer">
// I tried calling the index here but the modal can't see my index
<input type="submit" className ="btn btn-danger" data-dismiss="modal" onClick={this.deleteEmployee.bind(this, this.state.Employee_ID ,this.state.i)}/>
<button type="button" className="btn btn-default" data-dismiss="modal" >Close</button>
</div>
</div>
</div>
</div>
but the onclick on my modal can't see the index, because it always delete the first row
deleteEmployee(id, index) {
jQuery.support.cors = true;
fetch('http://localhost:5118/api/employeedetails/DeleteEmployeeDetail/'+ id, {
method: 'GET'
}).then(function(response) {
// history.go(0);
var jsonReturnedValue = [...this.state.jsonReturnedValue];
this.setState({jsonReturnedValue})
}).catch(function(err) {
// Error :(
});
this.state.jsonReturnedValue.splice(index, 1)
this.setState({})
}
PS: The delete works my problem was only the ajax
You are passing the emplyee ID into the bind function as a parameter, which doesn't make sense at all, what you need to do is pass the employee ID to the deleteEmployee function, like this:
onClick={() => this.deleteEmployee(d.Employee_ID , d.Employee_Name,i).bind(this)}
Also just as an extra information start using ES6's awsesome arrow function and you don't have to bind the this everytime, for instance in your case just change the above click handler to:
onClick={() => this.deleteEmployee(d.Employee_ID , d.Employee_Name,i)}
and your deleteEmployee function should look like this:
deleteEmployee = (id, index) => {
jQuery.support.cors = true;
fetch('http://localhost:5118/api/employeedetails/DeleteEmployeeDetail/'+ id, {
method: 'GET'
}).then(function(response) {
// history.go(0);
var jsonReturnedValue = [...this.state.jsonReturnedValue];
this.setState({jsonReturnedValue})
}).catch(function(err) {
// Error :(
});
this.state.jsonReturnedValue.splice(index, 1)
this.setState({})
}
for the button you should change it
<td><center><button className ='btn btn-danger' onClick={this.handleOnclick2.bind (this,d.Employee_ID,d.Employee_Name,i)} data-toggle="modal" data-target="#DeleteEmployee"> Delete</button></center></td>
and add the bind in your constructor
constructor() {
super();
this.state = { jsonReturnedValue: []}
this.handleOnclick2= this.handleOnclick2.bind(this)
}

Inject data from a modal form into a parent form in AngularJS?

I have a form with additional data fields displayed in a modal:
<form class="form-horizontal" name="newForm" ng-controller="FormCtrl" ng-submit="submit()">
<label>Test</label>
<div ng-controller="ModalCtrl">
<a class="btn btn-link" ng-click="open()">Open</a>
<ng-include src="'partials/modal.html'"></ng-include>
</div>
</form>
includes:
<div modal="shouldBeOpen" close="close()" options="opts">
<div class="modal-header">
<h4>I'm a modal!</h4>
</div>
<div class="modal-body">
<ul>
<input type="text" tabindex="16" ng-model="someinput" name="someinput" size="32" class="validate[someinput]" />
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
</div>
</div>
JS:
var ModalCtrl = function ($scope) {
$scope.open = function () {
$scope.shouldBeOpen = true;
};
$scope.close = function () {
$scope.shouldBeOpen = false;
};
$scope.opts = {
backdropFade: true,
dialogFade:true
};
};
How can I read/inject/transfer the user input from the modal form into the main form?
What you need is to communicate between two controllers and this can be achieved by creating a service.
Using this as reference.
You could create a service as follows:
angular.module('myApp', [])
.service('sharedInput', function () {
var modalInput = "";
return {
getModalInput:function () {
return modalInput;
},
setModalInput:function (value) {
modalInput = value;
}
};
});
Next, in your ModalCtrl() function, I assume that you will have a button to submit the input. Let us say that clicking this button invokes the "submitInput" function in the scope of ModalCtrl. You will write this function as:
$scope.submitInput = function() {
sharedInput.setMOdalInput($scope.someinput);
}
...and in your FormCtrl() you will write the following code to read the modal input:
var input = sharedInput.getModalInput()
You also need to pass the parameter "sharedInput" to the ModalCtrl and FormCtrl just like how you passed $scope. And now you have your two controllers communicating.
I found a comment to an issue on GitHub with a plunker explaining the problem and the solution with angular-ui, without the shared service. Works like a charm.
http://plnkr.co/edit/ktfq0Y?p=preview

Categories