AngularJS: how to change button text onclick rendered using ng-repeat - javascript

I have the following HTML + AngularJS code:
<table class="table table-hover">
<thead>
<tr>
<th width="80%">Task</th>
<th width="10%">Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="task in task_list track by $index">
<td>{{task.title}}</td>
<td>
<button ng-click="delete_task($index)" class="btn btn-success btn-xs">Completed</button>
</td>
</tr>
</tbody>
</table>
This generate a list of task like in the following image:
View image
When I click on the "Complete" button I am sending an http request to server, and that part is working fine. What I am trying to achieve is, when I click on the button the button text should change to 'Please wait'.
How can I achieve this using AngularJS without using jQuery.

You can do something like this. The following code will change the status of button while submitting to submitting. Once complete it will change to completed and also disable the button.
Html
<tr ng-repeat="task in task_list track by $index">
<td>{{task.title}}</td>
<td>
<button ng-disabled="task.disabled" ng-click="delete_task($index)" class="btn btn-success btn-xs">{{task.status ? task.status : 'complete'}}</button>
</td>
</tr>
Javascript
$scope.delete_task = function(index) {
var task = $scope.task_list[index];
task.status = 'submitting';
$http.get('post.json').then(function(res) {
task.status = 'completed';
task.disabled = true;
});
};
Here is working plunkr

Related

How to save items to cart using localStorage

So I have a table like this:
<table border="1">
<tbody>
<tr>
<th> Book Title </th>
<th> Author </th>
<th> Book </th>
</tr>
<tr>
<td id= Book_Title>Gone </td>
<td id= Author>Micheal Grant</td>
<td><button id="AddToCart" onclick="addToLocalStorage()">Add To Cart</button> </td>
</tr>
<tr>
<td id= Book_Title>The Knife of never letting go</td>
<td id= Author>Ryan Howard</td>
<td><button id="AddToCart" onclick="addToLocalStorage()">Add To Cart</button> </td>
</tr>
</tbody>
My goal is to have, on button click for the data of a specific row to be saved to local storage. However, because the id's are the same for each row only the first instance of the id will save. I was wondering how I could use jquery closest() to fix my problem. Or even if there is any other solution to my problem.
In order to save the data contained in your table's row... Like the book title and author, I suggest you to use some objects contained in an array.
Then you'll have to stringify that prior to use localStorage.
When you'll want to retreive the stored data, you'll have to parse it back to an array of objects.
Sadly, SO snippets do not like the use of localStorage... So my working demo is on CodePen.
Here's the relevant code:
// The "add to cart" handler.
$("table").on("click", ".AddToCart", function(e){
// Get previous storage, if any.
var storage = JSON.parse(localStorage.getItem("cart"));
if(storage==null){
storage = [];
}
var row = $(this).closest("tr");
var title = row.find("td").eq(0).text().trim();
var author = row.find("td").eq(1).text().trim();
// Create an object to store.
var data = {author:author,title:title};
storage.push(data);
// Store it.
localStorage.setItem("cart",JSON.stringify(storage));
});
Use classes instead of IDs, and attach the listener using Javascript instead of inline attributes (which is as bad as eval). No need for jQuery. For example:
document.querySelector('table').addEventListener('click', (e) => {
if (e.target.className !== 'AddToCart') return;
// e.target refers to the clicked button:
const [bookTd, authorTd] = [...e.target.closest('tr').children];
addToLocalStorage({ title: bookTd.textContent, author: authorTd.textContent });
});
function addToLocalStorage(obj) {
console.log('adding ' + obj);
}
<table border="1">
<tbody>
<tr>
<th> Book Title </th>
<th> Author </th>
<th> Book </th>
</tr>
<tr>
<td class="Book_Title">Gone </td>
<td class="Author">Micheal Grant</td>
<td><button class="AddToCart">Add To Cart</button> </td>
</tr>
<tr>
<td class="Book_Title">The Knife of never letting go</td>
<td class="Author">Ryan Howard</td>
<td><button class="AddToCart">Add To Cart</button> </td>
</tr>
</tbody>
</table>

Angular , How to hide a table row on click of a button

