Making The Table Count Rows - javascript

I have a table which automatically adds rows or removes them. I want to make the table to count these rows and give them number. For example;
| # | Name | Surname|
| 1 | Jake | Murray |
| 2 | Maria| Brown |
Here is my code;
Don't worry about the php code. I only need to fix the javascript. It may not work because i didn't put the php code inside the table.
var number = document.getElementById ( "nmr" ).innerText;
if (number = 1){
number = number + 1;
}
<table class="table">
<tr>
<th>#</th>
<th><b>Name</b></th>
<th><b>Email</b></th>
<th><b>The Lowest Money</b></th>
<th><b>The Most Money</b></th>
<th><b>Currency</b></th>
<th><b>Age</b></th>
<th><b>Gender</b></th>
<th><b>Hobby 1</b></th>
<th><b>Hobby 2</b></th>
<th><b>Reason</b></th>
<th><b>Favorite Color</b></th>
<th></th>
<th></th>
</tr>
<?php
require 'inc/session.ic.php';
$sql = "SELECT * FROM people WHERE username='" . $_SESSION[ "uid" ] . "'";
$res = mysqli_query( $conn, $sql );
?>
<?php
while ( $row = mysqli_fetch_assoc( $res ) ) {
$sql = "SELECT * FROM supportus WHERE emailUsers=\"" . $row["emailPerson"] ."\"";
$res2 = mysqli_query($conn, $sql);
$giftExists = mysqli_num_rows($res2) > 0;
// eger varsa, asagidaki butonu degistir.
?>
<tr>
<th id="nmr">1</th>
<td id="name"><?=$row["name"]?></td>
<td id="email"><?=$row["emailPerson"]?></td>
<td id="moneyLow"><?=$row["least"]?></td>
<td id="moneyMuch"><?=$row["much"]?></td>
<td id="currency"><?=$row["currency"]?></td>
<td id="age"><?=$row["age"]?></td>
<td id="gender"><?=$row["gender"]?></td>
<td id="hobby 1"><?=$row["likes_main"]?></td>
<td id="hobby 2"><?=$row["likes_sub"]?></td>
<td id="reason"><?=$row["reason"]?></td>
<td id="fovColor"><?=$row["color"]?></td>
<?php if ($giftExists) {?>
<td><a style="margin-top: 40px;" href="giftIdeas.php" class="btn btn-primary btn-sm active" role="button" aria-pressed="true">See Gifts??</a></td>
<?php } else {?>
<td><a style="margin-top: 40px;" href="giftIdeas.php" class="btn btn-primary btn-sm active" role="button" aria-pressed="true">See Gift Ideas</a></td>
<?php } ?>
<td><a style="margin-top: 40px;" href="2-kisi.php?deleteid=<?=$row["id"]?>" class="btn btn-primary btn-sm active" role="button" aria-pressed="true">Delete Person</a></td>
</tr>
<?php } ?>
</table>

what about something to the effect of const rows = document.querySelectorAll on the TRs and then .length will be the next number (because the tr from the head is basically the +1 you would normally do to inc the number)

It is a little unclear really what the problem actually is here - if it is to simply add a number for each row that can easily be accomplished in the PHP loop (set a variable and increment on each loop iteration.)
Further confusion because, according to the question, rows can be automatically added or removed but it is not clear how or why this happens. The javascript is incorrect and the HTML is also incorrect because of the duplicated ID attributes set on each TD ~ a better option if it is really required would be to use a dataset attribute perhaps but targeting specific elements within the DOM can be accomplished using querySelector &/or querySelectorAll
The below code uses a simple piece of Javascript ( & querySelectorAll ) to find all the relevant table cells within the table and assign an integer to each. Because of the "table which automatically adds rows or removes them" if a row were added or removed the integers would no longer be accurate - hence using the MutationObserver to monitor the DOM for changes to the table.
I hope this offers some help.
document.addEventListener('DOMContentLoaded',(e)=>{
// specifically target ALL first cells within the table and assign some content - an integer.
const callback = function() {
Array.from( document.querySelectorAll( 'tr > td:first-of-type' ) ).forEach( ( td, i )=>{
td.textContent=i + 1;
})
};
// determine what the observer will react to
const config = {
attributes:false,
childList:true,
characterData:false,
subtree:true
};
// monitor the table for changes
( new MutationObserver( callback ) ).observe( document.querySelector('table'), config );
// number the table rows at page load
callback();
// utility function to find table row
const getrow=function(e){
let n=e.target;
while(n.tagName!='TR')n=n.parentNode;
return n;
};
// a simple event listener bound to the `delete` links which will remove entire table row
// the `MutationObserver` will be triggered by a row deletion and the rows will be re-indexed
Array.from( document.querySelectorAll('td > a') ).forEach( a=>{
a.onclick=function(e){
e.preventDefault()
let tr=getrow(e);
tr.parentNode.removeChild( tr );
}
})
})
<table>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Surname</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>fred</td>
<td>bloggs</td>
<td>Delete</td>
</tr>
<tr>
<td></td>
<td>jim</td>
<td>smith</td>
<td>Delete</td>
</tr>
<tr>
<td></td>
<td>john</td>
<td>doe</td>
<td>Delete</td>
</tr>
<tr>
<td></td>
<td>mike</td>
<td>hunt</td>
<td>Delete</td>
</tr>
</tbody>
</table>
If that has over complicated things and you simply need to display a number on each row and the table does not change after page load then either add using PHP as mentioned or you could even just use CSS

