not able to retrieve direct child elements using Simple HTML DOM - php

I have an html table like this
<table>
<tbody>
<tr>
<td><table>
<tbody>
<tr class="prdLi">
<td rowspan="2" class="prdNo"><span>310.</span></td>
<td colspan="2" class="prdDe" rowspan="2"><span>Pepsi</span></td>
</tr>
<tr class="prdLi">
<td class="prdAc"><span> 1.5L</span></td>
<td><span> </span></td>
</tr>
</tbody>
</table></td>
</tr>
</tbody>
</table>
the table is saved as $html
I want to select the child elements of the class .prdLi
I tried like this:
foreach($html->find('tr.prdLi') as $foo){
echo $foo;
}
the output that i get is like this
<span>310.</span>
<span>Pepsi</span
.
.
.
but what i actually want to get is the code with the parent element td.like this:
<td rowspan="2" class="prdNo"><span>310.</span></td>
<td colspan="2" class="prdDe" rowspan="2"><span>Pepsi</span></td>
.
.
.
please help me

Since Simple HTML DOM Parser supports CSS like selectors, you can use 'tr.prdLi td' to specify all td elements which are children of tr with class prdLi. The following should provide what you are looking for:
$htmlstr = <<<EOD
<table>
<tbody>
<tr>
<td><table>
<tbody>
<tr class="prdLi">
<td rowspan="2" class="prdNo"><span>310.</span></td>
<td colspan="2" class="prdDe" rowspan="2"><span>Pepsi</span></td>
</tr>
<tr class="prdLi">
<td class="prdAc"><span> 1.5L</span></td>
<td><span> </span></td>
</tr>
</tbody>
</table></td>
</tr>
</tbody>
</table>
EOD;
$html = str_get_html($htmlstr);
foreach ($html->find('tr.prdLi td') as $foo) {
echo $foo . "\n";
}
Note that find() is called on the main simple_html_dom-element. In your example, the result was already limited by a previous find().

What andy says is correct, but the css for direct child is > *, therefore:
foreach($html->find('tr.prdLi > *') as $foo){
echo $foo . "\n";
}

Related

Print HTML dynamically on a page via PHP based on Condition

I want to print a section of a table if the data is available in JSON file for it. And if the data is not there and it shouldn't do anything.
So, far what I am doing is as below. Checking is the account_type is parent and then generate the table rows with corresponding data.
<?php
$str = file_get_contents('test.json');
$json = json_decode($str, true);
$parent= strtr('<tr>
<td colspan="2" style="color:#263a80;font-size:19px;padding-bottom:20px;padding-top:20px">Parent Information</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">First Name</td>
<td>#fname</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Last Name</td>
<td>#lname</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Mobile Number</td>
<td>#mobile</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Email</td>
<td><a #email target="_blank" rel="noreferrer">#email</a></td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Country</td>
<td>#country</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">State</td>
<td>#state</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">City</td>
<td>#city</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Postal Code</td>
<td>#pcode</td>
</tr>
<tr>
<td style="width:30%;font-weight:700;padding-bottom:10px">Full Home Address</td>
<td>#address</td>
</tr>', ["#fname"=>$json["json"]["register_session_1"]["first_name"],
"#lname"=>$json["json"]["register_session_1"]["last_name"],
"#mobile"=>$json["json"]["register_session_1"]["mobile"],
"#email"=>$json["json"]["register_session_1"]["email"],
"#country"=>$json["json"]["register_session_1"]["country"],
"#state"=>$json["json"]["register_session_1"]["state_online"],
"#city"=>$json["json"]["register_session_1"]["city"],
"#pcode"=>$json["json"]["register_session_1"]["postal_code"],
"#address"=>$json["json"]["register_session_1"]["address"]
]);
if ($json["json"]["register_session_1"]["account_type"]==="parent"){
echo $parent;
}
else {
echo "hahahah";
}
?>
Problem is that it printing the table data anyway. I don't know what I am doing wrong. The if-else condition is not working.
I have this code and I can't seem to figure out why. I have added this code in between the <table></table> tag.

how would i remove some portion of <tr><td> from a table in php?

