how to make html table rows equal in php - php

data is from my database they are not same value of data. and my html display are not good to view, is there any way to create empty td?
<?php while($team= mysqli_fetch_assoc($team_set)){ ?>
<td><?php echo htmlentities($team['tname']); ?></td>
<?php while($grade = mysqli_fetch_assoc($grade_set)){ ?>
<td><?php echo htmlentities($grade['points']); ?></td>
<?php } mysqli_free_result($grade_set); ?>
<td><?php echo htmlentities($team['sum']); ?></td>
<?php } mysqli_free_result($team_set); ?>

I would reorganize the structure of the middle part, i.e. this part of your code:
<?php while($grade = mysqli_fetch_assoc($grade_set)){ ?>
<td><?php echo htmlentities($grade['points']); ?></td>
<?php } mysqli_free_result($grade_set); ?>
Here every entry is put into its own table cell, creating what you describe in your question (different amount of cells in each row). I would instead put all these entries into one cell:
<td class="points_cell">
<?php while($grade = mysqli_fetch_assoc($grade_set)){ ?>
<span class="points"><?php echo htmlentities($grade['points']); ?></span>
<?php } mysqli_free_result($grade_set); ?>
</td>
As you can see, I wrapped the single entries into span tags with a class (.points) and created and applied the class .points_cell to the cell that wraps them. For these two classes you can create CSS rules similar to this:
.points_cell {
white-space: nowrap;
}
.points {
display: inline-block;
padding: 0 10px;
}
white-space: nowrap; on .points_cell makes sure the .points spans are not put below each other, but in one line. The side padding in .points creates sufficient distance between the entries - this value can of course be adjusted as needed.
You could also create CSS borders (left and right) or alternating background colors for those span elements if you want to set them apart in a more obvious way.

To output table cells using only PHP, you'd need to pre-loop your arrays, find the max in any row, then loop again that many times when you actually display.
Here I'm ls using a temporary array to hold the results so you don't need to call the database twice. I made some assumptions about your SQL result set, so you may need to modify it slightly.
<?php
// Call database, pre-looping result set
$max = 1;
$table_arr = array();
while( $team = mysqli_fetch_assoc($team_set) ){
$tmp = array();
while( $grade = mysqli_fetch_assoc($grade_set) ){
$tmp[] = $grade['points'];
}
mysqli_free_result($grade_set);
// Store results for later use
$table_arr[] = array(
'tname' => $team['tname'],
'sum' => $team['sum '],
'points' => $tmp,
);
// Get max cells in any result set
$max = max( $max, count($tmp) );
}
mysqli_free_result($team_set);
?>
<?php
// Loop $table_array to actually output things
foreach ($table_array as $team) {
?>
<td><?php echo htmlentities($team['tname']); ?></td>
<?php
// loop $max times, output points if present else empty cell
for ($x = 0; $x < $max; $x++) {
$points = isset( $team['points'][ $x ] ) ? $team['points'][ $x ] : ' ';
?>
<td><?php echo htmlentities($points); ?></td>
<?php } ?>
<td><?php echo htmlentities($team['sum']); ?></td>
<?php } ?>

Related

Auto generate index number for variables inside same table row, for each row?