Related

How do I filter a table by any matching code/name and not every available field

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" />

Showing and Hiding Table Rows Based Off Alphabet Buttons

I have a table with a lot of rows in it, and I want to give users the ability to click an 'A' button and all the results that start with 'A' are displayed. They could do the same for every letter. This is what I've come up with so far:
HTML
<input type="button" id="aSort" value="A" onclick="alphaSort(this.value);">
<table>
<thead>
<tr>
<td>Title</td>
<td>Description</td>
<td>Active</td>
</tr>
</thead>
<tbody>
<tr>
<td name="title">Apple</td>
<td>It's a fruit</td>
<td>Active</td>
</tr>
<tr>
<td name="title">Pear</td>
<td>It's also fruit</td>
<td>No</td>
</tr>
</tbody>
</table>
JS
function alphaSort(val) {
//pseudocode
var $rows = $('td[name=title]');
$rows.forEach(function(e) {
if(e.innerText == val + '%') {
e.closest('tr').show();
} else {
e.closest('tr').hide();
}
}
}
So with what I have here, the idea is if the user clicked the button only the Apple row would show. Ideally the function would be case insensitive. Could someone help me with how to properly iterate through all the table rows efficiently and compare the value stored in the title row?
you can use startsWith function : https://www.w3schools.com/jsref/jsref_startswith.asp
like this :
$("#aSort").click(function(){
var $rows = $('td[name=title]');
var val = $(this).val()
$rows.each(function() {
if($(this).text().startsWith(val)) {
$(this).closest('tr').show();
} else {
$(this).closest('tr').hide();
}
})
})
https://jsfiddle.net/xpvt214o/899140/

MySQL : Create table comparison product

I am confused when will display product comparison table. I have 2 tables t_product_item and t_product_specification. Here's a picture of the table structure:
I want to display a product comparison like this picture :
Script:
<table border="1">
<tr style="background-color: #C3C3C3">
<td>Product</td>
<td>Spec Name</td>
<td>Spec Value</td>
</tr>
<?php
$sql = mysqli_query($conn, "SELECT item, spec_name, spec_value FROM t_product_item JOIN t_product_specification USING (item_id)");
if (mysqli_num_rows($sql)>0){
while ($row=mysqli_fetch_array($sql)){
?>
<tr>
<td><?php echo $row['item']?>
<td><?php echo $row['spec_name']?>
<td><?php echo $row['spec_value']?>
</tr>
<?php
}}
?>
</table>
Instead it appears like this
Result:
How do I structure logically or query for the table to display like the example pic?
Change your SQL Query to:
SELECT spec_name,MAX(CASE WHEN ItemId=1 THEN spec_value END)`Samsung Galaxy S8+`
,MAX(CASE WHEN ItemId=2 THEN spec_value END)`Samsung Galaxy S8`
FROM t_product_item JOIN t_product_specification USING (item_id)
GROUP BY spec_name
ORDER BY MIN(spec_Id)
Hope this helps you.
You are looping through item_id for each of your <tr> rows. Instead you should be looping through spec_name for <tr>, and for each cell <td> loop through the product.
In pseudo code:
<table>
<thead>
<tr>
<th> </th> <!-- Empty cell for spacer -->
for (item in item_list) {
<th>item.name</th>
}
</tr>
</thead>
<tbody>
<tr>
for (spec in spec_list) {
<td>spec.name</td>
}
for (item in item_list) {
<td>item.spec[spec.name]</td> <!-- display spec detail of each item -->
}
</tr>
</tbody>
</table>
You might have to restructure your data before looping it through the table.

Remove tables from HTML using jQuery

I've got many chunks of HTML coming into my app which I have no control over. They contain tables for layout, which I want to get rid of. They can be complex and nested.
What I want is to basically extract the HTML content from the tables, so that I can inject that into other templates in the app.
I can use jQuery or plain JS only, no server side trickery.
Does anyone know of a jQuery plugin of good tip that will do the job?
Littm - I mean to extract content from the td tags essentially. I want no trace of table left in the code when it's done. Thanks!
Here's an example of the type of HTML in question. It all comes in via XHR from some ancient application so I have no control over the markup. What I want is to get rid of the tables completely, leaving just the rest of the HTML or other text content.
<table>
<tr><td colspan="4"></td></tr>
<tr>
<td width="1%"></td>
<td width="40%" style="padding-left: 15px">
<p>Your access level: <span>Total</span></p>
</td>
<td width="5%">
<table><tr><td><b>Please note</b></td></tr></table>
</td>
<td width="45%" style="padding-left: 6px" valign="top"><p>your account</p></td>
</tr>
<tr><td colspan="4"> </td></tr>
<tr>
<td width="1%"></td>
<td width="40%" style="padding-left: 15px">
<table>
<tr>
<td align="right">Sort Code: </td>
<td align="center"><strong>22-98-21</strong></td>
</tr>
<tr>
<td align="right">Account Number: </td>
<td><strong>1234959</strong></td>
</tr>
</table>
</td>
<td width="5%"></td>
<td width="45%" style="padding-left: 6px">Your account details for</td>
</tr>
</table>
I've tried;
var data = ""
$("td").each(function(){
data += $(this).html()
});
$("article").append(data);
$("table").remove();
But var data still contains nested td tags. I'm no JS expert so I'm not sure what else to try....
Let's suppose that you have X number of tables.
In order to extract all the content information from these, you could try something like this:
// Array containing all the tables' contents
var content = [];
// For each table...
$("table").each(function() {
// Variable for a table
var tb = [];
$(this).find('tr').each(function() {
// Variable for a row
var tr = [];
$(this).find('td').each(function() {
// We push <td> 's content
tr.push($(this).html());
});
// We push the row's content
tb.push(tr);
});
// We push the table's content
content.push(tb);
});
So for instance, if we have the following 2 tables:
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>A</td>
</tr>
</table>
<table>
<tr>
<td>r1</td>
<td>r2</td>
<td>r3</td>
</tr>
<tr>
<td>rA</td>
<td>rB</td>
</tr>
<tr>
<td>rP</td>
</tr>
</table>
The array content will be something like this:
content = [ [ [1, 2], [A] ] ] , [ [r1, r2, r3], [rA, rB], [rP] ] ]
\_______________/ \______________________________/
1st table 2nd table
and if you want to access the first table, you'll just have to access content[0] for instance.
Now, let's suppose that you have a DIV, with and id my_div, and that you want to output some table content in it.
For example, let's suppose that you only want to have the 1st table only. Then, you would do something like this:
// Note: content[0] = [[1, 2], [A]]
var to_print = "<table>";
for(var i=0; i<content[0].length; i++) {
to_print += "<tr>";
for(var j=0; j<content[0][i].length; j++)
to_print += "<td>"+ content[0][i][j] +"</td>";
to_print += "</tr>";
}
to_print += "</table>";
$("#my_div").html(to_print);
which will give you something like this:
<div id="my_div">
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>A</td>
</tr>
</table>
</div>
Hope this helps.
Edit: You should create a recursive function to do that.
Simply create you function that gets "td"'s as a value:
function searchTexts(td) {
if (td.find("td")) {
searchTexts(td.find("td"));
}
td.each(function(){
data += $(this).html()
$(this).remove(); // remove it for avoiding duplicates
});
}
Then call it passing a jQuery object to the function.