I have a table in which each row has a delete button. on click of the button the data gets deleted. However to verify that record is deleted, I have to refresh the page. I want to hide the current row on click of the delete button. Here is my code.
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people" *ngIf="!hideRow">
<td><button (click)="delete(person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>
and in my component.ts On delete I change the value of hideRow
delete(id) {
this.hideTr = true;
this.personService.delete(id).subscribe(p=> console.log(p));
}
hideRow is a boolean variable with default value of false. The problem is that when I click on delete, all the rows become hidden(of course). How can I refer just to the current row?
When you want to delete the row then you should delete it in actual instead of hide row. No need of *ngIf="!hideRow". You no need to refresh the page, this is beauty of AngularJS. Below is code to delete particular row. Pass $index of the row:
HTML code:
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people">
<td><button (click)="delete($index)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>
JavaScript Code:
// delete row
$scope.delete = function(index) {
$scope.people.splice(index, 1);
};
Simple yet more effective :
Template Side :
<tr *ngFor="let person of people" *ngIf="!person?.hideRow">
<td><button (click)="delete(person)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
Component Side :
delete(person) {
person.hideRow = true;
this.personService.delete(person.id).subscribe(p=> console.log(p));
}
Without changing user's (property) interface
Template Side :
<tr *ngFor="let person of people;let i = index;">
<td><button (click)="delete(i , person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
Component Side :
delete(index , id) {
this.people.splice(index, 1);
this.personService.delete(id).subscribe(p=> console.log(p));
}
Based from the code you provided, I would remove this part *ngIf="!hideRow" and add this to your component
delete(id) {
this.personService.delete(id).subscribe(p=> {
console.log(p);
this.people.filter( person => person.id !== id)
// or you can use splice by using the index
});
}
Now your html is simpler and no need to use *ngIf
<table>
<tr>
<th>Delete</th>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let person of people">
<td><button (click)="delete(person.id)" title="Delete">Delete</button></td>
<td>person.Id</td>
<td>person.Name</td>
</tr>
</table>

ng-if inside ng-repeat in a table AngularJs

hey everyone am trying to use ng-if inside ng-repeat my condition is if {{dev[2]}} == "" i wanna display in the <td>Non Valide</td> else i just wanna display the data inside the dev i've been looking about a lot of exemples but nothing look the same cause am trying to use if else does it even possible to make it this way here's my code :
<table class="table table-bordered" >
<thead><tr class="infoti" >
<th>Id Dev</th>
<th>Nom Dev </th>
<th>Nom Ecu</th>
<th>Etat</th>
<th>Action</th>
<tr>
</thead>
<tbody>
<tr dir-paginate=" dev in devs | itemsPerPage:7 ">
<td >{{dev[0]}}</td>
<td>{{dev[1]}}</td>
<td>{{dev[2]}}</td>
<td ng-if({{dev[2]}} != "") >non validé</td>
<td><button class="btn btn-gray" ng-click="displaydata(dev[0])" data-toggle="modal" data-target="#myModal" >Validé</button></td>
</tr>
</tbody>
</table>
any help would be appreciated
You could use ng-bind to bind conditional data on view.
<td ng-bind="dev[2] != ''? 'Non Validé': 'Validé'"></td>

material angular checkbox bind custom input checkbox