I have a number of table rows, which I choose according to the number of items that I plan to extract from my database.
I don't render the rows automatically, because in some of them I want to have the freedom to include some static elements that do not have a certain uniform (see ABC, XYZ in code for example).
For each item (person) I also manually set in the PHP file itself, some other relevant values for his particular row, such as $company[i]
PHP:
<?php
// Choose Relevant people, and turn them into an array
$item_array = array(
'Mike',
'Bill',
'Joe'
);
//implode items, turn into string
$item_implode = join("','", $item_array);
//declare an overall array for result
$person = array();
$personList = array();
$result = $mysqli->query("SELECT available from people_table where available IN ('$item_implode') ORDER BY FIELD (available, '$item_implode');");
if ($result->num_rows > 0) {
$x = 1;
// output data of each row
while($row = $result->fetch_assoc()) {
$person[$x]["available"] = $row['available'];
$x = $x + 1;
}
} else {
echo "0 results";
}
// Manually Set Values:
$hide1=false;
$comment1="hello";
$company1="apple";
$hide2=false;
$comment2="something";
$company2="microsoft";
// And so on...
?>
Since I add another code block for each row, I have to replace in each block the index number, according to the order of the row in the HTML code, which means that in each block, I should CTRL-F the number, and replace it with the following number, which doesn't feel very efficient:
HTML:
// First Row
<?php if ($person[1]["available"]=="yes") { ?>
<tr<?= !$hide1 ? "" : " class=\"hidden\""; ?>>
<td>ABC</td>
<td><?= !$comment1 ? "" : "<div class=\"cell\">" . $comment1 . "</div>"; ?></td>
<td><?= some_function( $company1 ) ?></td>
</tr>
<?php } else { } ?>
// Second Row
<?php if ($person[2]["available"]=="yes") { ?>
<tr<?= !$hide2 ? "" : " class=\"hidden\""; ?>>
<td>XYZ</td>
<td><?= !$comment2 ? "" : "<div class=\"cell\">" . $comment2 . "</div>"; ?></td>
<td><?= some_function( $company2 ) ?></td>
</tr>
<?php } else { } ?>
// and so on
Is there any way to get the indexing number which appears in the end of each variable, to be generated automatically according to the row number in the HTML?
Edit:
Thanks to Andrew Cheong's answer I made an advancement:
I switch all variables that end with a fixed number, into [i] form.
I added a while loop (one line after code start, and another line before code end) to each Table Row, which allows me to indicate index number just once:
So it works fine but I think it's not perfect yet, how else shall I modify it?
New Code:
// First Row
<?php if ($person[1]["available"]=="yes") { ?>
<?php $i = 1; while ($i > 0) { ?> /// New Line #1
<tr<?= !$hide[$i] ? "" : " class=\"hidden\""; ?>>
<td>ABC</td>
<td><?= !$comment[$i] ? "" : "<div class=\"cell\">" . $comment[$i] . "</div>"; ?></td>
<td><?= some_function( $company[$i] ) ?></td>
</tr>
<?php break; } ?> /// New Line #2
<?php } else { } ?>
// Second Row
<?php if ($person[2]["available"]=="yes") { ?>
<?php $i = 2; while ($i > 0) { ?> /// New Line #1
<tr<?= !$hide[$i] ? "" : " class=\"hidden\""; ?>>
<td>XYZ</td>
<td><?= !$comment[$i] ? "" : "<div class=\"cell\">" . $comment[$i] . "</div>"; ?></td>
<td><?= some_function( $company[$i] ) ?></td>
</tr>
<?php break; } ?> /// New Line #2
<?php } else { } ?>
// and so on
You could use actual arrays, still—
// Manually Set Values:
$hide[1]=false;
$comment[1]="hello";
$company[1]="apple";
$hide[2]=false;
$comment[2]="something";
$company[2]="microsoft";
and where they don't apply, simply don't set them, e.g.
$comment[3]="only a comment";
and in your HTML,
<?php
if ($person[1]["available"]=="yes") { ?>
<tr<?= !isset($hide[$i]) || !$hide[$i] ? "" : " class=\"hidden\""; ?>>
<td>ABC</td>
<td><?= !isset($comment[$i]) || !$comment[$i] ? "" : "<div class=\"cell\">" . $comment[$i] . "</div>"; ?></td>
<td><?= if (isset($company[$i])) { some_function( $company[$i] ); } ?></td>
</tr>
<?php } else { } ?>
I didn't do all the work for you, but you can see I've modified it so you can now place the thing in a loop indexing over $i.
If you don't know how many $i there will be, then use a while loop, and get creative, e.g. break when isset($hide[$i]) && isset($comment[$i]) && isset($company[$i]) == false.
If you want to hide the comment column altogether, then pull the isset outside the <td> so that you don't even created a <td> in that case.
The way I've wrapped some_function... in an if( ... ) probably won't work because you're using the short-echo form <?= => but I'll let you figure that out.
Re: New Code / Comments
Let me take your new code and modify it a little. I'm going to fix the formatting too so that indentations match up, too:
<?php
$i = 1;
while ($i > 0) {
if ($person[$i]["available"]=="yes") {
?>
<!--
Only add the hidden class if $hide[$i] has been set by someone,
i.e. you, manually, AND it has been set to true.
-->
<tr<?= isset($hide[$i]) && $hide[$i] ? " class=\"hidden\"" : ""; ?>>
<td>ABC</td>
<!--
Same as above, only add the comment div if it has been set, but
instead of what you're doing, I'm going to do what I think you
meant to do: only if there's a non-empty string for a comment.
-->
<td><?= isset($comment[$i]) && $comment[$i] != "" ? "<div class=\"cell\">" . $comment[$i] . "</div>" : ""; ?></td>
<!--
Same thing yet again: only proceed if $company[i] is set and not
an empty string.
-->
<td><?= isset($company[$i]) && $company[$i] != "" ? some_function( $company[$i] ) : "" ?></td>
</tr>
<?php
} // The `else` case is not required.
$i++;
if (!isset($hide[$i]) &&
!isset($comment[$i]) &&
!isset($company[$i]))
{
// Now, this entire thing can be put in a form inside the
// `while`'s condition so that there is no need for this `if`
// statement nor the `break`, but I'm doing it this way to
// make it clearer to you what's going on.
break;
}
}
?>
That's it. No other loops, no other blocks. Now let me answer your questions in your comment:
Of course, no, I didn't mean to use a while per row. That'd be silly and save you no work. I meant the above, where you need only one row.
In my "don't set" example I meant to show that $hide[3] and $company[3] were not set; only $comment[3].
As I'm sure some have tried to tell you, your problem wasn't that you just needed to convert numbers to variables. You actually picked the wrong approach, and unfortunately, stubbornly held onto that approach. I know what it's like to feel like, "Yes, I know! I know! But I have a special case! And in my special case, I need it to be this way!" But seasoned programmers know what kinds of special cases merit certain techniques, and it was obvious that your special case had nothing to do with what's called "reflection" or "variable variables," which you were trying to use. What you were missing were some simple isset()s (and there are probably 10 other ways to do this too, without reflection). isset() checks if, well, you've set the variable, manually, non-manually, whatever. That means you can now create a loop for each <tr> and use isset() on each row's respective variable to see whether you want to do anything with it. If you copy-paste this code to create a new, custom, one-off page, where $hide and $comment and $company are no longer relevant, then guess what: Nothing breaks, because the isset()s will just ignore them. I hope that makes things clearer, but if it doesn't, no worries, as you continue to program, you'll get accustomed to various patterns, and the knowledge will come automatically.