Select random row from table, then remove that row and create a new table with that row?

I found some code that helped me get pretty close. Kudos to daiscog for that! Here is what I'm trying to do. There is a table with rows of entries for a giveaway. I want to be able to click a button and remove that row from the table and and generate a new table on the fly with that random row that was picked form the primary table.
Right now the code below selects a random row and highlights it in dark blue. Which is great. Issue is it also counts the <thead> and <tfoot> as rows in the random pick, ideally it wouldn't. Which isn't a huge deal. But can be once I get working what I'd like to. Issue is right now when the logs of entries gets really long it's hard to keep track of who was picked first.
Any ideas on how to accomplish this via Javascript?
<table id="cp_logs_table" class="widefat" style="background-color:#333;color:#ddd;font-weight:bold;margin:15px;">
<thead><tr><th scope="col">Name [Username]</th><th scope="col">Points</th><th scope="col">Entry Type</th><th scope="col">Time</th></tr></thead>
<tfoot><tr><th scope="col">Name [Username]</th><th scope="col">Points</th><th scope="col">Entry Type</th><th scope="col">Time</th></tr></tfoot>
<tr>
<td title="wolfkin">wolfkin [wolfkin]</td>
<td>- 150</td>
<td>
Lottery Ticket
</td>
<td title="2011-10-14 17:20:29">11 hours ago</td>
</tr><tr>
<td title="dragon290513">dragon290513 [dragon290513]</td>
<td>+ 5</td>
<td>
Video Entry
</td>
<td title="2011-10-14 01:42:30">1 day ago</td>
</tr></table>
<script>
function cplottopickwinner() {
// get all TRs that are descendants of table#cp_logs_table:
var tds = document.getElementById("cp_logs_table").getElementsByTagName("tr");
// get a random int between 0 (inclusive) and tds.length (exclusive)
var rand = Math.floor( Math.random() * tds.length );
// highlight tr at that index
tds[rand].style.backgroundColor = "#375297";
//tds[rand].style.color = "#000";
}
</script>
Pick Random Winner(s)
I modified the function to the code below, but it's not populating the table with anything, but it's still highlighting the table row in blue. I'm sure I'm missing something simple to automatically remove that row and add it to the new table.
function cplottopickwinner() {
// get all TRs that are descendants of table#cp_logs_table:
var tds = document.getElementById("cp_logs_table").getElementsByTagName("tr");
// get a random int between 0 (inclusive) and tds.length (exclusive)
var rand = Math.floor( Math.random() * tds.length );
// highlight tr at that index
tds[rand].style.backgroundColor = "#375297";
//tds[rand].style.color = "#000";
jQuery("#cb_winners").fadeIn("slow");
var html = tds[rand].html();
tds[rand].remove();
jQuery("#winners").append("<tr>"+html+"</tr>");
}
If you have another table to put in the winners,
<table>
<thead><!-- .... --></thead>
<tfoot><!-- .... --></tfoot>
<tbody id="winners"></tbody>
</table>
Then you just have to append the whole <tr> to it, then it will disappear from old table because it is not cloned.
document.getElementById('winners').appendChild(trs[rand]);
http://jsfiddle.net/sMPQS/
I made it using jQuery.. hope it's helpful.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<table id="cp_logs_table" class="widefat" style="background-color:#333;color:#ddd;font-weight:bold;margin:15px;">
<thead><tr><th scope="col">Name [Username]</th><th scope="col">Points</th><th scope="col">Entry Type</th><th scope="col">Time</th></tr></thead>
<tfoot><tr><th scope="col">Name [Username]</th><th scope="col">Points</th><th scope="col">Entry Type</th><th scope="col">Time</th></tr></tfoot>
<tr>
<td title="wolfkin">wolfkin [wolfkin]</td>
<td>- 150</td>
<td>Lottery Ticket</td>
<td title="2011-10-14 17:20:29">11 hours ago</td>
<td><input type='submit' value='MOVE' class='move'></td>
</tr>
<tr>
<td title="dragon290513">dragon290513 [dragon290513]</td>
<td>+ 5</td>
<td>Video Entry</td>
<td title="2011-10-14 01:42:30">1 day ago</td>
<td><input type='submit' value='MOVE' class='move'></td>
</tr>
</table>
<script>
$('.move').click(function(){
var row = $(this).parent('td').parent('tr');
var html = row.html();
row.remove();
$('#winners').append("<tr>"+html+"</tr>");
});
</script>
<table id='winners' ></table>

Categories

Resources