Im using this awesome angular material, now what im trying to do is when the angular checkbox 1 is click then all the input checkbox that has a class of "column_1" will be check, same as the angular checkbox 2 and 3, clicking in any of them will then checked the corresponding input checkbox that was bind for the clicked angular checkbox e.g if click checkbox2 then all the input checkbox that has a class of "column_2" will be check, click checkbox3 then all the input checkbox that has a class of "column_3" will be check. Any help, clues, ideas, recommendation and suggestion to achieve it?
here's my html
<div ng-app="j_app">
<div ng-controller="j_controller">
<md-checkbox ng-model="check">
</md-checkbox>
<table>
<thead>
<th><md-checkbox class="checkbox1"></md-checkbox></th>
<th><md-checkbox class="checkbox2"></md-checkbox></th>
<th><md-checkbox class="checkbox3"></md-checkbox></th>
</thead>
<tbody>
<tr class="row_1">
<td class="column_1"><md-checkbox></md-checkbox></td>
<td class="column_2"><md-checkbox></md-checkbox></td>
<td class="column_3"><md-checkbox></md-checkbox></td>
</tr>
<tr class="row_2">
<td class="column_1"><md-checkbox></md-checkbox></td>
<td class="column_2"><md-checkbox></md-checkbox></td>
<td class="column_3"><md-checkbox></md-checkbox></td>
</tr>
</table>
</div>
</div>
and my script (module and controller)
var app = angular.module('j_app', ['ngMaterial']);
app.controller('j_controller', function($scope) {
$scope.check = {
value1 : true,
value2 : false
};
});
Here is a plunker that looks to the behavior you want :
I basically dynamically created the checkboxes to have a better control on it.
<th ng-repeat="(column,columnindex) in [1,2,3]">
<md-checkbox ng-change="checkColumnCheckBoxes(columnindex,checkBoxesHeader[columnindex])"
ng-model="checkBoxesHeader[columnindex]" class="checkbox1">
</md-checkbox>
</th>
<tr class="row_{{$index}}" ng-repeat="(row,rowindex) in [1,2,3]">
<td class="column_{{$index}}"
ng-repeat="(column,columnindex) in [1,2,3]">
<md-checkbox ng-init="checkBoxes[rowindex][columnindex] = false"
ng-model="checkBoxes[rowindex][columnindex]">
</md-checkbox>
</td>
</tr>
You can replace "[1,2,3]" with any other counter.
My js "checkColumnCheckBoxes" function :
$scope.checkColumnCheckBoxes = function(index,value){
angular.forEach($scope.checkBoxes, function(checkBox,key){
$scope.checkBoxes[key][index] = value;
})
}
I'm pretty sure you will have to rework this to your "real" needs (as you don't need a table that display only checkboxes) but it could be a solid start. If you need some help to adapt it to your needs feel free to ask.
Hope it helped.
Since your HTML is pre-generated here is how it should look like :
<table>
<thead>
<th><md-checkbox ng-change="checkColumnCheckBoxes(0,checkBoxesHeader[0])" class="checkbox1" ng-model="checkBoxesHeader[0]"></md-checkbox></th>
<th><md-checkbox ng-change="checkColumnCheckBoxes(1,checkBoxesHeader[1])" class="checkbox2" ng-model="checkBoxesHeader[1]"></md-checkbox></th>
<th><md-checkbox ng-change="checkColumnCheckBoxes(2,checkBoxesHeader[2])" class="checkbox3" ng-model="checkBoxesHeader[2]"></md-checkbox></th>
<tbody>
<tr class="row_1">
<td class="column_1"><md-checkbox ng-init="checkBoxes[0][0] = false" ng-model="checkBoxes[0][0]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[1][0] = false" ng-model="checkBoxes[0][1]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[2][0] = false" ng-model="checkBoxes[0][2]"></md-checkbox></td>
</tr>
<tr class="row_2">
<td class="column_1"><md-checkbox ng-init="checkBoxes[0][1] = false" ng-model="checkBoxes[1][0]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[1][1] = false" ng-model="checkBoxes[1][1]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[2][1] = false" ng-model="checkBoxes[1][2]"></md-checkbox></td>
</tr>
</table>
I also updated the plunker to match the exemple.

Extract a Cell/Td/tabledata value from a given row of a table using javascript/jquery

Here is my html table that is used in the Asp.net MVC razor view
<table class="table-striped table-bordered">
<thead>
<tr>
<th class="col-md-2">
Id
</th>
<th class="col-md-4">
Description
</th>
<th class="col-md-3">
Quantity
</th>
<th class="col-md-3">
AssetType
</th>
</tr>
</thead>
<tbody>
#foreach (var i in Model)
{
<tr>
<td class="col-md-2">
#i.Id
</td>
<td class="col-md-4">
#i.Description
</td>
<td class="col-md-3">
#i.Count
</td>
<td class="col-md-3">
#i.AssetType
</td>
<td>
<a onclick="getId()">Edit</a>
</td>
</tr>
}
</tbody>
</table>
My Js Code
<script type="text/javascript">
var getId = function () {
//get current row
var currentRow = $(this).closest('tr');
// get the id from the current row. or is there any better way ?
}
</script>
Hi In the above code. all i want to do is when the user selects the edit link of the given row in the table. i want to extract id value of the selected row.
Could anyone please guide me in this one? I have seen articles that says how to get a given cell value from each row but didnt have any luck in finding articles that explains how to extract the data cell value from a given row.
You already have it since you are generating the HTML from server side, when the user clicks pass the id to the funcion to do whatever you want with it.
<td>
<a onclick="getId('#i.Id')">Edit</a>
</td>
function getId(id) {...}
or if you prefer you can use something like this:
<a onclick="getId(this)">Edit</a>
function getId(dom){
var id = $(dom).parent().find('.col-md-2').html();
}
You can put the id value to data-id attribute in the Edit link as below
<a data-id="#i.Id" class="edit-button" href="#">Edit</a>
Add the click event handler to the edit link, you can get the id value by using $(this).data('id')
<script type="text/javascript">
$('.edit-button').on('click', function (e) {
e.preventDefault();
alert($(this).data('id'));
});
</script>
Working fiddle: http://jsfiddle.net/ds4t6jur/

Categories

Resources