Is there any way for php to highlight the difference between two strings?

I've got a table which outputs two mySQL records, one original and one which has been edited and flagged for approval/disapproval by the admin. I want to change the column color to highlight rows which have been edited.
The color highlight on changed rows works for all rows except "SalaryFrom" and "Email", for some reason they are always highlighted as different even when the values appear to be completely identical.
Is there any function in PHP which highlights the difference between two strings so I can figure out where the difference is?
Here's my code for one row:
<tr>
<?php
if (htmlval($cand['salaryfrom'])!==htmlval($flaggedcand['salaryfrom']))
{
$tcolor="#000000";
}
else
{
$tcolor="#D3D5E8";
}
?>
<td bgcolor=<?php echo $tcolor ;?>><b>Salary from</b></td>
<td><?php htmlout($flaggedcand['salaryfrom']." "); ?></td>
</tr>
function htmlval($text)
{
return html_entity_decode($text, ENT_QUOTES);
}
Use this
<?php
if ( $cand['salaryfrom'] != $flaggedcand['salaryfrom'] ) $tcolor ="#000000";
else $tcolor="#D3D5E8";
?>
<td style="background: <?php echo $tcolor; ?>;"><b>Salary from</b></td>
<td><?php echo $flaggedcand['salaryfrom'] ." "; ?></td>
There are several reasons why your strings may look the same but they aren't for real. Example: Maybe you need to trim heading and trailing space like this :
function htmlval($text)
{
return trim(html_entity_decode($text, ENT_QUOTES));
}
There are a couple of classes, lib, or self-made function to highlight two strings differences (not in core php) but in your case it might be just enought to output explicitly string 1 and then string 2 so that you can spot the differences by yourself like this :
<tr>
<?php
if (htmlval($cand['salaryfrom'])!==htmlval($flaggedcand['salaryfrom']))
{
$tcolor="#000000";
ob_start();
var_dump(htmlval($cand['salaryfrom']));
echo " is not equal to ";
var_dump(htmlval($flaggedcand['salaryfrom']));
$out = ob_get_clean();
}
else
{
$tcolor="#D3D5E8";
$out = $flaggedcand['salaryfrom'];
}
?>
<td bgcolor=<?php echo $tcolor ;?>><b>Salary from</b></td>
<td><?php htmlout($out." "); ?></td>
</tr>

