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;
}
}
Related
I have a page called SQLFailover.php that shows a table with two rows. Each row will have a toggle button. The toggle button on the first row will be set to primary and the server name on that row will be determined by a SQL query done earlier in the code. The second row’s toggle will be set to secondary and will get the server name from the same SQL query. When either button is toggled, I need the button to trigger a post to SQLAction.php. That page will call a powershell script that will update server names in a table then be redirected back to SQLFailover.php by using a header() cmd. When the SQLFailover.php is reloaded, the section with the comment “get current primary server and secondary server from SQL Table” will do a query which retrieves the primary and secondary servers to display, which at this point, will have been changed from the powershell that will be added to the SQLAction.php page at a later time. The trouble I am having is that when my current script POSTs to the action page the key => value pairs are undefined. Please help me to understand how this is happening and correct my code. Thank you.
SQLFailover.php
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="portlet-body">
<div class="table-scrollable">
<table class="table table-hover">
<thead>
<tr>
<th class="all"> Location </th>
<th class="all"> Status </th>
</tr>
</thead>
<tbody>
<?php $UserSession = $_SESSION['jigowatt']['username'];?>
<script> var UserSession = '<?=$UserSession?>';</script>
<?php
$env = "CERT";
if (isset($env)) {
if ($env === 'CERT') {
$stageEnvironmentType = "CERT";
$SQLFileName = "AGL_C_ 01\C01,10995";
$serverName = $SQLFileName;
}elseif($env === 'PROD') {
$stageEnvironmentType = "PROD";
$SQLFileName = "AGL_P_ 01\P01,11111";
$serverName = $SQLFileName;
}
//SQLServer Connection
$connectionInfo = array( "Database"=>"master");
$conn = sqlsrv_connect( $serverName, $connectionInfo );
if( $conn === false ) {
die( print_r( sqlsrv_errors(), true));
}else{
//get current primary server and secondary server from SQL Table
$sql = file_get_contents('SQLSelect.sql');
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$conn_current_PrimaryReplica = $row['conn_current_PrimaryReplica'];
$conn_new_PrimaryReplica = $row['conn_new_PrimaryReplica'];
?>
<tr>
<td> <?php echo $conn_current_PrimaryReplica;?> </td>
<td>
<input data-server-name="<?php echo "$conn_new_PrimaryReplica";?>" class="toggle-event" checked type="checkbox" data-toggle="toggle" data-on="Primary" data-onstyle="success" data-off="Secondary" data-offstyle="danger" data-size="small" />
</td>
</tr>
<tr>
<td> <?php echo $conn_new_PrimaryReplica; ?> </td>
<td>
<input data-server-name="<?php echo "$conn_current_PrimaryReplica";?>" class="toggle-event" type="checkbox" data-toggle="toggle" data-on="Primary" data-onstyle="success" data-off="Secondary" data-offstyle="danger" data-size="small" />
</td>
</tr>
<?php
}
sqlsrv_free_stmt($stmt);
}
}
?>
</tbody>
</table>
</div>
</div>
<script>
$(function() {
$('.toggle-event').change(function() {
var serverName = $(this).data('server-name');
var mode = $(this).prop('checked');
var username = '<?=$UserSession?>';
var payload = {
server: serverName,
username: username
};
var form = document.createElement('form');
form.style.visibility = 'hidden';
form.method = 'POST';
form.action = '/SQLAction.php';
for (key in Object.keys(payload)) {
var input = document.createElement('input');
input.name = key;
input.value = payload[key];
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
})
})
</script>
Below is the SQLAction.php page.
<?php
echo "<b>begin POST values</b><br><br>";
foreach ($_POST as $key => $value) {
echo "<tr>";
echo "<td>";
echo $key;
echo "</td>";
echo " : ";
echo "<td>";
echo $value;
echo "</td>";
echo "</tr>";
echo "<br>";
}
echo "<b>end of POST values</b><br><br>";
header('refresh:5; / SQLFailover.php ');
?>
The object key iteration of your code seems not correct (at least it appears to be non-standard) and the values extracted are found to be undefined. (I have tested your code and it generates undefined values)
Please iteration your Object keys thru the Object.keys(obj).forEach construct, with the following syntax:
Object.keys(obj).forEach(key => {
// console.log(key, obj[key]);
});
Hence, for your case , please change the block
for (key in Object.keys(payload)) {
var input = document.createElement('input');
input.name = key;
input.value = payload[key];
form.appendChild(input);
}
to
Object.keys(payload).forEach(key => {
var input = document.createElement('input');
input.name = key;
input.value = payload[key];
form.appendChild(input);
});
The page is now working with a change to the for line in the function.
<script>
$(function() {
$('.toggle-event').change(function() {
var serverName = $(this).data('server-name');
var mode = $(this).prop('checked');
var username = '<?=$UserSession?>';
var payload = {
server: serverName,
mode: mode,
username: username
};
var form = document.createElement('form');
form.style.visibility = 'hidden';
form.method = 'POST';
form.action = 'SNFailover/SQLAction.php';
$.each(Object.keys(payload), function(index, key) {
var input = document.createElement('input');
input.name = key;
input.value = payload[key];
form.appendChild(input)
});
document.body.appendChild(form);
form.submit();
});
})
I have a problem inserting the multiple row from my table to my database. Ill show picture of my UI.
https://i.stack.imgur.com/1okJB.png
There are 5 column that I will insert into my database Barcode,Description and QTY is in the table that I want to insert and the two data is outside the table,or not on the table e.g username and customer_id. Its printed on the other part of my UI.
I tried this ajax code but nothing happen.
$(document).on('click','.Enter',function(e){
var user = [];
var product = [];
var customer = [];
var quantity = [];
$('input .user').each(function(){
user.push($(this).text());
});
$('tableData tr td .barcode').each(function(){
product.push($(this).text());
});
$('select .customer_id').each(function(){
customer.push($(this).text());
});
$('tableData tr td .qty').each(function(){
quantity.push($(this).text());
});
$.ajax({
url:"insert_sales.php",
method:"POST",
data:{user:user, product:product, customer:customer, quantity:quantity},
success: function(data){
alert(user[0]);
},
})
});
This is part of my HTML file.
<input type="hidden" name="user" value="<?php echo $row['username']; ?>" class="user" />
<select class="customer_id" name="customer" style='cursor:pointer'>
<?php
if(mysqli_num_rows($show)>0){
while ($row = mysqli_fetch_array($show)) {
?>
<option value="<?php echo $row['customer_id']; ?>"><?php echo $row['firstname'];?>
</option>
<table id="table2">
<thead>
<tr class='text-center'>
<th>Barcode</th>
<th>Description</th>
<th>Price</th>
<th>Unit</th>
<th>Qty</th>
<th>Sub.Total</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tableData">
</tbody>
</table>
This is my insert_product.php file.
if(isset($_POST['user'])){
$user = $_POST['user'];
$product = $_POST['products'];
$customer = $_POST['customer'];
$quantity = $_POST['quantity'];
$query = '';
for($count = 0; $count<count($user); $count++){
$user_clean = mysqli_real_escape_string($db, $user[$count]);
$product_clean = mysqli_real_escape_string($db, $user[$count]);
$customer_clean = mysqli_real_escape_string($db, $user[$count]);
$quantity_clean = mysqli_real_escape_string($db, $user[$count]);
if($user_clean != '' && $product_clean != '' && $customer_clean != '' && $quantity!= ''){
$query = "INSERT INTO sales(username,product_id,customer_id,quantity) VALUES('$user_clean',$product_clean,$customer_clean,$quantity_clean)";
}
}
if ($query != ''){
if(mysqli_multi_query($db,$query)){
echo "Item Inserted"
}else{
echo "Error";
}
}else{
echo "No Product";
}
}
Hope someone can help me about this one. I'd put an alert in ajax to know if the it passes to the code. There's no insert happening even though it passes to the alert.
I have number of rows in investment table. I need to retrieve all of them and send them back using json_encode.
Here is my code
$project_code = $_GET['id'];
$sql = "select * from investment where project_code = '$project_code'";
$result = mysql_query($sql);
while($x1 = mysql_fetch_array($result))
{ $detail = $x1['detail'];
$sector = $x1['sector'];
}
echo json_encode(array(
'a' => $detail,
'b' => $sector
));
In javascript I wrote following script:
$('#myHref').change(function(){
var value = $('#myHref').val();
$.get('display_acc.php',{id:value},function(data)
{
data = JSON.parse(data);
$( '#a' ).html(data.a);
$( '#b' ).html(data.b);
});
});
Here my problem is that it returns only data of last rows. I want to receive data of all rows.
I have to display id a and b here
I use table to display it.
Thank in advance
This should do the trick:
--EDIT after OP explanation--
PHP
$project_code = (int)$_GET['id']; //better put (int) before to avoid SQL Injection
$sql = "select detail, sector from investment where project_code = '$project_code'"; //better to maintain if you set only the fields you will use
$result = mysql_query($sql);
$return = array('detail'=> array(), 'sector' => array()); //here you can put empty return array or set detail and sector key. Your choice will have impact in your front-end
$return['my_extra_var' ] = $my_extra_var;
$i = 0;
while($x1 = mysql_fetch_array($result))
{
$return['table'][$i]['detail'] = $x1['detail'];
$return['table'][$i]['sector'] = $x1['sector'];
$i++;
}
echo json_encode($return);
Javascript
... your ajax request ...
data = JSON.parse(data);
var tableData = data.table;
$.each(tableData, function(index, value) {
$('#tableData').append('<tr><td>'+value.detail+'</td><td>'+value.sector+'</td></tr>'); //append row to tbody
});
HTML
<table>
<thead>
<th>Details</th>
<th>Sector of Investment</th>
</thead>
<tbody id="tableData">
</tbody>
</table>
You need arrays in your loop
$project_code = $_GET['id'];
$sql = "select * from investment where project_code = '$project_code'";
$result = mysql_query($sql);
$cnt=0;
while($x1 = mysql_fetch_array($result))
{ $detail[$cnt] = $x1['detail'];
$sector[$cnt] = $x1['sector'];
$cnt++;
}
echo json_encode(array(
'a' => $detail,
'b' => $sector
));
and in javascript loop over the result
It looks like you are not accumulating the two elements. Try something like this:
array_push(your_array_name, $detail, $sector);
Then encode your array when all done.
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();
}
});
}
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.