AngularJS change attribute values - html

I have rows in table which generate buttons dynamically
<tr ng-repeat="task in task">
<td>{{task.Name}}</td>
<td>{{task.Comments}}</td>
<td>{{task.Project}}</td>
<td>{{task.Duration}}</td>
<td>
<button class={{editable}} ng-click="editTask(task.id)"></button>
<button class="glyphicon glyphicon-trash"></button>
</td>
</tr>
In my Angular code I have
$scope.editTask = function(id){
if($scope.editable == "glyphicon glyphicon-edit"){
$scope.editable="glyphicon glyphicon-floppy-save";
}
else{
$scope.editable="glyphicon glyphicon-edit"
}
}
So basically I want to change the edit glyphicon to save glyphicon and the save glyphicon back to edit glyphicon. But since I have assigned class to the button it changes the glyphicons of all buttons in the table. How can I change the icon of only the button of which is clicked?

By assigning the editable variable to the task object:
$scope.editTask = function(task){
if(task.editable == "glyphicon glyphicon-trash")
task.editable="glyphicon glyphicon-floppy-save";
else
task.editable="glyphicon glyphicon-trash";
}
and in your HTML:
<button ng-class="editable" ng-click="editTask(task)"></button>
This way, you'll end up having an unique class for each of your task object.
Also, remember to use ng-class instead of the plain class attribute.

Approach 1
You can update your HTML to
<td>
<button class="glyphicon" ng-class="task.editable" ng-click="editTask(task)"></button>
<button class="glyphicon glyphicon-trash"></button>
</td>
Passing the task instead of the id directly allows you to update it's editable state directly on the task. Your controller should update the editable property
$scope.editTask = function(task){
if(task.editable == "glyphicon-edit") {
task.editable="glyphicon-floppy-save";
}
else{
task.editable="glyphicon-edit"
}
}
Note: I've passed the glyphicon class directly to the button since it won't change.
Approach 2
You could also approach it another way and keep the condition in the HTML
<button class="glyphicon" ng-class="task.editable ? 'glyphicon-edit': 'glyphicon-floppy-save'" ng-click="editTask(task)"></button>
And your controller could just update the editable property
$scope.editTask = function(task){
task.editable = !task.editable;
}

Set the editable property on the task itself and then use task.editable. This will be a unique property for each task

you need to make some changes to your code. I'm gonna provide you the code I used in order to achieve what I believe is your goal, and will then explain the reasoning behind it.
<table>
<tr ng-repeat="task in tasks">
<td>{{task.Name}}</td>
<td>{{task.Comments}}</td>
<td>{{task.Project}}</td>
<td>{{task.Duration}}</td>
<td>
<button class={{task.editable}} ng-click="editTask($index)"></button>
<button class="glyphicon glyphicon-trash"></button>
</td>
</tr>
</table>
As you can see, I included an attribute inside the task called editable. I'll be using this attribute to change the class. You'll also notice I', using $index. This is a default counter for ng-repeat.
$scope.tasks.push({Name: 'Jorge', Comments: 'Comentario',Project: 'Tengu', Duration: 45, editable: "glyphicon glyphicon-trash"});
$scope.tasks.push({Name: 'Mermelada', Comments: 'Comentario2',Project: 'DM-300', Duration: 30, editable: "glyphicon glyphicon-trash"});
You'll need to add the editable properties to your objects.
$scope.editTask = function(id){
if($scope.tasks[id].editable == "glyphicon glyphicon-trash"){
$scope.tasks[id].editable="glyphicon glyphicon-floppy-save";
} else{
$scope.tasks[id].editable="glyphicon glyphicon-trash"
}
}
I don't believe this needs much explanation. Please let me know otherwise.

If you simply want to switch between class just use ng-class
exemple, you have a variable leftOrRight, we will assume that you have two class in you css file: floatLeft and floatRight (with the attribute float: right/left; )
ng-class="{ floatRight : leftOrRight == 'right', floatLeft : leftOrRight == 'left' }"
If you set leftOrRight to "right" you will have the same thing as class="floatRight" for exemple.

Related

Manipulate Html table with Angular

very simple
what is the equivalent of this jQuery code
$('#message tr').eq(index).addClass('negative') in angular,
or how can i achieve the same result with angular
can't use [class.bind] the above job should be done in by clicking the button.
the button will pass some data to the function and based on some condition and checking the negative class will be added to the related row not to all of them.
You have not added any code, so I imagine you have something like:
<table>
<tr *ngFor="let data of arrayData;let i=index" [class.negative]="indexSelected==i">
<td>{{data?.prop1}}</td>
<td>{{data?.prop2}}</td>
<td><button
(click)="indexSelected=(indexSelected==i)?-1:i;
indexSelected!=-1 && diifer(data)">
select
</button>
</td>
</tr>
</table>
(or instead use a button add the "click" to the <tr>)
You can also pass the "index" to the function diifer like
(click)="diifer(data,i)"
And
diifer(data:any,index)
{
this.indexSelected=this.indexSelected==index?-1:index
if (this.indexSelected!=-1)
{
...do something..
}
}
NOTE: See that you check if indexSelected is the "row" you select. If true, you "unselect" making indexSelected=-1
NOTE2: remember that index goes from 0 to arrayData.length-1

