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>
Related
I'm trying to do the following: I have a table populated with data from the DB. Apart from that, I have an input where you can write something and a button that will filter, only showing the lines that have that string. This is working now!
The thing is, the input should only allow you to filter by foo.name/foo.code (two propertys of my entity).
I'm adding the code I have in case anyone can guide me out, I've tried several things but this are my first experiences with JQuery while I have a strict story-delivery time. Thanks everyone!
<tbody>
<c:forEach var="foo" items="${foo}">
<tr id = "fooInformation" class="mtrow">
<th id="fooName" scope="row">${foo.name}</th>
<td id="fooCode" class="left-align-text">${foo.code}</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</c:forEach>
</tbody>
$("#search").click(function () { -> button id
var value = $("#fooRegionSearch").val(); -> value of the input
var rows = $("#fooRegionTable").find("tr"); -> table id
rows.hide();
rows.filter(":contains('" + value + "')").show();
});
To start with, your HTML is invalid - there cannot be elemenets with duplicate IDs in HTML. Use classes instead of IDs.
Then, you need to identify which TRs pass the test. .filter can accept a callback, so pass it a function which, given a TR, selects its fooName and fooCode children which contain the value using the :contains jQuery selector:
$("#search").click(function() {
var value = $("#fooRegionSearch").val();
var rows = $("#fooRegionTable").find("tr");
rows.hide();
rows.filter(
(_, row) => $(row).find('.fooName, .fooCode').filter(`:contains('${value}')`).length
).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="fooRegionTable">
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name1</th>
<td class="fooCode" class="left-align-text">code1</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name2</th>
<td class="fooCode" class="left-align-text">code2</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</table>
<button id="search">click</button><input id="fooRegionSearch" />
Every time the toggle is clicked, all payments are getting replaced with new payments. My problem is how to maintain the payments of a particular index of every click and show at respective index. please help me out
here is my html
<tbody data-ng-repeat="invoice in relatedInvoices>
<tr>
<td class="td-bottom-border">
{{invoice.PayableCurrencyCode}} {{invoice.PayablePaidAmount | number: 2}}<br />
<small>
<a data-ng-click="isOpenPayablePayments[$index] = !isOpenPayablePayments[$index]; togglePayablePayments(invoice.PayableInvoiceId)">Paid</a>
</small>
</td>
</tr>
<tr data-ng-show="isOpenPayablePayments[$index]">
<td>
<table>
<thead>
<tr>
<th>Transaction Id</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="payment in payablePayments">
<td>{{payment.TransactionId}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
Here is my javascript
var getPayments = function (invoiceId) {
paymentService.getPayments(invoiceId).then(function (paymentsResponse) {
return paymentsResponse.data;
});
};
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments = getPayments(invoiceId);
};
If I understood correctly, you want to have "payablePayments" for every invoice.
This is working: http://plnkr.co/edit/cj3jxZ?p=info
Try something like
// init at beginning
$scope.payablePayments = [];
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments[invoiceId] = getPayments(invoiceId);
};
and then
<tr data-ng-repeat="payment in payablePayments[invoice.PayableInvoiceId]">
Otherwise you overwrite the object for the preceding invoice.
Can anyone let me know how to disable on click event for particular column.
Scenario : We displayed user details in a table , once click has been made on the table row, popup dialog window will appears with more details(Calling ajax request to retrieve details from database) . But our constraint is to disable on click event for single column associated with the table.
Eg :
<table border = '1'>
<tr>
<th> Name </th>
<th> Id </th>
<th> Phone Number</th>
</tr>
<tr onclick = "testing()">
<td> Krupa </td>
<td> 123 </td>
<td> <a href = "http://www.google.com" target= '_blank'>Click me </a> </td>
</tr>
</table>
If click has been made on text(1st and 2nd column) , it will invoke on click event . But if user clicks on hyper link (3rd column) , i want to redirecting it to Google but not on-click event(testing()).
Can anyone help me to achieve this
Try this:
//snip
<tr>
<td onclick = "testing()"> Krupa </td>
<td onclick = "testing()"> 123 </td>
<td> <a href = "http://www.google.com" target= '_blank'>Click me </a> </td>
</tr>
//snip
Try this
Add a class named templatecell to the corresponding td to prevent click.
<table border = '1'>
<tr>
<th> Name </th>
<th> Id </th>
<th> Phone Number</th>
</tr>
<tr onclick = "testing()">
<td> Krupa </td>
<td> 123 </td>
<td class="templatecell"> <a href = "http://www.google.com" target= '_blank'>Click me </a> </td>
</tr>
</table>
script goes like this
$("table").on("click","td", function(e){
if($(e.target).closest(".templatecell").length){
//Clicked hyper link
//do action and return from here
return;
}
//Else clicked on td cell show popup
})
function testing() {
alert('testing')
}
$(document).ready(function () {
$('table tr td').click(function () {
if ($(this).index() < 2) {
testing();
}
else {
// window.open($(this).find('a').attr('href')); //working
$(this).find('a')[0].click();
}
});
});
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/
When someone clicks on the Download button in my table, I want to pass the date values from that particular row to a function. Currently I can only pass the date values from the first table row.
This is the selector I'm using:
$(this).parent().find('#period-start');
Which always returns:
[<td id="period-start">5/1/2013</td>]
I've tried combinations of the parent, child, find and closest selectors, but haven't been able to stumble across the correct one to grab the date values from the current row. Thanks.
Table
<table id="tblStatements" class="table">
<thead>
<tr>
<th>Period Starting</th>
<th>Period Ending</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<tr>
<td id='period-start'>5/1/2013</td>
<td id='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>4/1/2013</td>
<td id='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>3/1/2013</td>
<td id='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
</tbody>
</table>
ID's are always supposed to be unique in HTML. So, you might try out this, w/o using an ID:
// Get the first td
var periodStart = $(this).closest('tr').children('td:eq(0)').text();
// Get the second td
var periodEnd = $(this).closest('tr').children('td:eq(1)').text();
FIDDLE DEMO
Use this - don't use duplicate ID's though, use class instead
$(this).closest('tr').find('#period-start');
or -
$(this).closest('td').siblings('#period-start');
try this
$(this).parent().siblings('#period-start');
Make sure all your ids is unique..your HTML is invalid.... change it to class and try this
$(this).parent().siblings('.period-start');
You should not use more then one element with the same id use class insidead.
<tr>
<td class='period-start'>5/1/2013</td>
<td class='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>4/1/2013</td>
<td class='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>3/1/2013</td>
<td class='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
and use this code to select proper element
$(this).parents('tr').find('.period-start');
try this
$.trim($(this).closest('tr').find('[id="period-start"]').html());//this gives start date