sort a table's columns using jquery without plugins - javascript

I am trying to sort a table's column values when specific buttons are clicked. I first want to figure out how to sort the table with pre-defined values (I have included 2 rows with actual values in my table). Second, after I am done with sorting pre-defined values in the table. I want to be able to add a "Create Row" button which can randomly generate any values or even letters. And still, after clicking buttons, values will be sorted.
My code is broken and I don't know why!
I am stuck and I cannot find much help!! Thanks in advance guys!
//add row function
$(document).ready(function() {
$("#add_row").click(function() {
event.preventDefault();
var new1 = $("<tr><td>6</td><td>1</td><td><input id ='dr' class='btn btn-danger' type ='button' value= 'delete'></td></tr>").on('click', function() {
$(this).find('td').toggleClass('highlighted')
});
$('#myTable').append(new1);
});
//delete function
$('#myTable').on('click', '#dr', function() {
$(this).parent().parent().remove();
});
//sort function
$('#sort1,#sort2').on('click', function() {
var n1 = $(this).index();
console.log(n1);
var n2 = $('#myTable').find('tbody >tr:has(td)').get();
console.log(n2);
n1 += 1;
n2.sort(function(a, b) {
var vA = $(a).children(':nth-child(' + n1 + ')').text();
var vB = $(b).children(':nth-child(' + n1 + ')').text();
if (vA < vB) {
return -1;
} else if (vA > vB) {
return 1;
} else {
return 0
};
});
$.each(n2, function(index, row) {
$('tbody').append(row);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>create table</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style type="text/css">
table,
td {
border: 1px solid black;
}
.highlighted {
background-color: yellow;
}
</style>
</head>
<body>
<div class="container">
<p>Click the buttons to create and delete row(s) for the table.</p>
<table id="myTable" class="table" style="width: 80%">
<tbody>
<tr>
<td>Name<button type="button" id="sort1" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></td>
<td>Value<button type="button" id="sort2" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></td>
<td>Deletable</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<br>
<button type="button" id="add_row" class="btn btn-primary">Create row</button>
</div>
</body>

In your first row if you change the <td> tags to <th>s then the sorting will leave them where they are.
<th>Name<button type="button" id="sort1" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></th>
<th>Value<button type="button" id="sort2" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></th>
<th>Deletable</th>
And in your code when getting the index of the clicked button you always get the index of $(this) which is the button's index and not the column's. So try changing that line to
var n1 = $(this).closest("th").index();
and it should work.
//add row function
$(document).ready(function() {
$("#add_row").click(function() {
event.preventDefault();
var new1 = $("<tr><td>6</td><td>1</td><td><input id ='dr' class='btn btn-danger' type ='button' value= 'delete'></td></tr>").on('click', function() {
$(this).find('td').toggleClass('highlighted');
});
$('#myTable').append(new1);
});
//delete function
$('#myTable').on('click', '#dr', function() {
$(this).parent().parent().remove();
});
//sort function
$('#sort1,#sort2').on('click', function() {
var n1 = $(this).closest("th").index() + 1;
console.log(n1 - 1);
var n2 = $('#myTable').find('tbody >tr:has(td)').get();
console.log(n2);
n2.sort(function(a, b) {
var vA = $(a).children(':nth-child(' + n1 + ')').text();
var vB = $(b).children(':nth-child(' + n1 + ')').text();
if (vA < vB) return -1;
if (vA > vB) return 1;
return 0;
});
$.each(n2, function(index, row) {
$('tbody').append(row);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>create table</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style type="text/css">
table,
td {
border: 1px solid black;
}
.highlighted {
background-color: yellow;
}
</style>
</head>
<body>
<div class="container">
<p>Click the buttons to create and delete row(s) for the table.</p>
<table id="myTable" class="table" style="width: 80%">
<tbody>
<tr>
<th>Name<button type="button" id="sort1" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></th>
<th>Value<button type="button" id="sort2" class="btn btn-default btn-xs pull-right glyphicon glyphicon-triangle-bottom"></button></th>
<th>Deletable</th>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<br>
<button type="button" id="add_row" class="btn btn-primary">Create row</button>
</div>
</body>

Related

Dynamically add row with jQuery

I have an application that integrated with barcode scanner, like this:
I have made a row dynamically with this snippet of code:
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<div class="container" align="top" style="margin-top: 0px;">
<h1 align="center">
Barcode: <br><input type="text" id="myHeader" value="5555">
</h1>
<table id="myTable" class=" table order-list">
<thead>
<tr>
<td>Barcode</td>
<td>Item</td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align: left;">
<div align="right">
<p style="color: black;margin-right: 90px;">9.999.999</p>
</div>
<input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
</td>
</tr>
<tr>
</tr>
</tfoot>
</table>
</div>
and here is the code that I wrapped with script tag:
<script >
$(document).ready(function() {
var counter = 0;
$("#addrow").on("click", function() {
var newRow = $("<tr>");
var cols = "";
cols += '<td><input type="text" disabled value="123123123" class="form-control" name="name' + counter + '"/></td>';
cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function(event) {
$(this).closest("tr").remove();
counter -= 1
});
});
function calculateRow(row) {
var price = +row.find('input[name^="price"]').val();
}
function calculateGrandTotal() {
var grandTotal = 0;
$("table.order-list").find('input[name^="price"]').each(function() {
grandTotal += +$(this).val();
});
$("#grandtotal").text(grandTotal.toFixed(2));
} </script>
But the code above just add the row only when I clicked the Add Row button.
What I want for now is, when I scan a barcode with a barcode scanner, the row automatically added follow the scanned barcode result.
In this case it will be: "When the value on barcode on the header changed ( <h1 align="center">Barcode: 123123123</h1> , the result is same when I clicked the Add Row button.
So, please refer any approach, tutorial or example code how to do that, it would be very appreciated :)
For additional information: The purpose of this app is for cashier app on a store, like when the cashier scan a product, the result automatically appear on the app. And I developing it using Python Flask.
You have to listen to the changes made in the element. You can try with MutationObserver
$(document).ready(function() {
var counter = 0;
$("#addrow").on("click", function() {
var newRow = $("<tr>");
var cols = "";
cols += '<td><input type="text" disabled value="123123123" class="form-control" name="name' + counter + '"/></td>';
cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function(event) {
$(this).closest("tr").remove();
counter -= 1
});
});
function calculateRow(row) {
var price = +row.find('input[name^="price"]').val();
}
function calculateGrandTotal() {
var grandTotal = 0;
$("table.order-list").find('input[name^="price"]').each(function() {
grandTotal += +$(this).val();
});
$("#grandtotal").text(grandTotal.toFixed(2));
}
// Listen to the changes in the header element and add row
var target = document.querySelector('#myHeader');
setTimeout(function() {
target.textContent = "New Barcode: XXXXXXXXX"; // change text after 2 seconds
}, 2000)
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
$("#addrow").trigger("click"); // trigger the click event to add row if the header text is changed
});
});
var config = {
attributes: true,
childList: true,
characterData: true
};
observer.observe(target, config);
// otherwise
observer.disconnect();
observer.observe(target, config);
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<div class="container" align="top" style="margin-top: 0px;">
<h1 align="center" id="myHeader">Barcode: 123123123</h1>
<table id="myTable" class=" table order-list">
<thead>
<tr>
<td>Barcode</td>
<td>Item</td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align: left;">
<div align="right">
<p style="color: black;margin-right: 90px;">9.999.999</p>
</div>
<input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
</td>
</tr>
<tr>
</tr>
</tfoot>
</table>
</div>
Update: The updated question indicates that you can trigger the click event on blur event of the barcode input element:
$(document).ready(function() {
var counter = 0;
$("#addrow").on("click", function() {
var newRow = $("<tr>");
var cols = "";
var barcode = $("#myHeader").val().trim();// take the current barcode value
cols += '<td><input type="text" disabled value= '+ barcode +' class="form-control" name="name' + counter + '"/></td>';
cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function(event) {
$(this).closest("tr").remove();
counter -= 1
});
});
function calculateRow(row) {
var price = +row.find('input[name^="price"]').val();
}
function calculateGrandTotal() {
var grandTotal = 0;
$("table.order-list").find('input[name^="price"]').each(function() {
grandTotal += +$(this).val();
});
$("#grandtotal").text(grandTotal.toFixed(2));
}
// Add new row by triggering the click event on focus out
var target = document.querySelector('#myHeader');
target.addEventListener('blur', function(){
$("#addrow").trigger("click");
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<div class="container" align="top" style="margin-top: 0px;">
Barcode: <br><input type="text" id="myHeader" value="5555">
<table id="myTable" class=" table order-list">
<thead>
<tr>
<td>Barcode</td>
<td>Item</td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align: left;">
<div align="right">
<p style="color: black;margin-right: 90px;">9.999.999</p>
</div>
<input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
</td>
</tr>
<tr>
</tr>
</tfoot>
</table>
</div>
$('#myTable tbody').append(newRow)
I think you have problem with your jQuery selector.
Try the code shown above - hope it works for you.

Using AngularJS Trying to insert a <tr> in the middle

Here, I'm trying to insert a tr tag under a selected tr tag.I managed to insert the tr in the table but it was in the bottom.
This is a sample code:
"use strict";
(function(angular) {
var app = angular.module('app', []);
app.controller('MainController', MainController);
MainController.$inject = ['$compile', '$scope', '$templateCache'];
function MainController($compile, $scope, $templateCache) {
var publishShown = false;
var lastItemAppned;
var vm = this;
vm.targets = ['Single passenger', 'Single driver', 'All passengers', 'All drivers'];
vm.items = ["Cheese", "Pepperoni", "Black Olives"];
vm.cancel = cancel;
vm.fruits = [{
name: 'Orange',
color: 'Orange',
tree: 'Orange Tree!',
origin: 'China'
}, {
name: 'Apple',
color: 'Green',
tree: 'Apple Tree!',
origin: 'Moon'
}];
vm.message = 'Fruit store!';
function appendTemplate(event) {
if (publishShown) {
removeLastAppend();
}
publishShown = true;
var template = $templateCache.get('template.html');
var compiledHtml = $compile(template)($scope);
var parent = event.currentTarget.parentElement.parentElement.parentElement;
parent.append(compiledHtml[0]);
}
vm.showOptions = function(event) {
appendTemplate(event);
}
function removeLastAppend() {
angular.element('#publish-template').remove();
}
function cancel() {
removeLastAppend();
}
}
})(window.angular);
<!DOCTYPE html>
<html ng-app="app">
<head>
<link data-require="bootstrap-css#3.*" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
<link data-require="bootstrap#*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
<script data-require="jquery#*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="Tether#*" data-semver="1.4.0" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script data-require="bootstrap#*" data-semver="4.0.5" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<script data-require="angularjs#1.6.*" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
<script data-require="angular-animate#1.6.*" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular-animate.js"></script>
<script data-require="angular-touch#1.6.*" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular-touch.js"></script>
<script data-require="ui-bootstrap#*" data-semver="2.5.0" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-2.5.0.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController as vm">
<script type="text/ng-template" id="template.html">
<tr id="publish-template">
<td colspan="5">
<div class="row">
<div class="col-sm-3">
<button class="btn btn-sm btn-success" ng-click="vm.command()">Command</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-primary" ng-click="vm.sell()">Sell</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-warning" ng-click="vm.eatSome()">Eat some!</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-danger" ng-click="vm.cancel()">Cancel</button>
</div>
</div>
</td>
</tr>
</script>
<div class="container-fluid">
<h1>{{vm.message}}</h1>
<table class="table">
<thead>
<th>Name</th>
<th>Color</th>
<th>Tree</th>
<th>Origin</th>
<th>Action</th>
</thead>
<tbody>
<tr ng-repeat="fruit in vm.fruits">
<td>{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptions($event)">Options</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
As you see, if you click the second options button, you'll not notice the problem, but if you click the first one, it adds a tr tag always in the bottom of the table!
My aim is to add the new tr under the selected on.
Thanks in advance
The ng-repeat is running on the tr element and you are looking to break the loop and insert another tr in the middle based on the row that was clicked on. To achieve this you need to break the table into 3 parts
TR ng-repeat on topFruits
TR row with option buttons (will be hidden initially)
TR ng-repeat on bottomFruits
Initially, you will need to assign all the fruits to topFruits and keep the bottomFruits null. Also keep the tr row with the option buttons hidden.
When the show Options button is clicked on a row, get the index of the row and then divide the fruits between topFruits and bottomFruits based on the index. Also make the row with buttons visible.
Here is a working demo
Here is the HTML body
<body ng-controller="MainCtrl as vm">
<div class="container-fluid">
<h1>{{vm.message}}</h1>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
<th>Tree</th>
<th>Origin</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="fruit in vm.topFruits">
<td style="background:#bbb">{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptionsTop($index)">Options</button>
</td>
</tr>
<tr id="publish-template" style="display:none">
<td colspan="5">
<div class="row">
<div class="col-sm-3">
<button class="btn btn-sm btn-success" ng-click="vm.command()">Command</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-primary" ng-click="vm.sell()">Sell</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-warning" ng-click="vm.eatSome()">Eat some!</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-danger" ng-click="vm.cancel()">Cancel</button>
</div>
</div>
</td>
</tr>
<tr ng-repeat="fruit in vm.bottomFruits">
<td style="background:#fcc">{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptionsBottom($index)">Options</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
Here is the controller code
vm.fruits = [{
name: 'Orange',
color: 'Orange',
tree: 'Orange Tree!',
origin: 'China'
}, {
name: 'Apple',
color: 'Green',
tree: 'Apple Tree!',
origin: 'Moon'
}];
vm.topFruits = vm.fruits;
vm.bottomFruits = [];
vm.message = 'Fruit store!';
function appendTemplate(index) {
if (vm.publishShown) {
removeLastAppend();
}
vm.publishShown = true;
vm.topFruits = [];
vm.bottomFruits = [];
document.getElementById('publish-template').style.display="block";
for(i=0;i<vm.fruits.length;i++) {
if(i<=index) {
vm.topFruits[i] = vm.fruits[i];
} else {
vm.bottomFruits[i-vm.topFruits.length] = vm.fruits[i];
}
}
}
vm.showOptionsTop = function(index) {
appendTemplate(index);
}
vm.showOptionsBottom = function(index) {
appendTemplate(index+vm.topFruits.length);
}
function removeLastAppend() {
document.getElementById('publish-template').style.display="none";
vm.publishShown = false;
}
function cancel() {
removeLastAppend();
}

change Id/class or input name on adding rows in dynamic table

Currently I'm working on a dynamic table where user can add and remove rows form the table to input data...how do I change my user's input 'name/id/class' on adding rows. Any help will be appreciated. Thanks.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic table</title>
<script src="https://code.jquery.com/jquery-1.8.3.min.js" integrity="sha256-YcbK69I5IXQftf/mYD8WY0/KmEDCv1asggHpJk1trM8="
crossorigin="anonymous"></script>
<script>
$(document).ready( function() {
$('#butVal').click(function(){
var rowLen = $('tr.tabRow').length;
if(rowLen>9)
{
alert("no of row is reached 10");
}
else
{
$("tr.tabRow:first").clone(true).appendTo("#table-2>tbody");
$(".tabRow:last").children("td").children("input").each(function(index, element){
$(element).val("");
});
}
});
$(document).on("click", "button.remove", function(){
if($(this).parents("tr").siblings("tr.tabRow").length > 0)
{
$(this).closest("tr.tabRow").remove();
}
else
{
alert("you can.t remove this record");
}
});
$(document).on("click", ".add, .remove", function(){
$("td.sno").each(function(index,element){
$(element).text(index + 1);
});
});
});
</script>
</head>
<body>
<div class="total">
<table id="table-2" class="add" border ="1">
<thead>
<tr>
<th class="small">S.No</th>
<th class="sizing"> Description</th><th>Quantity</th>
<th> Price </th>
<th><button id="butVal"> + </button></th>
</tr>
</thead>
<tbody>
<tr class="tabRow" id="1item">
<td class="sno">1</td>
<td> <input class="desc" type="text" name="desc"/> </td>
<td> <input class="qty" type="text" name="qty"/> </td>
<td> <input class="price" type="text" name="price"/> </td>
<td><button class="remove">Remove</button></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
So you have tried using ".addClass() Jquery function" or removeclass() function??
Heres an example of .addClass():
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>addClass demo</title>
<style>
p {
margin: 8px;
font-size: 16px;
}
.selected {
color: blue;
}
.highlight {
background: yellow;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<p>Hello</p>
<p>and</p>
<p>Goodbye</p>
<script>
$( "p" ).last().addClass( "selected" );
</script>
</body>
</html>
So, whenever a new entry is created, you need to change the class attribute of the input elements:
$('#butVal').click(function () {
var rowLen = $('tr.tabRow').length;
if (rowLen > 9) {
alert("no of row is reached 10");
} else {
$("tr.tabRow:first").clone(true).appendTo("#table-2>tbody");
$(".tabRow:last").children("td").children("input").each(function (index, element) {
var className = $(element).attr("class"); // get the current class attribute of the element
$(element).attr("class", className + rowLen); // append the current row number to the class
$(element).val("");
});
}
});
Note: when you remove rows, the classes will not change. It could happen that you have the classes desc, then desc1, but then desc3.

AngularJS - add style/class to parent element when button is clicked

In my application I've a list of Product IDs that an user can assign to "Hot" or "Cold" by clicking on a button.
This is how this list is displayed:
And this is how it is created:
<table>
<tr ng:repeat="acq in WaterList">
<td style="border:0; padding:5px 20px">{{acq.ProductNumber}}</td>
<td style="border:0; padding:5px 20px"><button class="btn btn-primary" type="button" ng-click="updAC(acq.ApartmentId, acq.ProductNumber, acq.WaterTempId)">HOT</button></td>
<td style="border:0; padding:5px 20px"><button class="btn btn-primary" type="button" ng-click="updAF(acq.ApartmentId, acq.ProductNumber, acq.WaterTempId)">COLD</button></td>
</tr>
</table>
I would like to add a style to the parent <td> of a button to add a class, for example to add a border to show what button was clicked.
How can I do this with Angular?
Another idea could be to add bootstrap class disabled (not using ng-disabled or disabled HTML attribute, because buttons should remain clickable) to the not clicked button.
You could do it like this.
HTML:
<table>
<tr ng:repeat="acq in WaterList">
<td style="padding:5px 20px">{{acq.ProductNumber}}</td>
<td style="padding:5px 20px"><button data-ng-class="{active:index=={{$index}} && set===1}" class="btn btn-primary" type="button" ng-click="updAC($index, 1)">HOT</button></td>
<td style="padding:5px 20px"><button data-ng-class="{active:index=={{$index}} && set===2}" class="btn btn-primary" type="button" ng-click="updAF($index, 2)">COLD</button></td>
</tr>
</table>
Controller:
$scope.updAC = function(index, set) {
$scope.index=index;
$scope.set=set;
};
$scope.updAF = function(index, set) {
$scope.index=index;
$scope.set=set;
};
CSS:
button.active {
border-bottom: 2px solid #000000;
}
I left out all your other variables etc just to test it, but you probably know how to implement it to your own html and functions. You can also do variations with this. For example set different border or what ever on when clicking "HOT" or "COLD".
EDIT based on comments:
You could toggle the class like this:
tr.hot button.hot {
border: 2px solid red;
}
tr.cold button.cold {
border: 2px solid blue;
}
<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body ng-controller='testCtrl'>
<h1>Your Order</h1>
<table>
<tr ng:repeat="acq in WaterList">
<td style="padding:5px 20px">{{acq.ProductNumber}}</td>
<td style="padding:5px 20px"><button class="btn btn-primary hot" type="button" ng-click="updAC($event, 'hot')">HOT</button></td>
<td style="padding:5px 20px"><button class="btn btn-primary cold" type="button" ng-click="updAF($event, 'cold')">COLD</button></td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<script>
function testCtrl($scope) {
$scope.WaterList = [
{
'ProductNumber': 1
},{
'ProductNumber': 2
},{
'ProductNumber': 3
}
];
$scope.updAC = function(element, set) {
var tr = angular.element(element.target).parent().parent();
tr.removeClass('hot');
tr.removeClass('cold');
if (tr.hasClass(set)) {
tr.removeClass(set);
} else {
tr.addClass(set);
}
};
$scope.updAF = function(element, set) {
var tr = angular.element(element.target).parent().parent();
tr.removeClass('hot');
tr.removeClass('cold');
if (tr.hasClass(set)) {
tr.removeClass(set);
} else {
tr.addClass(set);
}
};
}
</script>
</body>
</html>
pass object to updAF and updAC functions and add ng-class with object property:
<table>
<tr ng:repeat="acq in WaterList">
<td style="border:0; padding:5px 20px">{{acq.ProductNumber}}</td>
<td style="border:0; padding:5px 20px" ng-class="{hot: acq.hot}"><button class="btn btn-primary" type="button" ng-click="updAC(acq)">HOT</button></td>
<td style="border:0; padding:5px 20px"ng-class="{cold: acq.cold}"><button class="btn btn-primary" type="button" ng-click="updAF(acq)">COLD</button></td>
</tr>
</table>
and add property to acq in updAF and updAC functions:
$scope.updAF = function(acq) {
acq.cold = true;
acq.hot = false;
};
$scope.updAC = function(acq) {
acq.hot = true;
acq.cold = false;
};
you can do this using a hr tag instead of a button from css.
<a id="btn" href="#btn">Demo</a>
here you have a fiddle
Check out the ngClass Directvie.

AngularJS ToDO List Edit error

I have an issue in the Edit Part of a Simple Angular Todo App That I created.
My App Adds, deletes and Edits an Entry. I have used AngularJS and BootStrap for this.
The prolem is, when I press edit button, all the entries, get into edit mode instead of the entry that I want to edit.
I am not sure why the in place edit is not working as expected.
My HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="UTF-8">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="../bower_components/angular/angular.min.js"></script>
<script src="todo.js"></script>
</head>
<body ng-controller="myCtrl">
<div class="container">
<h1>My TODO List</h1>
<table class="table">
<thead>
<tr>
<td><input class="form-control" ng-model="todo"></td>
<td><button class="btn btn-primary" ng-click="addItem()">Add</button></td>
</tr>
<tr>
<th>Serial No</th>
<th>Tasks to be Completed</th>
<th>Action</th>
<th>&nbsp</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in todolist">
<td >{{$index+1}}</td>
<td ng-hide="todo.selected == true">{{todo.task}}</td>
<td><input class="form-control" ng-show="todo.selected == true" ng-model="todo.task">
<button class="btn btn-success" ng-show="todo.selected == true" ng-click="save($index)">Save</button>
<button class="btn btn-danger" ng-show="todo.selected == true" ng-click="cancel($index)">Cancel</button>
<button class="btn btn-warning" ng-click="edit($index)" ng-hide="todo.selected == true">Edit</button>
<button class="btn btn-danger" ng-click="deleteItem($index)" ng-hide="todo.selected == true">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
My JavaScript Code:
angular.module("myApp",[])
.controller("myCtrl", function($scope){
$scope.todolist = [];
$scope.addItem = function(){
console.log($scope.todo);
if($scope.todo === undefined){
return false ;
}
else{
$scope.todoObj = {};
$scope.todoObj["task"] = $scope.todo;
$scope.todoObj["selected"] = false;
$scope.todolist.push($scope.todoObj);
$scope.todo = "";
console.log($scope.todolist);
}
}
$scope.deleteItem = function($index){
var index =$index;
$scope.todolist.splice(index,1);
}
$scope.edit = function($index){
for(var i=0; i< $scope.todolist.length; i++)
if($index == i){
$scope.todolist[i].selected = true;
}
}
$scope.save = function($index){
console.log("saving contact");
console.log($scope.todolist.length)
for(var i=0; i< $scope.todolist.length; i++){
if($index == i){
console.log($scope.todolist[$index]);
$scope.todolist[i] = `enter code here`angular.copy($scope.todolist[$index]);
// $scope.todolist[i] = $scope.todolist[$index];
$scope.todolist[i].selected = false;
console.log("todo after save",$scope.todolist);
}
}
}
$scope.cancel = function($index) {
for(var i=0; i< $scope.todolist.length; i++){
if ($scope.todolist[$index].selected !== false) {
$scope.todolist[$index].selected = `enter code here`$scope.todolist[i];
$scope.todolist[$index].selected = false;
}
}
};
})
When you are setting this
$scope.editing = $scope.todolist.indexOf(item);
All of your ng-repeats are relying on this to hide/show themselves.
ng-show="editing"

Categories