How to access a dynamically generated id of a HTML element with angular

<div *ngFor="let link of links; let i = index;">
<p>{{link.full}}</p>
<button [id]='i' (click)="copyToClipboard(copy) ">Copy</button>
</div>
How do I access the [id]="i" in my typescript file
Have a look at this demo:
[https://stackblitz.com/edit/angular-irxzeg?file=src%2Fapp%2Fapp.component.ts]
It includes suggestions from #Sam Herrmann
And with Renderer, to add Class
[https://stackblitz.com/edit/angular-mjvvp1?file=src%2Fapp%2Fapp.component.ts]
You don't need to add an id or to change 'manually' the label of button.
You can add a flag to know if link has been copied or not, inside your existing model.
For example:
export type Link = {
full: string,
copied: boolean
}
Then, inside your code you can set this flag to true:
copyToClipboard(link: Link) {
link.copied = true;
...
}
In template, just use this flag to adapt the label of button, and also to set a specific class on button (or elsewhere):
<div *ngFor="let link of links">
<p>{{link.full}}</p>
<button (click)="copyToClipboard(link)" [class.copied]="link.copied">
{{ link.copied ? 'Copied' : 'Copy' }}</button>
</div>
.copied {
background-color: green
}

How to control multiple (click) events inside a table?

Hello I hope the title is descriptive enough to understand my problem,
I have this HTML code. In <td> i have attached a (click) function. Inside this <td>, I have another div which also has a (click) function attached. When I click the button inside <td> both functions are triggered.
But, I would like only the (click) in div to be triggered when I click it and not the <td> (click).
Is it possible to happen?
<td mat-cell align="center" *ngFor="let option of options; let opt_indx = index"
(click)="optionsClicked(opt_indx, i);" id="defaultBadge-wrapper">
<div *ngIf="!rowCommands[i].defaultSelected[opt_indx]" class="defaultBadge">
<a class="badge badge-secondary" matTooltip="Click here to set this Option as Default"
(click)="markDefault(i,option.id)">Default</a>
</div>
</td>
Typescript code
markDefault(index, option: string) {
alert('this function triggered');
}
optionsClicked(option, rule) {
alert('I dont want this function to be triggered when i click markDefault');
}
In ts method pass the $event as param and include
event.stopPropagation();
or in the click event pass another function:
(click)="markDefault(i,option.id); event.stopPropagation();">Default</a>
use the stoppropagation to prevent the event from propagating
(click)="markDefault(i,option.id); event.stopPropagation();">Default</a>
just add $event.stopPropagation() to inner click.
<div *ngIf="!rowCommands[i].defaultSelected[opt_indx]" class="defaultBadge">
<a class="badge badge-secondary" matTooltip="Click here to set this Option as Default"
(click)="$event.stopPropagation();markDefault(i,option.id)">Default</a>
</div>

Hide and show div in Angular

I want to show a div that is hidden when I click on a Button. I am working with Angular7 I tried some methods but they didn't work. Please help me. Thanks
You can use *ngIf
Template:
<div *ngIf="display">Test Data</div>
<input type="button" value="click" (click)="update"/>
Component:
display = true;
update(){
this.display = !this.display;
}
You can link an *ngIf directive to your component with a variable set to True,
then on the button click modify the variable to false.
Template:
<div *ngIf='variable'></div>
<button (click)='showContent()'></button>
Component:
variable = true;
showContent() {
this.variable = false;
}
change display or visibility depending on what you need.
use ngStyle or ngClass to set it based on a condition

what is the method(way) to use data of html in component of angular 2?

in angular 2 there is a button that I want when click on it a div appear.
<button class="dokme" type="button" (click)="onSelect(signUp)" >Register</button>
<div *ngIf="selectedBtn">
<div>Hello</div>
</div>
and I couldn't complete my component, because I don't know how I should write it:
onSelect():void{
this.selectedBtn=...(?)}
Actually I know it can be similat to "Hide the empty detail with ngIf" in angular tutorial Hide the empty detail with ngIf, but the problem is I can't change that code to what I want. Because in that example there is hero and I don't know what should I replace it.
please help me in the simplest way it would be your kind.
The expression you pas into (click) will be executed when you click on the button.
If the expression you pass into *ngIf is true, the content inside the element will be present on the page. Otherwise, it will not.
So, what you ned to do is to change the value of selectedBtn when (click) event happens.
Template
<button class="dokme" type="button" (click)="onSelect()" >Register</button>
<div *ngIf="selectedBtn">
<div>Hello</div>
</div>
Component
onSelect() {
this.selectedBtn = true
}
Just set the variable to true
onSelect() {
this.selectedBtn = true;
}
ngIf works in a simmilar way that if statement in other programming languages so it checks for condition and if it is true (or if a function called in condition returns true). In this case, your ngIf is linked to component variable selectedBtn so only what you need to do is set it to true:
this.selectedBtn = true;
More easily, you can achieve the sane goal without creating new function in your controller.
<button class="dokme" type="button" (click)="selectedBtn=true" >Register</button>
<div *ngIf="selectedBtn">
<div>Hello</div>
</div>
Or if you want the button to toggle :
<button class="dokme" type="button" (click)="selectedBtn=!selectedBtn" >Register</button>
<div *ngIf="selectedBtn">
<div>Hello</div>
</div>