Multiple column HTML Table From Single Column Text File In PHP

I have a simple working PHP script to write an HTML table from a text file that contains a single column of data that contains HTML links. This writes the data horizontally in a row across 5 or 6 columns as I want it to. But I am looking to set up a script with a loop that will take this list of data and input it into the table until it finishes the data list, so that I do not have to hard code each table cell individually. Just let the script create each table cell, at 5 or 6 columns across (whichever I need for this specific table), go to the next row, etc., until it runs out of data. The data in the data file will be added to on a regular basis, so the table will not be of a certain fixed length forever. I am using the echo command so that I can add some more HTML formatting later on.
Even though my existing script is simple and it works, if you can think of a better way of doing what I am trying to do, all suggestions are appreciated.
Thanks in advance, Stan...
PHP code follows:
<?php
$item = #fopen('linklist.txt', "r");
if ($item) { while (!feof($item)) { $lines[] = fgets($item, 4096); } fclose($item); }
echo'
<TABLE border="1">
<TR>
<TD>'.($lines[1]).'</td>
<TD>'.($lines[2]).'</td>
<TD>'.($lines[3]).'</td>
<TD>'.($lines[4]).'</td>
<TD>'.($lines[5]).'</td>
<TD>'.($lines[6]).'</td>
</tr>
<TR>
<TD>'.($lines[7]).'</td>
<TD>'.($lines[8]).'</td>
<TD>'.($lines[9]).'</td>
<TD>'.($lines[10]).'</td>
<TD>'.($lines[11]).'</td>
<TD>'.($lines[12]).'</td>
</tr>
<!-- And So On, And So On, ETC -->
</table>'
?>
<?php
echo '<table border="1"><tr>';
for($i=0; $i<sizeof($lines); $i++) {
echo '<td>'.$lines[$i].'</td>';
if(($i+1)%6==0 && $i!=sizeof($lines)-1) echo '</tr><tr>';
}
echo '</tr></table>';
?>
Explanation:
Repeats through each "line" and writes the <td>value</td>
If a line is a multiple of 6, after writing the value, then close the row, and open another (unless it's the last one, since it will close the row after the loop as well.
(I assume you meant to start on $line[0], but if you really meant to start on $line[1], just change the $i=0; to $i=1;, remove the +1 in the row check, and change $i<sizeof to $i<=sizeof
$lines = chunk_split($lines,6);
?>
<TABLE border="1">
<? foreach ($lines as $row): ?>
<TR>
<? foreach ($row as $value): ?>
<TD><?=$value?></td>
<? endforeach ?>
<TR>
<? endforeach ?>
</TABLE>
In pseudo code...
x = 0
echo '<TABLE border="1">'
For each $line in $lines {
x = x + 1
if x = 1 {
echo '<TR>'
}
echo <TD>'.($line).'</TD>
if x = 6 {
echo '</TR>'
x = 0
}
}
echo '</TABLE>'
Note the use of the $line object to hold the value of the $line array element.
hth
If you use a loop, you can also avoid reading the complete file into memory, which might be beneficial:
<?php
$item = #fopen('linklist.txt', "r");
if ($item) {
echo'<TABLE border="1">';
$i=0;
$lines=array();
while (!feof($item)) {
$line[] = fgets($item, 4096);
$i++;
if ($i==6) {
echo "<tr>";
echo '<TD>'.($lines[0]).'</td>';
echo '<TD>'.($lines[1]).'</td>';
echo '<TD>'.($lines[2]).'</td>';
echo '<TD>'.($lines[3]).'</td>';
echo '<TD>'.($lines[4]).'</td>';
echo '<TD>'.($lines[5]).'</td>';
echo "<tr>";
$i=0;
$lines=array();
}
}
echo '</table>';
fclose($item);
}
?>

Print fields in drupal

I'm trying to make Drupal print a list with two different fields in the same array. So first comes field A, then field B and it prints in this way until the whole array is printed.
The result I'm trying to get is something like
<tr>
<td>Field_1[value1]</td>
<td>Field_2[value1]</td>
</tr><tr>
<td>Field_1[**value'n'**]</td>
<td>Field_2[**value'n'**]</td>
</tr>
Until all values are printed.
EDIT.
Figured out one way of achieving this directly in node--testnode.tpl.php.
<table>
<?php if ($content['field_test'][1]): ?>
<tr><td><?php print render($content['field_test'][0])?></td><td><?php print render($content['field_test'][1])?></td></tr>
<?php endif; ?>
<?php if ($content['field_test'][3]): ?>
<tr><td><?php print render($content['field_test'][2])?></td><td><?php print render($content['field_test'][3])?></td></tr>
<?php endif; ?>
<?php if ($content['field_test'][5]): ?>
<tr><td><?php print render($content['field_test'][4])?></td><td><?php print render($content['field_test'][5])?></td></tr>
<?php endif; ?>
</table>
Second fix, only manual work is to say how many repetitions you want.
<dl class="My Class">
<?php
$i = 0;
$counter = 2 * render ($content['field_counter_slides'][0]) -1;
while ($i <= $counter):
if ($content['field_test'][1]){
echo "<dt>";
print render ($content['field_test'][$i]);
$i++;
echo "</dt><dd>";
print render ($content['field_test'][$i]);
echo "</dd>";
$i++;
}
endwhile;
?>
</dl>
It's quite hard to answer without knowing more but something like this would probably do it:
$header = array();
$rows = array();
foreach ($node->field_my_field[$langcode] as $key => $field_entry) {
$rows[] = array(
$field_entry['value'],
$node->field_my_second_field[$langcode][$key]['value']
);
}
$output = theme('table', array('header' => $header, 'rows' => $rows));
You'd have to make sure yourself that there are equal numbers of entries for each field so that there will always be a field_my_second_field entry for each run through the foreach loop.

how can put value in two columns?

how can a list of values that select of database, put in two columns together by PHP ?
EXAMPLE:
values select of database:
Internet
Game Notes
Internet
Pool
Coffee
Game Notes
i want like this:
Row-first order
<table>
<?php
$left = true;
foreach ($values as $value){
if ($left)
echo "<tr>";
echo "<td>$value</td>";
if (!$left)
echo "</tr>";
$left = !$left;
}
?>
</table>
With column-first order (as in your sample) you'll have to involve CSS and it's much complex. Something like
<div class='inline_div'>
<?php
$middle = count($values)/2+1;
$count = 0;
foreach ($values as $value){
if ($count==$middle)
echo "</div><div class='inline_div'>";
echo "$value<br/>";
++$count;
}
?>
</div>
inline_div is something like .inline_div {display:inline; float:left}. But that will definitely not work as expected, I'm no CSS master. IE does not support display:inline for sure.
If you want it exactly like you want in your example then you are going to have to read the whole table into memory, calculate the mid-point element and then build your table from that using a base point, an offset and a check to ensure that you've not repeated anything which involves a whole load of calculation.
A way around this would be to build two separate tables (each containing a single column) and then enclose them in a single table with two columns:
<?php
$list=array('a','b','c','d','e','f');
$midpoint=floor(count($list)/2);
$tableHeader='<table width="100%">';
$tableFooter='</table>';
$leftTable=$tableHeader;
$rightTable=$tableHeader;
for ($c=0; $c<$midpoint; $c++)
{
$leftTable.='<tr><td width="100%">'.$list[$c].'</td></tr>';
}
$leftTable.=$tableFooter;
for ($c=$midpoint; $c<count($list); $c++)
{
$rightTable.='<tr><td width="100%">'.$list[$c].'</td></tr>';
}
$rightTable.=$tableFooter;
$mainTable='<table><tr><td width="50%">'.$leftTable.'</td><td width="50%">'.$rightTable.'</td></tr></table>';
echo $mainTable;
?>
Or something along those lines. I haven't tested this code but it would be pretty close (may have to adjust the values in the "for" sections
The simple solution would be to use two divs. As a previous poster commented, you first need to count the elements. Suppose the items you want to display are in an array $items You can use this kind of code
<?php
$divItemCount = (count($items)%2) ? count($items)/2 + 1 : count($items)/2;
?>
<div id="leftdiv" style="width: 30%;">
<ul>
<?php
for($i=0; $i<$divItemCount; $i++) {
echo '<li>'. $items[$i] .'</li>';
}?>
</ul></div><div id="rightdiv" style="width: 30%; float:left"><ul>
<?php
for($j=$i; $j<count($items); $j++) {
echo '<li>'. $items[$j] .'</li>';
}?>
</ul></div>
I have not tested the code so there may be errors. You can use the border property in the divs to create a custom separator between the two lists.

Categories