this is my table -
<table>
<tr>
<td>ABC</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
and I want to remove this one table row:
<tr>
<td> </td>
</tr>
my expected output is:
<table>
<tr>
<td>ABC</td>
</tr>
</table>
is it possible??please help me
As you have tagged your question with the tag php i would recommend using a regular expression.
The pattern \s*<tr>\s*<td> <\/td>\s*<\/tr> will find the tr with an empty ( ) td.
To test and look into the regex you can have a look here: https://regex101.com/r/ax6Xdg/1
Put together this will look something like this:
$table = "<table>
<tr>
<td>ABC</td>
</tr>
<tr>
<td> </td>
</tr>
</table>";
$pattern = "/\s*<tr>\s*<td> <\/td>\s*<\/tr>/";
var_dump( preg_replace( $pattern , "" , $table ) );
This will output something very simmilar to this:
string '<table>
<tr>
<td>ABC</td>
</tr>
</table>' (length=60)
You can do this by using JQuery function .remove(). You can look it up here
Edit: If you want to locate that specific tag, you can do that by using .next()read here, .find() read here,.parent()read here, .children read here
Just add id to your table :
<table id="tableid">
<tr>
<td>ABC</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
This script find , if found then remove !
$('#tableid tr').each(function() {
if ($(this).find('td').html()==' ') $(this).remove();
});
If you want to find some text and then remove then replace html() with text()
$('#tableid tr').each(function() {
if ($(this).find('td').text()=='ABC') $(this).remove();
});
You should try this:
<table>
<tr id="abc>
<td>ABC</td>
</tr>
<tr id="remove">
<td> </td>
</tr>
<script>
$('#remove').remove();
</script>
When rendering the table, add a unique class for the rows you wish to delete. Lets say the class is: _rowToDelete, and then using jQuery, remove all the rows that have this class.
In the below example, when you click on the button the rows are being removed, so you can see the changes. But you can do the same on page load if you wish so.
$(function() {
$("#removeBtn").click(function() {
$("._rowToDelete").remove() ;
});
}) ;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ABC 1</td>
</tr>
<tr class="_rowToDelete">
<td> </td>
</tr>
<tr>
<td>ABC 2</td>
</tr>
<tr class="_rowToDelete">
<td> </td>
</tr>
<tr>
<td>ABC 3</td>
</tr>
<tr class="_rowToDelete">
<td> </td>
</tr>
</table>
Remove

mixing html code with php code

