php sidebar and footer inside main - php

I help develop my school's website what I can not figure out is why on a certain page the sidebar and footer go into the table main. It only does this for two thing custodial and kitchen even when I think the code for say administrators is the same code and looks the same to me.
This is the code used to generate the teachers page
The link below will take you to the broken page since I can't post pictures
http://gwhs.kana.k12.wv.us/academics/display.php?action=teacher&id=103
While the link below will take you to one that actually works
http://gwhs.kana.k12.wv.us/academics/display.php?action=teacher&id=24
If you want the entire file for this code let me know and I will post a link
function dTeacher() {
global $db, $id;
if ($stmt = $db->prepare("SELECT name, department, schedule, education, whyteach, phone, email, image, quote FROM teachers WHERE id = ?"))
{
$stmt->bind_param('i', $id);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
$stmt->close();
$schedule = array();
$schedule = explode(",",$row['schedule']);
$education = explode(",",$row['education']);
$noshow = array(20, 14, 25, 15, 24, 21, 23);
print '<h1>Viewing '.$row['name'].'\'s Profile!</h1>';
if ($row['image']) {
print '<img style="max-width:40%; display: block; margin: 2% auto;" src="'.$row['image'].'" alt="Teacher Image Here">';
}
if (!(in_array($row['department'], $noshow))) {
print '<h3>Schedule</h3>
<table id="maindata">
<tr id="head"><td style="width:30%;">Period</td><td style="width:70%;">Class</td></tr>';
for ($i=0; $i<count($schedule); $i++)
{
$oddeven = ($i%2==0) ? "even" : "odd";
$scnum = $schedule[$i];
$scresult = $db->query("SELECT id, name FROM classes where id = {$scnum} LIMIT 1");
$scrow = $scresult->fetch_assoc();
if ($scnum == 1337) {
$scrow['name'] = "OFF";
} //off periods
print '<tr id="'.$oddeven.'"><td style="width:30%;">'.$i.'</td><td style="width:70%;">'.$scrow['name'].'</td></tr>';
}
}
if ($row['education']) {
print "</table><h3>Education</h3>";
for ($i=0; $i<count($education); $i++)
{
$oddeven = ($i%2==0) ? "even" : "odd";
print '<table id="maindata"><tr id="'.$oddeven.'"><td>'.$education[$i].'</td></tr>';
}
print '</table>';
}
if ($row['phone'] || $row['email']) {
print '
<h3>Contact</h3>
<table id="maindata"><tr id="even"><td style="width:30%;">Phone</td><td>'.$row['phone'].'</td></tr>
<tr id="odd"><td style="width:30%;">Email</td><td>'.$row['email'].'</td></tr></table>';
}
if ($row['whyteach'] != "") {
print '<h3>Why do you teach?</h3>
<table id="maindata"><tr id="even"><td><p>'.$row['whyteach'].'</p></td></tr></table>';
}
if ($row['quote'] != "") {
print '<h3>Favorite Quote</h3>
<table id="maindata"><tr id="even"><td><p>'.$row['quote'].'</p></td></tr></table>';
}
}
else {
print "Error with your request.";
die();
}
}

