I am trying to delete a row based on a table's cell value.
In my HTML page I have a simple search function. It would send the values in the text box to the database through ajax then PHP and then PHP would create a table dynamically based on what is in the database.
I have tried to check a the cell in the table for a specific value so that if it is true then the current row would be removed, the function name is checkMatch(). However it doesn't work.
This is the button in the HTML, the rest of the HTML is just a text box and drop down box:
<input type="button" id="device_search" value="Search" onclick="searchDevice(); checkMatch();"></input>
This is the function in the external JavaScript file:
function checkMatch()
{
var row = document.getElementById("thisRow");
var cell = Row.getElementById("match");
if(cell[0].innerText = "0%")
{
row.deleteRow(this);
}
}
And here's the creating of table in the PHP:
if($num_row)
{
echo "<table id=\"myTable\" border=\"1\">";
echo "<tr>
<th>Board ID</th>
<th>Tester Name</th>
<th>Board Name</th>
<th>Current Slot</th>
<th>Log Created</th>
<th>Required Slot</th>
<th>Match</th>
</tr>";
while($row = mysql_fetch_assoc($result))
{
$board_id = $row['board_id'];
$tester_name = $row['tester_name'];
$board_name = $row['board_name'];
$config = $row['config'];
$log_created = $row['log_created'];
$req_config = $row['configuration'];
$exploded = explode(",", $req_config);
$count = count($exploded);
$j = 0;
foreach($exploded as $value)
{
$number = strlen($value);
$arr = str_split($value, $number);
if(in_array($config, $arr))
{
$j += 1;
$j /= ($count / 100);
echo $j;
}
else
{
}
}
echo "<tr id = \"thisRow\">
<td>$board_id</td>
<td>$tester_name</td>
<td>$board_name</td>
<td>$config</td>
<td>$log_created</td>
<td>$req_config</td>
<td id = \"match\">$j%</td>
</tr>";
}
echo "</table>";
}
The column that I'm checking on is the last column which is the Match column. My idea is to remove that current row whenever the cell value of Match is 0%. I can't seem to find what's wrong with my codes, I'm not really good at manipulating DOM elements either so there must be some mistake. Any help on this? Or are there others ways, through PHP etc?
Note: I am not trying to delete the row from database. I just want to remove the row whenever Match is 0%.
EDIT, codes for searchDevice() in external js file:
function searchDevice()
{
var device_name = $("#device_name").val();
var tester_type = $("#tester_type").val();
var page = "database.php";
if(device_name==""||tester_type=="")
{
alert("Please do not leave any blanks.");
}
else
{
$.post(page, {
device_name : device_name,
tester_type : tester_type,
action : "search"
}, function(data) {
$("div#display_board").html(data);
checkMatch();
});
}
}
Currently my table does display with all the right values, but it doesn't remove the rows with 0%.
checkMatch() should be called at ajax success callback
id should be unique with in HTML document
PHP
// use `class` instead of `id`
echo "<tr class=\"thisRow\">
<td>$board_id</td>
<td>$tester_name</td>
<td>$board_name</td>
<td>$config</td>
<td>$log_created</td>
<td>$req_config</td>
<td class=\"match\">$j%</td>
</tr>";
Javascript
function checkMatch()
{
$("#myTable tr.thisRow").each(function() {
var thisRow = $(this);
var match = thisRow.find(".match");
// note the `==` operator
if(match.text() == "0%") {
thisRow.hide();
// OR thisRow.remove();
}
});
}
Related
I have the below PHP script which is run via a command prompt and it works fine if there is only one table on a page but if I have two tables on a page it will just try and pull the first one out, is there a way I can say in certain instances to ignore the first table and process the second table only?
I have no control of the HTML so can't target the table by using an ID.
HTML
<html>
</head>
...
</head>
<body>
<table>
<tr>
<th>Problem Table</th>
</tr>
<tr>
<td>Annoying table in the way!</td>
</tr>
</table>
<hr/>
<table>
<tr>
<th>ID</th>
<th>Asset</th>
</tr>
<tr>
<td>34234234</td>
<td>Website3</td>
</tr>
<tr>
<td>34234234</td>
<td>Website4</td>
</tr>
</table>
</body>
</html>
PHP
$dom = new DOMDocument();
$html = $dom->loadHTMLFile($url);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(0)->getElementsByTagName('tr');
$cols = $rows->item(0)->getElementsByTagName('th');
$row_headers = null;
foreach($cols AS $node) {
$row_headers[] = $node->nodeValue;
}
$table = array();
$rows = $tables->item(0)->getElementsByTagName('tr');
foreach($rows AS $row) {
$cols = $row->getElementsByTagName('td');
$row = array();
$i = 0;
foreach($cols AS $node) {
if ($row_headers != null) {
$row[$row_headers[$i]] = $node->nodeValue;
}
$i++;
}
if (!empty($row)) {
$table[] = $row;
}
}
I agree with #GCC404 that you should target your elements better using an ID or class as this could easily lead to mistakes.
However, if you specifically want to target the last table, you just need to replace the 0 with the number of items found minus 1:
$rows = $tables->item( $tables->length - 1 )->getElementsByTagName('tr');
// etc.
When using getElementsByTagName(), you can specify an index with DOMNodelist::item.
This should probably only be used when you have no control over the source HTML or you are sure there will always be two tables, but I'd recommend just setting an id/class for each table if you are in control of the HTML.
$dom = new DOMDocument();
$html = $dom->loadHTMLFile($url);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(1)->getElementsByTagName('tr');
$cols = $rows->item(1)->getElementsByTagName('th');
$row_headers = null;
foreach($cols AS $node) {
$row_headers[] = $node->nodeValue;
}
$table = array();
$rows = $tables->item(1)->getElementsByTagName('tr');
foreach($rows AS $row) {
$cols = $row->getElementsByTagName('td');
$row = array();
$i = 0;
foreach($cols AS $node) {
if ($row_headers != null) {
$row[$row_headers[$i]] = $node->nodeValue;
}
$i++;
}
if (!empty($row)) {
$table[] = $row;
}
}
I have a mysql table with the name of a team in one column (club_name) and an id on another (club_id).
Every team has a logo named with their respective id .png.
Then I have a text input where the user can write the name of a team. There is a jQuery function that shows the possible team names found in the database according to what the user is typing so that it can autocomplete. Once the user selects one of the options the focus moves out of the text input. At this point, I would like the image to change to the logo corresponding to the team. When the text input is empty or the name does not match any team in the database the image should be 0.png
How can I achieve this? My code so far is below:
EDIT:
I have three problems right now:
The method suggested to store the club id in the json object is only
returning the first row of the table.
The method is below (although it only returns one row of the table it does work, the image changes to the appropriate one - I ran a little test by replacing 'thisclub' with the name of the club):
<script>
var clublist = [
<?php
$search_clubs = " SELECT club_id, club_name FROM clubs ORDER BY club_id DESC";
$result_clubs = mysql_query($search_clubs);
echo json_encode(mysql_fetch_assoc($result_clubs)); //only returns one row
?>
];
</script>
Using another method I was able to have all the rows in the json object but this one did not work when I ran the same test by replacing 'thisclub' with the name of one club):
<script>
var clublist = [
<?php
$clubid = array(); $clubname = array();
$search_clubs = mysql_query(" SELECT club_id, club_name FROM clubs ");
while($row = mysql_fetch_array($search_clubs)) {
$clubid[] = $row["club_id"]; // or smth like $row["video_title"] for title
$clubname[] = $row["club_name"];
}
$res = array($clubid, $clubname);
echo json_encode($res);
?>
];
</script>
The second problem is I don't know what to replace 'thisclub' with.
In other words, how to get the value returned by the function.
I am now using two vars - one to store the name of the clubs only, for the original function, the other one for the name of the clubs and respective id, for the function that makes the image change. This is because I don't know what changes to make in the original function so that it searches for the names in the new var (which contains club_id too)
The full code is below.
<img id="team-logo" src="logos/0.png"/>
<input type="text" class="club-name" name="home" autocomplete="off"/>
<script>
var clubs = [
<?php
$search_clubs = " SELECT club_name FROM clubs ";
$result_clubs = mysql_query($search_clubs);
while($clubs = mysql_fetch_array($result_clubs)) {
$club_name = $clubs['club_name'];
echo '"'.$club_name.'",';
}
?>
];
var clublist = [
<?php
$search_clubs = " SELECT club_id, club_name FROM clubs ORDER BY club_id DESC";
$result_clubs = mysql_query($search_clubs);
echo json_encode(mysql_fetch_assoc($result_clubs)); //only returns one row
?>
];
$(".club-name").autocomplete({
source: clubs,
autoFocus: true,
minLength: 2,
delay: 0,
close: function(event, ui){
if (!event.keyCode || event.keyCode === 13){
$(this).parents('form').find('.club-name').filter(function (){
return $(this).val() === '';
}).first().focus();
//
}
clubid = "";
$.each(clublist, function (i, elem) {
if (elem.club_name === thisclub) {
clubid = elem.club_id;
$("#team-logo").attr("src", clubid+".png");
}
});
if(clubid == "") {
// show default image
$("#team-logo").attr("src", "0.png");
}
//$("#team-logo").attr("src", clubs+".png");
}
});
</script>
I would get the club_id from the original SELECT that you do.
Then on the focus out you can do something along the lines of:
$("#team-logo").attr("src", club_id+".png");
And that will set the image src to the new image.
Edit:
To expand a bit, storing the results of the sql query in a json object using json_encode() would allow you to use something like:
<script>
var clublist = [
<?php
$search_clubs = " SELECT club_id, club_name FROM clubs ";
$result_clubs = mysql_query($search_clubs);
echo json_encode(mysql_fetch_array($result_clubs));
?>
];
</script>
// Run the following code inside the focus.out section and set thisclub to the returned clubname
clubid = "";
$.each(clublist, function (i, elem) {
if (elem.club_name === thisclub) {
clubid = elem.club_id;
$("#team-logo").attr("src", clubid+".png");
}
});
if(clubid == "") {
// show default image
$("#team-logo").attr("src", "0.png");
}
Second Edit (Complete working example):
I've tested the following and I believe it includes everything you're looking for. The problem seemed to be in the formatting of the php array when passed to json encode. Pay close attention to the HTML changes.
$sql = " SELECT club_id, club_name FROM clubs ORDER BY club_id DESC";
$result_clubs = mysql_query($sql);
if (!$result_clubs) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
$clubs = array();
while($row = mysql_fetch_assoc($result_clubs)){
$clubs[] = array('club_id' => $row['club_id'], 'club_name' => $row['club_name']);
}
?>
<img id="team-logo" src="logos/0.png"/>
<input id="clubname" type="text" class="club-name" name="home" autocomplete="off"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript">
var clubs = [
<?php
foreach($clubs as $club) {
$club_name = $club['club_name'];
echo '"'.$club_name.'",';
}
?>
];
var clublist = <?php echo json_encode($clubs)?>; //only returns one row
$(".club-name").autocomplete({
source: clubs,
autoFocus: true,
minLength: 2,
delay: 0,
close: function(event, ui){
if (!event.keyCode || event.keyCode === 13){
$(this).parents('form').find('.club-name').filter(function (){
return $(this).val() === '';
}).first().focus();
//
}
clubid = "";
for(var i = 0; i < clublist.length; i++) {
obj = clublist[i];
if(obj.club_name == $("#clubname").val()){
clubid = obj.club_id;
$("#team-logo").attr("src", clubid+".png");
}
}
if(clubid == "") {
// show default image
$("#team-logo").attr("src", "0.png");
}
}
});
</script>
I get from my database a PHP array that looks like this:
$dbResult= array([0]=>array([a]=>1 [b]=>1 [c]=>1)
[1]=>array([a]=>2 [b]=>2 [c]=>2)
[3]=>array([a]=>3 [b]=>3 [c]=>3)
)
And in my HTML Ihave a div with the id class.
What i would like to do is create a table with that PHParray using JavaScript but only when label id="labletocreatetable" is clicked, the table should look like this
a b c
1 1 1
2 2 2
3 3 3
i know that i should use json_encode but when i do that the result looks like this and im not pretty sure how to use it
[{"a":"1","b":"1","c":"1"},
{"a":"2","b":"2","c":"2"},
{"a":"3","b":"3","c":"3"}]
i am not sure what you wanted but this might helps you
<?php
$dbResult= array(0=>array('a'=>1, 'b'=>1, 'c'=>1),
1=>array('a'=>2, 'b'=>2, 'c'=>2),
3=>array('a'=>3, 'b'=>3, 'c'=>3)
);
echo '<table border=1><tr><td>';
echo implode('<td>',array_keys($dbResult[0]));
foreach($dbResult as $k =>$v){
echo '<tr>';
foreach ($v as $k1 => $v1) {
echo '<td>'.$v1.'</td>';
}
echo '</tr>';
}
output
Try this:
var arr = [
{"a":"1","b":"1","c":"1"},
{"a":"2","b":"2","c":"2"},
{"a":"3","b":"3","c":"3"}
], cols = [];
// Elements to clone:
var tr = document.createElement('tr'),
td = document.createElement('td');
function addCell(text, row) {
var cell = td.cloneNode(false);
cell.appendChild(document.createTextNode(text));
row.appendChild(cell);
}
// Body:
var tbody = document.createElement('tbody')
for(var i=0; i<arr.length; ++i) {
var row = tr.cloneNode(false);
// Iterate known columns
for(var j=0; j<cols.length; ++j) {
addCell(arr[i][cols[j]], row);
delete arr[i][cols[j]]; // Warning: will erase data
}
// Find new columns
for(var j in arr[i]) {
if(arr[i].hasOwnProperty(j)) {
cols.push(j);
addCell(arr[i][j], row);
}
}
tbody.appendChild(row);
}
// Head:
var thead = document.createElement('thead'),
row = tr.cloneNode(false);
for(var i=0; i<cols.length; ++i) {
addCell(cols[i], row);
}
thead.appendChild(row);
// Table:
var table = document.createElement('table');
table.appendChild(thead);
table.appendChild(tbody);
document.body.appendChild(table);
Demo.
The problem with your structure is that we don't know the columns beforehand, and that for..in iterates objects in arbitrary order.
Then, I created an array to store the columns in order, and for each row I first iterate those columns, and then iterate remaining ones (in any order) and push them to the array.
If you don't want to erase data, here is an alternative demo.
You need to use the ajax for this purpose. I have written the steps.
1) a.html
--Include jQuery library--
<div id="div1"></div> <!-- DIV WHERE THE TABLE CONTENT WILL BE LOADED -->
<label id="labletocreatetable" onclick="createTheTable()">Click to create the table</label>
<script>
function createTheTable() {
$.ajax({
url:"<Path to >get_the_content.php",
success:function(result){
$("#div1").html(result); // DIV WHERE THE CONTENT WILL BE LOADED
}
});
}
</script>
2) get_the_content.php
<?php $dbResult= array(
0=>array('a'=>1, 'b'=>1, 'c'=>1),
1=>array('a'=>2, 'b'=>2, 'c'=>2),
3=>array('a'=>3, 'b'=>3, 'c'=>3),
);
$myKeys = array_keys($dbResult[0]); //Will return you a,b,c as numeric array. ?>
<table border="1" width="30%">
<tr> <!-- FOR THE TABLE HEADER a,b and c -->
<th> <?php echo $myKeys[0]; ?> </th>
<th> <?php echo $myKeys[1]; ?> </th>
<th> <?php echo $myKeys[2]; ?> </th>
</tr>
<?php foreach($dbResult as $key=>$rows) { // for the table's content ?>
<tr>
<td><?php echo $rows[$myKeys[0]]; ?></td>
<td><?php echo $rows[$myKeys[1]]; ?></td>
<td><?php echo $rows[$myKeys[2]]; ?></td>
</tr>
<?php } ?>
</table>
<!-- YOU NEEDN'T TO echo THE TABLE it will be automatically returned to ajax. -->
Try this (jsFiddle):
// Set this with PHP
var data = [{"a":"1","b":"1","c":"1"},
{"a":"2","b":"2","c":"2"},
{"a":"3","b":"3","c":"3"}];
// Set this to the target html element
var target = document.getElementsByTagName('body')[0];
// Create table and add header
var table = createElement('table');
table.appendChild( addRow( Object.keys(data[0]) ) );
// Add rows
for (var r=0; r<data.length; r++) {
table.appendChild( addRow( data[r] ) );
}
// Append table to target
target.appendChild(table);
// Helper functions
function createElement(type, content) {
var e = document.createElement(type);
if (typeof content !== "undefined") {
if (typeof content === "string") {
content = document.createTextNode(content);
}
e.appendChild(content);
}
return e;
}
function addRow( rowData ) {
var tr = createElement('tr');
for (var key in rowData) {
tr.appendChild( createElement('td', rowData[key]) );
}
return tr;
}
All you need to do is set data and target.
I am trying to grab some text from a MyBB forum's exported messages. The file is a CSV file.
if (($handle = fopen("test.csv", "r")) === FALSE) {
exit("Couldn't load CSV");
}
fgetcsv($handle);
$messages = array();
$i = 0;
while($data = fgetcsv($handle)){
if(count($data) == 7){
$messages[$i]['date'] = $data[0] + "," + $data[1];
$messages[$i]['folder'] = $data[2];
$messages[$i]['subject'] = $data[3];
$messages[$i]['receiver'] = $data[4];
$messages[$i]['sender'] = $data[5];
$messages[$i]['message'] = str_replace("\'", "'", $data[6]);
}else{
$messages[$i]['date'] = $data[0];
$messages[$i]['folder'] = $data[1];
$messages[$i]['subject'] = $data[2];
$messages[$i]['receiver'] = $data[3];
$messages[$i]['sender'] = $data[4];
$messages[$i]['message'] = str_replace("\'", "'", $data[5]);
}
$i++;
}
I gave each tr and th tag (th includes the name of the sender and tr includes the message) a class with a number. First message is 0, second is 1, third is 2 and so on. I load the message in PHP like this:
$messages[0]['message'])
Where 0 is the first message. I want it to be like when I click on first message, it loads the first. When I click the second, it loads the second message. You get the idea.
My jQuery is as following:
$("td, th").on("click", function() {
var message = $(this).attr("class");
$("#message").text("<?= preg_replace("/\r|\n/", "", $messages[0]['message']) ?>");
});
I use preg_replace to get it all into one line.
Foreach loop
<table>
foreach($messages as $i => $message) {
echo <<<EOL
<tr>
<th class="$i"> {$message['sender']} </th>
</tr>
<tr>
<td class="$i"> {$message['message']} </td>
</tr>
EOL;
}
</table>
So to sum up: I want to display the message when I click the message in the table, but I am not sure what would be the best approach to do that.
$("td, th").on("click", function() {
var messageId = $(this).attr("class");
$.ajax({
url: "test.php",
type: "post",
data: messageId,
success: function(returnedVal){
$("#result").html(returnedVal);
},
error:function(){
$("#result").html('There is an error');
}
});
});
returnedVal is the value returned by your test.php.
For example, you can return your message.
Then you display it in $("#result") or wherever you want :)
I have a table that gets created using php drawing straight out of a database. Each td is editable and, when the mouse is clicked elsewhere, the new data is sent to the database and updated dynamically through .ajax(). That all works flawless. It does so through the data-fields of each td. They correspond with the field name in the database so the query has the proper WHERE clause.
Now, I have an ADD button that creates a new row of data that is also editable and can be edited and saved in the same manner. Currently I can add a row. I am trying to create an array of the data-fields from the first row of td so I can then add those to the newly created td during their creation loop. I am only able to get the data-field of the first and/or second td, though, not the entire row as I am intending. How, given the code I have, can I do that? Is it even possible with the configuration that I have? Thanks.
<script type="text/javascript">
/* Add a new table row to the bottom of the table */
$(document).ready(function() {
$(".add").click(function() {
$("#table").each(function() {
//create array
/* $('.edit_tr:last').find('.edit_td').each(function() {
var fieldArray = [];
fieldArray.push($('.edit_tr:last').find('.edit_td').attr('data-field'));
}); */
var fieldArray = [];
// fieldArray.push($('.edit_tr:last').find('.edit_td').last().attr('data-field'));
var $table = $(this);
// var field = $('.edit_tr').find('td:last').attr('data-field');
var id=$('#table tr:last').attr('id');
var $tr = $("#table").children('tr');
// var $th = $(this).closest('table').find('th').eq($(this).index());
// Number of td's in the last table row
var n = $('tr:last td', this).length;
var tds = '<tr class="edit_tr" id="' + id++ + '">';
// array
currentDataField = $('.edit_tr:first').find('.edit_td').first().attr('data-field');
console.log(currentDataField);
for (var i = 0; i < n; i++) {
fieldArray.push(currentDataField);
currentDataField = $('.edit_tr:first').find('.edit_td [data-field=' + currentDataField + ']').next().attr('data-field');
// currentDataField = $('.edit_tr').find('.edit_td').nextAll().attr('data-field');
}
console.log('fieldArray ' + fieldArray);
// console.log(field);
for (var i = 0; i < n; i++) {
tds += '<td class="edit_td"><input type="text" class="editbox" id="' +
id + '" data-field="' + fieldArray[i] + '"/> </td>';
console.log('fieldArray loop ' + fieldArray[i]);
}
tds += '</tr>';
// console.log(tds);
if ($('tbody', this).length > 0) {
$('tbody', this).append(tds);
}
else {
$(this).append(tds);
}
});
});
});
</script>
PHP code for table creation:
public function displayTable($table)
{
//connect to DB
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
echo "<table id='table' border='1'>"; //start an HTML table
$dbtable = $table;
$fields =array();
$result = mysqli_query($con, "SHOW COLUMNS FROM ".$dbtable);
//fill fields array with fields from table in database
while ($x = mysqli_fetch_assoc($result))
{
$fields[] = $x['Field'];
}
$fieldsnum = count($fields); //number of fields in array
//create table header from dbtable fields
foreach ($fields as $f)
{
echo "<th>".$f."</th>";
}
//create table rows from dbtable rows
$result = mysqli_query($con, "SELECT * FROM ".$dbtable);
while ($row = mysqli_fetch_array($result))
{
$rowid = $row[$fields[0]];
echo "<tr class='edit_tr' id='".$rowid."'>";
foreach ($fields as $f)
{
echo "<td class='edit_td' data-field='".$f."'><span id='".$rowid."' class='text'>".$row[$f]."</span>
<input type='text' value='".$row[$f]."' class='editbox' id='".$rowid."' data-field='".$f."'/> </td>";
}
$rowid++;
echo "</tr>";
}
echo "</table>"; //close the HTML table
$recordid = $rowid;
//close connection
mysqli_close($con);
}
Okay, there's a lot of code in there (and I'm not a PHP user, so I had to give it my best shot at testing out on some sample HTML :D ), so here's what I think will get you past the issue that you are having with the data-field values, but I'll stop there:
<script type="text/javascript">
$(document).ready(function() {
/* Add a new table row to the bottom of the table */
$(".add").click(function() {
var fieldArray = [];
var $table = $("#table");
var $lastRow = $table.find("tr:last");
var $dataFields = $lastRow.find("td");
$dataFields.each(function() {
fieldArray.push($(this).attr("data-field"));
});
. . . .
That should get you your fieldArray value, populated with the data-field values from all of the td elements in the last row of the table.
A couple of side notes:
again, my PHP isn't great, but it doesn't look like you are creating your th values inside a row in the table . . . they really should be wrapped in a tr element
you could get the $dataFields value in one line of code (several ways, actually), but splitting it up into three lines, like I did, is actually faster (and a little easier to read, in my opinion :) ).
If you set data attributes via jQuery function .data(), then these attributes are hidden attributes and cannot be found from $('.item [data-...]').
if you need to set string or number to data attribute, then set it with .attr('data-NAME', value) function
You can find all elements without searching data attribute and then filter elements with function jQuery.map()