I am trying to use tcpdf library to generate pdf. I have a php file which contains variables like name,company name etc. But for displaying the products I am passing the array to php. Now I want to display each element of array in a table row for that I have to write the php code but somehow I am having problem mixing PHP code with html code.Here is the part whihch contains the problem
$html .= '<br><br>
<table border="1" cellpadding="5">
<tr>
<td colspan="3">Invoice # {invoice_ref_id}</td>
</tr>
<tr>
<td><b>Product</b></td>
<td><b>Quantity</b></td>
<td align="right"><b>Amount (Rs.)</b></td>
</tr>'.
foreach($item as products): .' //This part contains error
<tr>
<td>'echo products['item']'</td>
<td>'echo products['quantity']'</td>
<td align="right">75</td>
</tr>
<tr>
<td colspan="3" align="right"><b>Total: 375</b></td>
</tr>'
endforeach;
'</table>';
$html .= '<br><br>Some more text can come here...';
Instead of concatenating your HTML in a string that you will then need to echo, I would go to something like this :
<br><br>
<table border="1" cellpadding="5">
<tr>
<td colspan="3">Invoice # {invoice_ref_id}</td>
</tr>
<tr>
<td><b>Product</b></td>
<td><b>Quantity</b></td>
<td align="right"><b>Amount (Rs.)</b></td>
</tr>
<?php foreach($item as products){ ?>
<tr>
<td><?php echo products['item'] ?></td>
<td><?php echo products['quantity'] ?></td>
<td align="right">75</td>
</tr>
<tr>
<td colspan="3" align="right"><b>Total: 375</b></td>
</tr>
<?php> } //ending the foreach ?>
</table>
<br><br>Some more text can come here...
Notice how even here HTML code is still correctly highlighted? It will probably be the same in your editor of choice. I find it much more readable, and you even avoid possible character escaping issues.
NOTE : I didn't fix your HTML, but there are several bad practices in it regarding semantics or even use of obsolete/deprecated tags. Here are a few:
Don't use anything changing layout in your HTML, this is what CSS are for. For example, don't use border or cellpadding attributes on your table, use table {border: 1px solid #ccc;} (you can of course change color, that's an example) and table td {padding: 5px;} instead.
Semantic best practices also imply not using <br> tag. Better define top or bottom margins to put some space between elements. (I must admit that's probably the only example where I value ease over semantic and sometimes use it myself though)
<b> tag should be use only in very specific cases, cfr this article. In this specific case you can achieve the same effect (bold text) by using font-weight: bold on the desired cells, either by giving them a specific CSS class, either by targetting them with a CSS selector like for example : tr td:nth-child(3) {font-weight: bold;}}
similarily, don't use align attribute, same thing, target the desired cell and use CSS property text-align: right; instead.
You can't continue the html with a concatenation straight after the foreach. You have to do $html .= again.
This
</tr>'.
foreach($item as products): .' //This part contains error
<tr>
should be this
</tr>';
foreach($item as products): $html .= ' //This part contains error
<tr>
The same goes at the end of the foreach:
</tr>';
endforeach;
$html .= '</table>';
You are doing it wrong way. This should work -
$html .= '<br><br>
<table border="1" cellpadding="5">
<tr>
<td colspan="3">Invoice # {invoice_ref_id}</td>
</tr>
<tr>
<td><b>Product</b></td>
<td><b>Quantity</b></td>
<td align="right"><b>Amount (Rs.)</b></td>
</tr>';
foreach($item as products) { //This part contains error
$html .= '<tr>
<td>'. products['item']. '</td>
<td>'. products['quantity']. '</td>
<td align="right">75</td>
........ ';
}
$html .= '</table>';
$html .= '<br><br>Some more text can come here...';
thie right way of doing something like this
$html .= '<br><br>
<table border="1" cellpadding="5">
<tr>
<td colspan="3">Invoice # {invoice_ref_id}</td>
</tr>
<tr>
<td><b>Product</b></td>
<td><b>Quantity</b></td>
<td align="right"><b>Amount (Rs.)</b></td>
</tr>';
foreach($item as products):
$html .=' //This part contains error
<tr>
<td>'echo products['item']'</td>
<td>'echo products['quantity']'</td>
<td align="right">75</td>
</tr>
<tr>
<td colspan="3" align="right"><b>Total: 375</b></td>
</tr>';
endforeach;
$html .= '</table>';
$html .= '<br><br>Some more text can come here...';

Get the value from Second td from each TR

I had a table that used for user to input their value.
Table Structure:
<table id="tblAddProduct">
<tbody class='A2'>
<tr>
<td>Product Code :</td>
<td> <input/> </td>
</tr>
<tr>
<td>Product Description :</td>
<td> <input/> </td>
</tr>
</tbody>
<tbody class='A2'>
<tr>
<td>Product Code :</td>
<td> <input/> </td>
</tr>
<tr>
<td>Product Description :</td>
<td> <input/> </td>
</tr>
</tbody>
</table>
I had reference other solution and modified to my question. Here is my draft solution:
foreach(pq('.A2') as $tag) {
foreach(pq($tag)->find('tr') as $tr) {
foreach(pq($tr)->find('td') as $td) {
echo $td;
}
}
}
How to get the INPUT from the each second TD from each TR in each TBODY
Try this:
foreach ( $html->find('#tblAddProduct tbody.A2 tr') as $tr ) {
echo $tr->find('td', 1)->plaintext;
echo '<br/>';
}
I used the plaintext in an example and it worked just fine...
The full working example HERE if needed
Try doing a print_r($td); This will show whats inside. Then you can access it depending on how it is stored.

How can i get the entire HTML of an element using regex?

i'm learning Regex but can't figure it out.... i want to get the entire HTML from a DIV, how to procced?
already tried this;
/\< td class=\"desc1\"\>(.+)/i
it returns;
Array
(
[0] => < td class="desc1">
[1] =>
)
the code that i'm matching is this;
<table id="profile" cellpadding="1" cellspacing="1">
<thead>
<tr>
<th colspan="2">Jogador TheInFEcT </th>
</tr>
<tr>
<td>Detalhes</td>
<td>Descrição:</td>
</tr>
</thead><tbody>
<tr>
<td class="empty"></td><td class="empty"></td>
</tr>
<tr>
<td class="details">
<table cellpadding="0" cellspacing="0">
<tbody><tr>
<th>Classificação</th>
<td>11056</td>
</tr>
<tr>
<th>Tribo:</th>
<td>Teutões</td>
</tr>
<tr>
<th>Aliança:</th>
<td>-</td>
</tr>
<tr>
<th>Aldeias:</th>
<td>1</td>
</tr>
<tr>
<th>População:</th>
<td>2</td>
</tr><tr>
<td colspan="2" class="empty"></td>
</tr>
<tr>
<td colspan="2"> » Alterar perfil</td>
</tr>
</tbody></table>
</td>
<td class="desc1">
<div>STATUS: OFNAaaaAA</div>
</td>
</tr>
</tbody>
</table>
i need to get the entire code inside the < td class="desc1">, like that;
<div >STATUS: OFNAaaaAA< /div>
</td>
</tr>
</tbody>
</table>
Could someone help me out?
Thanks in advance.
I usually use
$dom = DOMDocument::load($htmldata);
for converting HTML code to XML DOM. And then you can use
$node = $dom->getElementsById($id);
/* or */
$nodes = $dom->getElementsByTagName($tag);
to get your HTML/XML node.
Now, use
$node->textContent
to get data inside node.
try this, it does not cover all possible cases but it should work:
/<td\s+class=['"]\s*desc1\s*['"]\s*>((.|\n)*)<\/td>/i
tested with: http://www.pagecolumn.com/tool/pregtest.htm
edit: improved solution suggested by Alan Moore
/<td\s+class=['"]\s*desc1\s*['"]\s*>(.*?)<\/td>/s

Categories