You have a bug here, you are not closing table tag:
if (!(in_array($row['department'], $noshow))) {
print '<h3>Schedule</h3>
<table id="maindata">
<tr id="head"><td style="width:30%;">Period</td><td style="width:70%;">Class</td></tr>';
for ($i=0; $i<count($schedule); $i++)
{
$oddeven = ($i%2==0) ? "even" : "odd";
$scnum = $schedule[$i];
$scresult = $db->query("SELECT id, name FROM classes where id = {$scnum} LIMIT 1");
$scrow = $scresult->fetch_assoc();
if ($scnum == 1337) {
$scrow['name'] = "OFF";
} //off periods
print '<tr id="'.$oddeven.'"><td style="width:30%;">'.$i.'</td><td style="width:70%;">'.$scrow['name'].'</td></tr>';
}
echo "</table>";
}
Because of this, when the profile has Schedule the table is not closed and the page will display bad.
And closes it here:
if ($row['education']) {
print "<h3>Education</h3>";
With two modifications the web should do its work fine.
Take a look this HTML validator, it will help you:
http://validator.w3.org/check?uri=http%3A%2F%2Fgwhs.kana.k12.wv.us%2Facademics%2Fdisplay.php%3Faction%3Dteacher%26id%3D103&charset=%28detect+automatically%29&doctype=Inline&group=0
Best regards.

First words: You should re-think the layout. Creating multiple tables to display page content is not the best approach and furthermore IDs have to be unique. So for valid HTML you can't have multiple tables with the ID maindata.
As mentioned by cmorrissey in the comments, you're not closing the first table, unless you enter the next if statement. Furthermore this part
if ($row['education']) {
print "</table><h3>Education</h3>";
for ($i=0; $i<count($education); $i++) {
$oddeven = ($i%2==0) ? "even" : "odd";
print '<table id="maindata"><tr id="'.$oddeven.'"><td>'.$education[$i].'</td></tr>';
}
print '</table>';
}
of your code closes the previous <table id="maindata"> but opens a new one in each iteration of the loop. After the loop, your closing just one of them. So if it is correct, that you want to create multiple of these tables, you should close them in the loop as well:
for ($i=0; $i<count($education); $i++) {
$oddeven = ($i%2==0) ? "even" : "odd";
print '<table id="maindata"><tr id="'.$oddeven.'"><td>'.$education[$i].'</td></tr>';
print '</table>';
}

Related

How to display checked checkbox from database in php?

I want to display checked checkbox which are stored as values in a mysql database.
For now the table stores the value of the checkbox being checked in the database. The header and first column are fetched from three different tables in the database. While the values of the checked check-boxes gets saved in a same table.
Here's the code for inserting the data.
$active = "CourseReport";
require_once 'pages/header.php';
require_once './functions/schema-functions.php';
require_once './functions/report-functions.php';
$course = Schema::getCourseReport();
$objective = Schema::getObjective();
$goals = Schema::getGoals();
$mainobj = Schema::getMainObjectives();
$subobj = Schema::getSubObjectives();
?>
<form id="addReport" action ='./functions/report-functions.php' method="post">
<table id="table1" class="table table-hover">
<thead>
<?php
echo '<tr><th>Goals</th>';
for ($i = 0; $i < count($course); $i++) {
echo '<th id = "rotate1">'. $course[$i]->commonName . '</th>';
}
echo '</tr>';
?>
</thead>
<tbody>
<?php
for ($y = 0; $y < count($goals); $y++) {
echo '<tr class="clickable"><th class="toggle">Goal#'.$goals[$y]['GoalId'].':'." " .' '.$goals[$y]['Goals'].'</th>
</tr>';
?>
<?php
for( $z = 0; $z < count($mainobj); $z++){
if($mainobj[$z]['GoalId'] == $goals[$y]['GoalId']) {
echo '<tr class="expander"><th class=row-header>Objective#'.$mainobj[$z]['MainObjId'].':'." ".' '.$mainobj[$z]['MainObjectives'].'</th>
</tr>';
?>
<?php
for ($j = 0; $j< count($subobj); $j++) {
if($mainobj[$z]['MainObjId'] == $subobj[$j]['MainObjId']){
echo '<tr class="expander"><td class=row-header>'.$subobj[$j]['SubObjId'].' ) '.$subobj[$j]['SubObjectives'].' </td>';
for ($x = 0; $x < count($course); $x++) {
echo "<td><input name='check[]' type=checkbox value=c".$course[$x]->courseId."-o".$subobj[$j]['SubObjId']." id=checked></td>";
}
echo '</tr>';
}
}
}
}
}
?>
</tbody>
</table>
<button class="button" name= "submit" value= "Submit">Submit</button>
</form>
report-functions.php
if( isset( $_POST['submit'], $_POST['check'] ) ){
try{
require_once 'db-connect.php';
$conn = DatabaseConnection::getConnection();
$sql= " insert into `Report` (`ColRow`) values (:value) ";
$stmt = $conn->prepare( $sql );
if( $stmt ){
$conn->beginTransaction();
foreach( $_POST['check'] as $index => $value ) {
$result = $stmt->execute( [ ':value' => $value ] );
if( !$result ) {
echo '
<script>
alert("Error, please try submitting again. Error code 1");
window.history.back();
</script>';
}
}
$conn->commit();
echo '<script>
alert("Report was submitted successfully.");
window.location = ".../";
</script>';
}
} catch( Exception $e ){
$conn->rollback();
exit( $e->getMessage() );
}
I expect that once I submit the table, the table should load the same table with the checked checkboxes. I should be able to make the changes and submit the table over and over again.
Please comment if I need to provide any additional information.
When you display your page (in your first section of code), at some point you do this:
echo "<td><input name='check[]' type=checkbox value=c".$course[$x]->courseId."-o".$subobj[$j]['SubObjId']." id=checked></td>";
The value is set to:
value=c"c.$course[$x]->courseId."-o".$subobj[$j]['SubObjId']";
This value is where you get the checked or not value you mentioned in the comments (like c1-o1.1).
Right. So before you do that echo, add a new if condition.
$value = "c$course[$x]->courseId" . "-o$subobj[$j]['SubObjId']";
if (verify_checked($value)) {
$checked_code = "checked=\"checked\"";
}
else {
$checked_code = "";
}
echo "<td><input name='check[]' type=checkbox value=$value id=checked $checked_code ></td>";
The verify_checked(value) function does (from what I understand of your database, you keep the "grid location" of checked elements):
function verify_checked($value)
{
// Connect to the database if needed
// Perform: SELECT count($value) FROM Report
// If the result is >0, return TRUE
// Else return FALSE
}
The idea here is to query the database every time your are about to echo the <input> element.
Note for concatenating text, I find it more legible to put spaces around the . to clearly split what is part of the text and what is the concatenation dot.
As mentioned previously, indentation is critical for understanding of the different contexts. Until I indented your code, I had not realized how the different loops worked in relation to the others.

Change background color of a cell when next value is different from the preceding one

I've been around for years on Stack but this is my first time posting. I'm working on a website (php + mysql) and the following problem is driving me absolutely nuts.
I have a table with 2 columns: Size and Amount. The table is generated by a basic php script simply outputting values stored in the database as rows in the table. Super basic, no fancy stuff there:
SELECT Size, Amount FROM database WHERE product = 'product123' ORDER BY Size ASC
The php echo outputs an html table displaying Size and the corresponding available packs (Amount).
Echo '<td>'.$record['size'].'</td><td>'.$record['amount'].'</td>'
Some Sizes are available in different Amounts, so therefore a particular Size can appear multiple times. Example:
Size | Amount
1 | 10
1 | 50
2 | 10
2+ | 10
3 | 40
3+ | 25
3+ | 40
4+ | 25
What I'm looking to achieve is that rows containing the same Size have the same background color. So it should alternate, grouped by Size, and this is irregular unfortunately. Example:
Size | Amount
1 | 10 < yellow
1 | 50 < yellow
2 | 10 < transparent
2+ | 10 < yellow
3 | 40 < transparent
3+ | 25 < yellow
3+ | 40 < yellow
4+ | 25 < transparent
So if the next Size is different from the preceding one, the row background color should change. This way a single Size is alternately highlighted as a group. Note that Size 2 and 2+ (same for 3 and 3+) are considered to be different sizes, hence the background color should change.
I can't figure out how to achieve this with php. The difficulty is that I can't use an evaluation based on odd/even since there sometimes is a "+" involved, making not all Sizes numeric values. Changing the naming scheme to get rid of that "+" is not an option unfortunately.
I was thinking of somehow having php check, while generating the table row by row, if the next outputted Size is identical to the preceding one. If yes: no change in bg-color. If no: change bg-color. However I can't figure out what the best way is to code something like this. Any pointers in the right direction are much appreciated.
Just a MCVE:
// your data
$records[] = array('size' => "1");
$records[] = array('size' => "1");
$records[] = array('size' => "2");
$records[] = array('size' => "2+");
$records[] = array('size' => "3");
$records[] = array('size' => "3+");
$records[] = array('size' => "3+");
$records[] = array('size' => "4");
$lastSize = $records[0]['size'];
$color = "yellow";
foreach ($records as $record) {
if ($lastSize != $record['size']) {
$lastSize = $record['size'];
if ($color == "yellow") $color = "transparent";
else $color = "yellow";
}
$lastSize == $record['size'];
echo $record['size'].' - '.$color.'<br>';
}
// OUTPUT:
// 1 - yellow
// 1 - yellow
// 2 - transparent
// 2+ - yellow
// 3 - transparent
// 3+ - yellow
// 3+ - yellow
// 4 - transparent
Ok, we'll start at the end. You probably want to put your color on the <tr>. The cleanest way to do it would be using css classes.
if ($newSize) {
echo '<tr class="tranparentRow">';
} else {
echo '<tr class="yellowRow">';
}
We'll figure out how to get the right value into $newSize in a moment. Next, we need the css for classes above, so make sure this is in your styles somewhere:
.transparentRow {
background-color: transparent;
}
.yellowRow {
background-color: yellow;
}
Ok, lets rip the + off the size:
$plainSize = trim($record['size'], '+')
Ok, we use that for comparison, using an ever changing $oldSize valiable. Here is a full, functional, block:
$oldSize = 0;
foreach($whatever as $record) {
$plainSize = trim($record['size'], '+')
if ($plainSize == $oldSize) {
$newSize = false;
} else {
$newSize = true;
}
$oldSize = $plainSize;
if ($newSize) {
echo '<tr class="tranparentRow">';
} else {
echo '<tr class="yellowRow">';
}
echo '<td>'.$record['size'].'</td><td>'.$record['amount'].'</td>';
echo '</td>';
}
Some cleanup can lead to this:
$oldSize = 0;
foreach($whatever as $record) {
$plainSize = trim($record['size'], '+')
if ($plainSize == $oldSize) {
echo '<tr class="tranparentRow">';
} else {
echo '<tr class="yellowRow">';
}
$oldSize = $plainSize;
echo '<td>'.$record['size'].'</td><td>'.$record['amount'].'</td>';
echo '</td>';
}
I hope that helped not just with this problem, but with an example of how you can approach many other problems. Start at the end, work your way back.
As my comment suggested, use a double foreach() + implode() (and yet another solution):
<?php
$array[] = array("size"=>1,"amount"=>50);
$array[] = array("size"=>2,"amount"=>10);
$array[] = array("size"=>"2+","amount"=>10);
$array[] = array("size"=>3,"amount"=>40);
$array[] = array("size"=>"3+","amount"=>25);
$array[] = array("size"=>"3+","amount"=>40);
$array[] = array("size"=>"3+","amount"=>25);
$array[] = array("size"=>'4+',"amount"=>30);
// Sort by size
foreach($array as $row) {
$new[$row['size']][] = $row['amount'];
}
?>
<table>
<?php
$i = 0;
// Loop through the sorted groups
foreach($new as $size => $amts) {
// Determine odd or even
$color = ($i % 2 == 0)? "yellow":"transparent";
?> <tr>
<td class="<?php echo $color; ?>"><?php echo $size; ?></td>
<td class="<?php echo $color; ?>"><?php echo implode("</td>".PHP_EOL."</tr>".PHP_EOL."<tr>".PHP_EOL.'<td class="'.$color.'">'.$size.'</td><td class="'.$color.'">',$amts); ?></td>
</tr>
<?php $i++;
}
?>
</table>
You can do this using php sessions like this
session_start();
$_SESSION["pre_val"]='not set';
$_SESSION["pre_class"]='transparent';
//in your loop for showing table
//your loop starts
if($_SESSION["pre_val"]==$record['size']){
$suitable_class=$_SESSION["pre_class"];
}
else{
if($_SESSION["pre_class"]=='yellow'){$suitable_class='transparent';}
else{$suitable_class='yellow';}
}
//setting current values to session
$_SESSION["pre_class"] = $suitable_class;
$_SESSION["pre_val"] = $record['size'];
Echo '<tr class="$suitable_class"><td>'.$record['size'].'</td><td>'.$record['amount'].'</td></tr>';
//your loop ends
in your css
.yellow{background-color:yellow;}
.transparent{ background-color: rgba(255, 0, 0, 0.5);}
hope this solve your problem
Some for loop fun while printing out the table
$rows = array(
array("size"=>"1" ,"amount"=>"10"),
array("size"=>"1" ,"amount"=>"50"),
array("size"=>"2" ,"amount"=>"10"),
array("size"=>"2+","amount"=>"10"),
array("size"=>"3" ,"amount"=>"40"),
array("size"=>"3+","amount"=>"25"),
array("size"=>"3+","amount"=>"40"),
array("size"=>"4+","amount"=>"25")
);
echo "
<table>
<thead>
<tr><th>Size</th><th>Amount</th></tr>
</thead>
<tbody>";
$bgColors = ['transparent','yellow'];
$bgColor = 0;
echo "
<tr>
<td class='" . $bgColors[$bgColor] . "'>" . $rows[0]["size"] . "</td><td>" . $rows[0]["amount"] . "</td>
</tr>";
for($i = 1, $max = count($rows), $lastSize = $rows[0]; $i < $max; $lastSize = $rows[$i], $i++) {
if($rows[$i]["size"] !== $lastSize["size"])
$bgColor = ($bgColor + 1) % 2;
echo "
<tr>
<td style='background-color:" . $bgColors[$bgColor] . "'>" . $rows[$i]["size"] . "</td><td>" . $rows[$i]["amount"] . "</td>
</tr>";
}
echo "
</tbody>
</table>";
And an unasked for JS solution (assuming you've printed out the table as usual)
var rows = document.querySelectorAll('#sizeTable tbody td[name=size]');
var bgColors = ['transparent','yellow'];
var bgColor = 0;
for(var i = 1, lastSize = rows[0], max = rows.length; i < max; lastSize = rows[i],i++) {
if(rows[i].innerHTML !== lastSize.innerHTML) {
bgColor = (bgColor + 1) % 2;
}
rows[i].style['background-color'] = bgColors[bgColor];
}
you can keep the current size on a variable and if it changes you can change the color.
<html>
<head><title> Sample - Menukz </title></head>
<body>
<?php
/* Sample data array with size and amount */
$product['product123'] = array
(
array("size"=>"1", "amount"=>10),
array("size"=>"1", "amount"=>50),
array("size"=>"2", "amount"=>10),
array("size"=>"2+", "amount"=>10),
array("size"=>"3", "amount"=>40),
array("size"=>"3+", "amount"=>25),
array("size"=>"3+", "amount"=>40),
array("size"=>"4+", "amount"=>25)
);
$pre_size=0;
$pre_init=1;
echo "<table>";
foreach($product['product123'] as $row)
{
echo "<tr>";
/* Initialize */
if(strcmp($pre_size, $row['size']) !== 0 && $pre_init ===1)
{
$pre_size = $row['size'];
$pre_init = 0;
}
/* Change track */
if (strcmp($pre_size, $row['size']) !== 0 && $pre_init ===0)
{
echo "<td>Changed ... </td><td>". $row['size'] . "</td><td>" . $row['amount'] . "</td>";
$pre_size = $row['size'];
}
else
{
echo "<td>Not Changed ... </td><td>". $row['size'] . "</td><td>" . $row['amount'] . "</td>";
}
echo "</tr>";
}
?>
</body>
</html>
Thanks all for the proposed solutions. Berriel's MCVE works like a charm! However Stack doesn't let me +1 the answer yet.
I have one additional question:
I also have a second table in which the output of the first column can be any article code consisting of 10 chars limited to [a-z][0-9]. Since there is no predefined scheme such as in the Size table, I can't hardcode/predict any output like in most of the proposed solutions. However I still want to color the rows it in the same way described in my opening post.
I am not familiar with Stored Procedures or PDO in mysql. Is there any way to work around arrays with predefined content and still achieve the color grouping of rows with the same article code?
You can accomplish this using a nested repeat region.
First select your product by group WHERE product = 'product123' GROUP BY size
<?php
require ('conn.php');
try {
$prod = 'product123';
$sql = "SELECT * FROM sizes WHERE product=:prod GROUP BY size";
$query = $conn->prepare($sql);
$query->bindValue(':prod', $prod, PDO::PARAM_INT);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
$totalRows = $query->rowCount();
} catch (PDOException $e) {
die('failed!');
}
?>
Then get all the products in each group ordered by amount inside a nested repeat region.
Each "grouped row" will alternate colors.
<table width="200" border="0" cellspacing="0" cellpadding="5">
<tr>
<td>Size</td>
<td>Amount</td>
</tr>
<?php
$i = 0;
do {
$i = $i + 1;
if ($i % 2 == 0){
echo '<tr bgcolor=#E4E4E4><td colspan="2">';
} else {
echo '<tr bgcolor=#EEEEEE><td colspan="2">';
}
try {
$group = $row['size'];
$sql = "SELECT * FROM sizes WHERE size=:group ORDER BY amount ASC";
$nested = $conn->prepare($sql);
$nested->bindValue(':group', $group, PDO::PARAM_INT);
$nested->execute();
$row_nested = $nested->fetch(PDO::FETCH_ASSOC);
$totalRows_nested = $nested->rowCount();
} catch (PDOException $e) {
die('nested failed');
}
echo '<table border="0" cellpadding="0" cellspacing="0" width="200">';
do {
echo '<tr><td width="100">'.$row_nested['size'].'</td><td width="100">'.$row_nested['amount'].'</td></tr>';
} while ($row_nested = $nested->fetch(PDO::FETCH_ASSOC));
echo '</table>';
echo '</td></tr>';
} while ($row = $query->fetch(PDO::FETCH_ASSOC));
?>
</table>

Using php's count () command to count the result of an if statement

I am trying to work my head round this, I am using the following code to check the answers to a quiz and output either CORRECT or INCORRECT depending on the result of the comparison, and if the answer field is black (which only comes from the feedback form) a different message is displayed.
I cant quite work out how to apply the php count function in this situation though, what im trying to get it to do it count the amount of CORRECT and INCORRECT answers and add the two together, and then I can work out a % score from that.
<?php
// Make a MySQL Connection
// Construct our join query
$query = "SELECT * FROM itsnb_chronoforms_data_answerquiz a, itsnb_chronoforms_data_createquestions
q WHERE a.quizID='$quizID' AND a.userID='$userID' and q.quizID=a.quizID and
a.questionID = q.questionID ORDER BY a.cf_id ASC" or die("MySQL ERROR: ".mysql_error());
$result = mysql_query($query) or die(mysql_error());
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
if ($row['correctanswer'] == ''){echo '<tr><td style="color:blue;">Thankyou for your feedback</td></tr>';}
elseif ($row['correctanswer'] == $row['quizselectanswer']){
echo '<tr><td style="font-weight:bold; color:green;">CORRECT</td></tr>';}
else {echo '<tr><td style="font-weight:bold; color:red;">INCORRECT</td></tr>';
}}
?>
Iv found this example and have been trying to work out how to work it in, but cant think how to count the results of an if statement with it ?.
<?php
$people = array("Peter", "Joe", "Glenn", "Cleveland");
$result = count($people);
echo $result;
?>
Just increment two counters
$correct_answers = 0;
$incorrect_answers = 0;
while ($row = mysql_fetch_array($result)) {
if ($row['correctanswer'] == '') {...
} elseif ($row['correctanswer'] == $row['quizselectanswer']) {
echo '<tr><td style="font-weight:bold; color:green;">CORRECT</td></tr>';
$correct_answers++;
} else {
echo '<tr><td style="font-weight:bold; color:red;">INCORRECT</td></tr>';
$incorrect_answers++;
}
}
Simply increase some counter in each branch of your if/elseif/else construct...
$counters = array( 'blank'=>0, 'correct'=>0, 'incorrect'=>0 );
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
if ( ''==$row['correctanswer'] ) {
echo '<tr><td style="color:blue;">Thankyou for your feedback</td></tr>';
$counters['blank'] += 1;
}
elseif ( $row['correctanswer']==$row['quizselectanswer'] ) {
echo '<tr><td style="font-weight:bold; color:green;">CORRECT</td></tr>';
$counters['correct'] += 1;
}
else {
echo '<tr><td style="font-weight:bold; color:red;">INCORRECT</td></tr>';
$counters['incorrect'] += 1;
}
}
echo '#correct answers: ', $counters['correct'];
How about creating a variable with a count of correct answers? For each question you loop through, increment the value by one.
<?php
$correct_answers = 0;
while($questions) {
if($answer_is_correct) {
// Increment the number of correct answers.
$correct_answers++;
// Display the message you need to and continue to next question.
}
else {
// Don't increment the number of correct answers, display the message
// you need to and continue to the next question.
}
}
echo 'You got ' . $correct_answers . ' question(s) right!';
<?php
// Make a MySQL Connection
// Construct our join query
$query = "SELECT ... ";
$result = mysql_query($query) or die(mysql_error());
$countCorrect = 0;
$countIncorrect = 0;
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
if ($row['correctanswer'] == ''){echo '<tr><td style="color:blue;">Thankyou for your feedback</td></tr>';}
elseif ($row['correctanswer'] == $row['quizselectanswer']){
$countCorrect++;
echo '<tr><td style="font-weight:bold; color:green;">CORRECT</td></tr>';}
else {
$countIncorrect++;
echo '<tr><td style="font-weight:bold; color:red;">INCORRECT</td></tr>';
}
}
echo ((int)($countCorrect/($countIncorrect + $countCorrect) * 100)) . "% answers were correct!" ;
?>

PHP Function givine IE problems

I have a small PHP function that is called from one of my pages.
function ratingDetails($uid, $align, $width) {
$queryFull = "SELECT * FROM rating WHERE uid = $uid";
$resultFull = mysql_query($queryFull);
//START DISPLAY TABLE IF RESULTS
if(mysql_num_rows($resultFull) > 0) {
echo "<table class=\"ratingTable\" align=\"center\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\" width=\"550\">\n";
echo "<tr bgcolor=\"#6699cc\"><th>STARS</th><th>DATE RATED</th><th>COMMENT</th><th>RATED BY</th></tr>\n";
while($rowFull = mysql_fetch_array($resultFull)) {
$rating = $rowFull['rating'];
$comment = $rowFull['comment'];
$datePosted = date("M j, Y", $rowFull['date']);
$rid = $rowFull['raterID'];
$rater = getUsername($rid);
//SHOW STARS
if($rating == 0) { $stars = "notYet.jpg"; }
if($rating == 1) { $stars = "starOne.jpg"; }
if($rating == 1.5) { $stars = "starOneHalf.jpg"; }
if($rating == 2) { $stars = "starTwo.jpg"; }
if($rating == 2.5) { $stars = "starTwoHalf.jpg"; }
if($rating == 3) { $stars = "starThree.jpg"; }
if($rating == 3.5) { $stars = "starThreeHalf.jpg"; }
if($rating == 4) { $stars = "starFour.jpg"; }
if($rating == 4.5) { $stars = "starFourHalf.jpg"; }
if($rating == 5) { $stars = "starFive.jpg"; }
//DISPLAY IT ALL
echo "<tr><td width=\"10\"><img src=\"/images/rating/$stars\" width=\"105\" height=\"20\" /></td>";
echo "<td width=\"75\" align=\"center\">$datePosted</td><td>$comment</td><td width=\"85\">$rater</td></tr>\n";
}//END WHILE
echo "</table>\n";
} //END IF
else {
echo "<table class=\"ratingTable\" align=\"center\" border=\"1\" cellspacing=\"0\" cellpadding=\"8\" width=\"550\">\n";
echo "<tr><td align=\"center\"><span class=\"blue\">NO REVIEWS OR RATINGS FOR THIS DISTRIBUTOR</span></td></tr></table>\n";
} //END IF ELSE
}
But when it runs in IE (7 or 8), it throws this error:
A script on this page is causing Internet Explorer to run slowly. Bla bla bla...
I call this function from two pages and both cause the same error. If I remove the call from the page, the page loads fine.
There is no javascript involved with the pages in question...
Help, help, help... I don't have much hair left...
Rick
What's happening is that it's taking a long time to execute your script. IE is waiting for output from the server but it's taking a long time.
You may want to try either a call to flush() every row (or maybe every 25 rows using the modulus operator) or using ob_implicit_flush() to turn on implicit flushing. That way you have data continually coming back to the browser (I assume you have a huge amount of data). You probably will also need to call set_timeout(0) to disable the 30 second time limit on your script.
The first thing I would do is get rid of all those IF statements for the stars, either using an array for them or a switch statement, either of which would reduce the processing required for your script. An array would be my approach. Your code would look something like the following:
function ratingDetails($uid, $align, $width) {
$queryFull = "SELECT * FROM rating WHERE uid = $uid";
$resultFull = mysql_query($queryFull);
// Declare the array for the stars.
$astars = array(
0=> "notYet.jpg",
1=> "starOne.jpg",
1.5=> "starOneHalf.jpg",
2=> "starTwo.jpg",
2.5=> "starTwoHalf.jpg",
3=> "starThree.jpg",
3.5=> "starThreeHalf.jpg",
4=> "starFour.jpg",
4.5=> "starFourHalf.jpg",
5=> "starFive.jpg"
);
//START DISPLAY TABLE IF RESULTS
if(mysql_num_rows($resultFull) > 0) {
echo "<table class=\"ratingTable\" align=\"center\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\" width=\"550\">\n";
echo "<tr bgcolor=\"#6699cc\"><th>STARS</th><th>DATE RATED</th><th>COMMENT</th><th>RATED BY</th></tr>\n";
while($rowFull = mysql_fetch_array($resultFull)) {
$rating = $rowFull['rating'];
$comment = $rowFull['comment'];
$datePosted = date("M j, Y", $rowFull['date']);
$rid = $rowFull['raterID'];
$rater = getUsername($rid);
$stars = $astars[$rating];
//DISPLAY IT ALL
echo "<tr><td width=\"10\"><img src=\"/images/rating/$stars\" width=\"105\" height=\"20\" /></td>";
echo "<td width=\"75\" align=\"center\">$datePosted</td><td>$comment</td><td width=\"85\">$rater</td></tr>\n";
}//END WHILE
echo "</table>\n";
} //END IF
else {
echo "<table class=\"ratingTable\" align=\"center\" border=\"1\" cellspacing=\"0\" cellpadding=\"8\" width=\"550\">\n";
echo "<tr><td align=\"center\"><span class=\"blue\">NO REVIEWS OR RATINGS FOR THIS DISTRIBUTOR</span></td></tr></table>\n";
} //END IF ELSE
The decimals may cause a problem in the array; if so, you can enclose the keys in quotes; e.g., "1.5"=>"starOneHalf.jpg"
The other thing you could do is create a variable for the HTML output instead of echoing the output every line, and then just echo the output at the end.
I found my problem...
The table within my function was assigned a css class. This particular css class contained a behavior, which called PIE.htc. Apparently, this caused some sort of IE melt down whenever it was called. I removed PIE (bummer, no more rounded corners or shadows in IE) and my problem is solved!!!
Thanks to everyone who provided assistance along the way!!!

php and mysql not showing data, not entering foreach loop

I am having trouble with modifying a php application to have pagination. My error seems to be with my logic, and I am not clear exactly what I am doing incorrectly. I have had before, but am not currently getting errors that mysql_num_rows() not valid result resource
and that invalid arguments were supplied to foreach. I think there is a problem in my logic which is stopping the results from mysql from being returned.
All my "test" echos are output except testing while loop. A page is generated with the name of the query and the word auctions, and first and previous links, but not the next and last links. I would be grateful if a more efficient way of generating links for the rows in my table could be pointed out, instead of making a link per cell. Is it possible to have a continuous link for several items?
<?php
if (isset($_GET["cmd"]))
$cmd = $_GET["cmd"]; else
die("You should have a 'cmd' parameter in your URL");
$query ='';
if (isset($_GET["query"])) {
$query = $_GET["query"];
}
if (isset($_GET["pg"]))
{
$pg = $_GET["pg"];
}
else $pg = 1;
$con = mysql_connect("localhost","user","password");
echo "test connection<p>";
if(!$con) {
die('Connection failed because of' .mysql_error());
}
mysql_query('SET NAMES utf8');
mysql_select_db("database",$con);
if($cmd=="GetRecordSet"){
echo "test in loop<p>";
$table = 'SaleS';
$page_rows = 10;
$max = 'limit ' .($pg - 1) * $page_rows .',' .$page_rows;
$rows = getRowsByProductSearch($query, $table, $max);
echo "test after query<p>";
$numRows = mysql_num_rows($rows);
$last = ceil($rows/$page_rows);
if ($pg < 1) {
$pg = 1;
} elseif ($pg > $last) {
$pg = $last;
}
echo 'html stuff <p>';
foreach ($rows as $row) {
echo "test foreach <p>";
$pk = $row['Product_NO'];
echo '<tr>' . "\n";
echo '<td>'.$row['USERNAME'].'</td>' . "\n";
echo '<td>'.$row['shortDate'].'</td>' . "\n";
echo '<td>'.$row['Product_NAME'].'</td>' . "\n";
echo '</tr>' . "\n";
}
if ($pg == 1) {
} else {
echo " <a href='{$_SERVER['PHP_SELF']}?pg=1'> <<-First</a> ";
echo " ";
$previous = $pg-1;
echo " <a href='{$_SERVER['PHP_SELF']}?pg=$previous'> <-Previous</a> ";
}
echo "---------------------------";
if ($pg == $last) {
} else {
$next = $pg+1;
echo " <a href='{$_SERVER['PHP_SELF']}?pg=$next'>Next -></a> ";
echo " ";
echo " <a href='{$_SERVER['PHP_SELF']}?pg=$last'>Last ->></a> ";
}
echo "</table>\n";
}
echo "</div>";
function getRowsByProductSearch($searchString, $table, $max) {
$searchString = mysql_real_escape_string($searchString);
$result = mysql_query("SELECT Product_NO, USERNAME, ACCESSSTARTS, Product_NAME, date_format(mycolumn, '%d %m %Y') as shortDate FROM {$table} WHERE upper(Product_NAME) LIKE '%" . $searchString . "%'" . $max);
if($result === false) {
echo mysql_error();
}
$rows = array();
while($row = mysql_fetch_assoc($result)) {
echo "test while <p>";
$rows[] = $row;
}
return $rows;
mysql_free_result($result);
}
edit: I have printed out the mysql error of which there was none. However 8 "test whiles" are printed out, from a database with over 100 records. The foreach loop is never entereded, and I am unsure why.
The problem (or at least one of them) is in the code that reads:
$rows = getRowsByProductSearch($query, $table, $max);
$numRows = mysql_num_rows($rows);
The $numRows variable is not a MySQL resultset, it is just a normal array returned by getRowsByProductSearch.
Change the code to read:
$rows = getRowsByProductSearch($query, $table, $max);
$numRows = count($rows);
Then it should at least find some results for you.
Good luck, James
Hi there,
The next problem is with the line that reads:
$last = ceil($rows/$page_rows);
It should be changed to read:
$last = ceil($numRows / $page_rows);
Would recommend adding the following lines to the start of you script at least while debugging:
ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('display_errors', 'On');
As that would have thrown up a fatal error and saved you a whole lot of time.
if (!(isset($pg))) {
$pg = 1;
}
How is $pg going to get set? You don't appear to be reading it from $_GET. If you're relying on register_globals: don't do that! Try to read it from $_GET and parse it to a positive integer, falling back to '1' if that fails.
<a href='{$_SERVER['PHP_SELF']}?pg=$next'>Next -></a>
You appear to be losing the other parameters your page needs, 'query' and 'cmd'.
In general I'm finding it very difficult to read your code, especially the indentation-free use of echo(). Also you have untold HTML/script-injection vulnerabilities every time you "...$template..." or .concatenate a string into HTML without htmlspecialchars()ing it.
PHP is a templating language: use it, don't fight it! For example:
<?php
// Define this to allow us to output HTML-escaped strings painlessly
//
function h($s) {
echo(htmlspecialchars($s), ENT_QUOTES);
}
// Get path to self with parameters other than page number
//
$myurl= $_SERVER['PHP_SELF'].'?cmd='.urlencode($cmd).'&query='.urlencode($query);
?>
<div id="tableheader" class="tableheader">
<h1><?php h($query) ?> Sales</h1>
</div>
<div id="tablecontent" class="tablecontent">
<table border="0" width="100%"> <!-- width, border, cell width maybe better done in CSS -->
<tr>
<td width="15%">Seller ID</td>
<td width="10%">Start Date</td>
<td width="75%">Description</td>
</tr>
<?php foreach ($rows as $row) { ?>
<tr id="row-<?php h($row['Product_NO']) ?>" onclick="updateByPk('Layer2', this.id.split('-')[1]);">
<td><?php h($row['USERNAME']); ?></td>
<td><?php h($row['shortDate']); ?></td>
<td><?php h($row['Product_NAME']); ?></td>
</tr>
<?php } ?>
</table>
</div>
<div class="pagercontrols">
<?php if ($pg>1) ?>
<<- First
<?php } ?>
<?php if ($pg>2) ?>
<-- Previous
<?php } ?>
<?php if ($pg<$last-1) ?>
Next -->
<?php } ?>
<?php if ($pg<$last) ?>
Last ->>
<?php } ?>
</div>
Is it possible to have a continuous link for several items?
Across cells, no. But you're not really using a link anyway - those '#' anchors don't go anywhere. The example above puts the onclick on the table row instead. What exactly is more appropriate for accessibility depends on what exactly your application is trying to do.
(Above also assumes that the PK is actually numeric, as other characters may not be valid to put in an 'id'. You might also want to consider remove the inline "onclick" and moving the code to a script below - see "unobtrusive scripting".)
This is wrong:
if($cmd=="GetRecordSet")
echo "test in loop\n"; {
It should be:
if($cmd=="GetRecordSet") {
echo "test in loop\n";
In your getRowsByProductSearch function, you return the result of mysql_error if it occurs. In order to debug the code, maybe you can print it instead, so you can easily see what the problem is.

Categories