Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2022
  • Last Modified:

Add button to table in php page

Hi all.

I have a php file (see below), that displays data in a table. I have added a button labeled "Completed" for rows that match the criteria in the query below. Using the code below, I see the button appear for the correct rows, but when I click the button it does not go to the ProcessComplete.php file, but unfortunately it is not doing that. When I click the button it just stays on the same page.

Any idea how I can get this to work?

Thank you in advance.

<?php 
require("common.php"); 
if(!$_SESSION['user']){ 
    header("Location: index.php"); 
    exit();
    } 
$query = "SELECT FieldSuperDataEntry.DataEntryID, Builder, Community, Lot, Block,Concat(Users.firstname, ' ', Users.lastname) As Super, FieldSuperDataEntry.Type,Concat(ProjectManagers.FirstName, ' ', ProjectManagers.LastName) As ProjectManager, jobtypedescription as JobType, DATE_FORMAT(ModifiedDate,'%m/%d/%Y') As EntryDate, FieldSuperDataEntry.Status FROM BuilderCommunity LEFT OUTER JOIN FieldSuperDataEntry  ON BuilderCommunity.BuilderCommunityID = FieldSuperDataEntry.BuilderCommunityID LEFT OUTER JOIN FieldSuperAssignment ON BuilderCommunity.BuilderCommunityID = FieldSuperAssignment.BuilderCommunityID LEFT OUTER JOIN Users ON FieldSuperAssignment.UserID = Users.userid LEFT OUTER JOIN ProjectManagerAssignment ON BuilderCommunity.BuilderCommunityID = ProjectManagerAssignment.BuilderCommunityID LEFT OUTER JOIN ProjectManagers ON ProjectManagerAssignment.ProjectManagerID = ProjectManagers.ProjectManagerID  LEFT OUTER JOIN JobType ON FieldSuperDataEntry.Type = JobType.jobtypeid WHERE FieldSuperAssignment.UserID = :user_id AND FieldSuperDataEntry.Status is null   Order By Builder, Community, Lot, Block, EntryDate";


    $query_params = array( 
    ':user_id' => $_SESSION['user']['userid']     
    );

	$stmt = $db->prepare($query); 
    $result = $stmt->execute($query_params);
    $data = $stmt->fetchAll();
?> 
<html>
<title>My Page</title>
  <head>
<script type="text/javascript" src="js/jquery-latest.js"></script> 
<script type="text/javascript" src="js/jquery.tablesorter.min.js"></script> 
  <link rel="stylesheet" href="js/style.css" type="text/css" />


<script type="text/javascript">
$(document).ready(function() { 
    // call the tablesorter plugin 
    $("#Table").tablesorter({sortList: [[1,0], [2,0]]} );    
    });
</script> 
</head>
<table id="Table" class="tablesorter"> 
<thead> 
<tr> 
    <th>DataEntryID</th>
    <th>Builder</th> 
    <th>Community</th> 
    <th>Lot</th> 
    <th>Block</th> 
    <th>Job Type</th>    
    <th>Entry Date</th>     
    <th>Super</th> 
    <th>Project Manager</th> 
    <th>Status</th> 
    <th>Button</th>
      
</tr> 
</thead> 
<tbody> 
<?php foreach ($data as $row){
  echo "<tr>";
  echo "<td>".html_escape($row['DataEntryID'])."</td>";
  echo "<td>".html_escape($row['Builder'])."</td>";
  echo "<td>".html_escape($row['Community'])."</td>";
  echo "<td>".html_escape($row['Lot'])."</td>";
  echo "<td>".html_escape($row['Block'])."</td>";
  echo "<td>".html_escape($row['JobType'])."</td>"; 
  echo "<td>".html_escape($row['EntryDate'])."</td>";     
  echo "<td>".html_escape($row['Super'])."</td>";
  echo "<td>".html_escape($row['ProjectManager'])."</td>";
  echo "<td>".html_escape($row['Status'])."</td>";  
 if ($row['Type'] == 2 AND	$row['Status'] <> "Completed") {
                     echo "<td><input class='button8'  type='submit' formaction='ProcessComplete.php' formmethod='post' value='Completed'/></td>"; }   


  echo "</tr>";
  }?> 

</tbody> 
</table> 	
</html>

Open in new window

0
Sim1980
Asked:
Sim1980
  • 7
  • 7
  • 3
  • +1
2 Solutions
 
leakim971PluritechnicianCommented:
do a right click on the page in your browser, choose view source and post it here
0
 
Marco GasiFreelancerCommented:
you have no form, so the button doesn't do any action. I think each row should be a form with its own data and its own submit button: add the forms and it will work...
0
 
Marco GasiFreelancerCommented:
"I have added a button labeled "Completed" for rows that match the criteria in the query below"
That is all rows, since you're printing rows which reuslt from the query: or am I missing something?

Another question is: what should happen in ProcessComplete.php?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Chris StanyonCommented:
marqusG is on the right track here - you have no form - only lots of invalid buttons:

<input class='button8'  type='submit' formaction='ProcessComplete.php' formmethod='post' value='Completed'/>

Open in new window

A submit button doesn't have formaction and formmethod attributes. These belong in a form:

<form method="post" action="ProcessComplete.php">
   <input type="submit" value="Complete">
</form>

Open in new window

Depending on what you need to do with ProcessComplete and how you intend to do it, you may have to wrap other data inside the form - maybe in hidden fields so they get POSTed to your script.

FYI - you may also have problems with your table - some rows will have 10 TDs and some will have 11...
0
 
Sim1980Author Commented:
Thanks marqusG, I added the form tags as you suggested and at least now it is going to the ProcessCompleted.php file but it's not doing the update that the ProcessCompleted.php file is supposed to do.

Here's the 2 files:

WorkDataTable.php:
<?php 

// First we execute our common code to connection to the database and start the session 
require("common.php"); 
if(!$_SESSION['user']){ 
    header("Location: index.php"); 
    exit();
    } 
$query = "SELECT FieldSuperDataEntry.DataEntryID, Builder, Community, Lot, Block,Concat(Users.firstname, ' ', Users.lastname) As Super, FieldSuperDataEntry.Type,Concat(ProjectManagers.FirstName, ' ', ProjectManagers.LastName) As ProjectManager, jobtypedescription as JobType, DATE_FORMAT(ModifiedDate,'%m/%d/%Y') As EntryDate, FieldSuperDataEntry.Status FROM BuilderCommunity LEFT OUTER JOIN FieldSuperDataEntry  ON BuilderCommunity.BuilderCommunityID = FieldSuperDataEntry.BuilderCommunityID LEFT OUTER JOIN FieldSuperAssignment ON BuilderCommunity.BuilderCommunityID = FieldSuperAssignment.BuilderCommunityID LEFT OUTER JOIN Users ON FieldSuperAssignment.UserID = Users.userid LEFT OUTER JOIN ProjectManagerAssignment ON BuilderCommunity.BuilderCommunityID = ProjectManagerAssignment.BuilderCommunityID LEFT OUTER JOIN ProjectManagers ON ProjectManagerAssignment.ProjectManagerID = ProjectManagers.ProjectManagerID  LEFT OUTER JOIN JobType ON FieldSuperDataEntry.Type = JobType.jobtypeid WHERE FieldSuperAssignment.UserID = :user_id AND FieldSuperDataEntry.Status is null   Order By Builder, Community, Lot, Block, EntryDate";


    $query_params = array( 
    ':user_id' => $_SESSION['user']['userid']     
    );

	$stmt = $db->prepare($query); 
    $result = $stmt->execute($query_params);
    $data = $stmt->fetchAll();
  $_SESSION['action_token1'] = generate_secure_token(); 
?> 
<html>
<title>MyPage</title>
  <head>
<script type="text/javascript" src="js/jquery-latest.js"></script> 
<script type="text/javascript" src="js/jquery.tablesorter.min.js"></script> 
  <link rel="stylesheet" href="js/style.css" type="text/css" />


<script type="text/javascript">
$(document).ready(function() { 
    // call the tablesorter plugin 
    $("#Table").tablesorter({sortList: [[0,0], [1,0]]} );    
    });
</script> 
</head>
<form action="ProcessCompleted.php" method="post">
<table id="Table" class="tablesorter"> 
<thead> 
<tr> 

    <th>Builder</th> 
    <th>Community</th> 
    <th>Lot</th> 
    <th>Block</th> 
    <th>Job Type</th>    
    <th>Entry Date</th>     
    <th>Super</th> 
    <th>Project Manager</th> 
    <th>Status</th> 
    <th>ID</th>
    <th>Button</th>
     
      
</tr> 
</thead> 
<tbody> 

<?php foreach ($data as $row){
  echo "<tr>";
  

  echo "<td>".html_escape($row['Builder'])."</td>";
  echo "<td>".html_escape($row['Community'])."</td>";
  echo "<td>".html_escape($row['Lot'])."</td>";
  echo "<td>".html_escape($row['Block'])."</td>";
  echo "<td>".html_escape($row['JobType'])."</td>"; 
  echo "<td>".html_escape($row['EntryDate'])."</td>";     
  echo "<td>".html_escape($row['Super'])."</td>";
  echo "<td>".html_escape($row['ProjectManager'])."</td>";
  echo "<td>".html_escape($row['Status'])."</td>";  
if ($row['Type'] == 2 AND	$row['Status'] <> "Completed") {
echo "<td><input name='DataEntryID' input id='DataEntryID' value=".html_escape($row['DataEntryID'])."></td>";
                     echo "<td><input class='button8'  type='submit'  value='Completed'/></td>"; 
                     
                                               
                     }   


  echo "</tr>";
  }?> 
   <input type="hidden" name="action_token1" value="<?php echo html_escape($_SESSION['action_token1']) ?>" />
</form>
</tbody> 
</table> 
	
</html>

Open in new window


ProcessCompleted.php:

<?php 
    // First we execute our common code to connection to the database and start the session 
   require("common.php");
   require("class.phpmailer.php");
       
    if (isset($_SESSION['user'])){   // check session
     
      if (isset($_POST)) {  //This if statement checks to determine whether the form has been submitted, If it has, then the code is run, otherwise the form is displayed  
           if (isset($_POST['action_token1']) && isset($_SESSION['action_token1']) && $_POST['action_token1'] == $_SESSION['action_token1']) {      // check request token
              

          $date = new DateTime();
          $date->setTimezone(new DateTimeZone('America/New_York'));
          $fdate = $date->format('Y-m-d H:i:s');
                           
		  $query = "UPDATE FieldSuperDataEntry set Status = 'Completed', StatusDate = :completiondate WHERE DataEntryID = :dataentryid "; 

 
          $query_params = array( 
            ':dataentryid' => $_POST['DataEntryID'],
            ':completiondate' => $fdate
            ); 
        
            $stmt = $db->prepare($query); 
            $result = $stmt->execute($query_params); 

        unset( $_SESSION['action_token'] );
          header('Location: Menu.php');
        exit();
       
 
       }    // Close check request token
      
       else {        // possible CSRF attempt 
            echo 'invalid submission'; 
            trigger_error('possible CSRF attack', E_USER_ERROR);    
            exit; 
        } 
      
      }  // Close isset($POST) if statement    
    } // Close check session
 
?> 

Open in new window

0
 
Marco GasiFreelancerCommented:
@Chris: this is the first time I hear about formaction and formmethod but they exist! Check the link I found and provided above: they say these attribute has the goal to allow to have two submit buttons, one which uses the form action attribute and one which uses button formaction overriding from action attribute. EE is useful to know latest updates ;)

Please, in ProcessComplete.php put at the top a beautyful var_dump to check if data is posted as exepected:

<?php 
    // First we execute our common code to connection to the database and start the session 
   require("common.php");
   require("class.phpmailer.php");
   echo "<pre>";
   var_dump($_SESSION); //so we can check at the same moment if issett $_SESSION['user']
   var_dump($_POST); 
   echo "</pre>";

 .....

Open in new window

0
 
Chris StanyonCommented:
Your code now generates 1 form with lots of buttons and lots of INPUTs with the same name and the same ID - this will never work.

You are probably better of either creating a new form on each row (so just wrap the button, the DataEntryID and the action_token1 values ) in your TD, or taking an AJAX approach (recommended!)

if ($row['Type'] == 2 && $row['Status'] <> "Completed") {
   echo "<td>
      <form action='ProcessCompleted.php' method='post'>
         <input class='button8'  type='submit'  value='Completed'/>
         <input type='hidden' name='action_token1' value='" . html_escape($_SESSION['action_token1']) . "'/>
         <input type='hidden' name='DataEntryID' value='" . html_escape($row['DataEntryID']) . "'/>
      </form>
   </td>";
}

Open in new window

0
 
Chris StanyonCommented:
OK Marqus - didn't know about them, but having said that they are HTML5 and not supported in IE9 and less, so I'd still stay away from them :)
0
 
Marco GasiFreelancerCommented:
@ChrisOh yes, I stay away me too! :)

@Sim1980: Chris is right I forgot to post my suiggestion for code (today I0m doing saeveral stranges things and my wife and my gaughters worry a bit :)

<table id="Table" class="tablesorter"> 
<thead> 
<tr> 
    <th>DataEntryID</th>
    <th>Builder</th> 
    <th>Community</th> 
    <th>Lot</th> 
    <th>Block</th> 
    <th>Job Type</th>    
    <th>Entry Date</th>     
    <th>Super</th> 
    <th>Project Manager</th> 
    <th>Status</th> 
    <th>Button</th>
      
</tr> 
</thead> 
<tbody> 
<?php foreach ($data as $row){
  echo "<tr><form>";
  echo "<td input type='hidden' name='DataEntryID' value='". html_escape($row['DataEntryID']) .">".html_escape($row['DataEntryID'])."</td>";
  echo "<td input type='hidden' name='Builder' value='". html_escape($row['Builder']) .">".html_escape($row['Builder'])."</td>";
  echo "<td input type='hidden' name='Community' value='". html_escape($row['Community']) .">".html_escape($row['Community'])."</td>";
  echo "<td input type='hidden' name='Lot' value='". html_escape($row['Lot']) .">".html_escape($row['Lot'])."</td>";
  echo "<td input type='hidden' name='Block' value='". html_escape($row['Block']) .">".html_escape($row['Block'])."</td>";
  echo "<td input type='hidden' name='JobType' value='". html_escape($row['JobType']) .">".html_escape($row['JobType'])."</td>";
  echo "<td input type='hidden' name='EntryDate' value='". html_escape($row['EntryDate']) .">".html_escape($row['EntryDate'])."</td>";
  echo "<td input type='hidden' name='Super' value='". html_escape($row['Super']) .">".html_escape($row['Super'])."</td>";
  echo "<td input type='hidden' name='ProjectManager' value='". html_escape($row['ProjectManager']) .">".html_escape($row['ProjectManager'])."</td>";
  echo "<td input type='hidden' name='Status' value='". html_escape($row['Status']) .">".html_escape($row['Status'])."</td>";
 if ($row['Type'] == 2 AND	$row['Status'] <> "Completed") {
                     echo "<td><input class='button8'  type='submit' formaction='ProcessComplete.php' formmethod='post' value='Completed'/></td>"; }   


  echo "</form></tr>";
  }?> 

</tbody> 
</table> 	

Open in new window

0
 
Chris StanyonCommented:
MarqusG - that's going to produce some very odd HTML!!

The only thing you can have inside a TR is a TD or a TH - not a form. Also, look at your TDs:

<td input type='hidden'...!

The script needs 2 POST keys - action_token1 and DataEntryID
0
 
Marco GasiFreelancerCommented:
About <td input... I'll cry later :(
@sim1980, please use this <td><input...

About the odd html... yes I agree, but I don't know how to do it better: but I'm ready to learn! :)
0
 
Sim1980Author Commented:
Thank you both! I got it to work now. marqusG thank you for suggesting the form tags and ChrisStanyon thank you for advising I should put the form tags in each row instead of before the table tags.

I will split the points up. Thanks again!
0
 
Chris StanyonCommented:
No worries.

For the record - my approach would be something like this:

<tbody> 
<?php foreach ($data as $row): ?>
<tr>
	<td><?php echo html_escape($row['DataEntryID']) ?></td>
	<td><?php echo html_escape($row['Builder']) ?></td>
	<td><?php echo html_escape($row['Community']) ?></td>
	<td><?php echo html_escape($row['Lot']) ?></td>
	<td><?php echo html_escape($row['Block']) ?></td>
	<td><?php echo html_escape($row['JobType']) ?></td> 
	<td><?php echo html_escape($row['EntryDate']) ?></td>     
	<td><?php echo html_escape($row['Super']) ?></td>
	<td><?php echo html_escape($row['ProjectManager']) ?></td>
	<td><?php echo html_escape($row['Status']) ?></td>
	<td>
	<?php if ($row['Type'] == 2 && $row['Status'] <> "Completed"): ?>
	<form method="post" action="ProcessCompleted.php">
		<input type="hidden" name="action_token1" value="<?php echo html_escape($_SESSION['action_token1']) ?>" />
		<input type="hidden" name="DataEntryID" value="<?php echo html_escape($row['DataEntryID']) ?>" />
		<input class='button8' type='submit' value='Completed' />
	</form>
	<?php endif; ?>
	</td>
</tr>
<?php endforeach; ?> 
</tbody>

Open in new window

Although I'd probably go the AJAX route ;)
0
 
Sim1980Author Commented:
Chris,

Doing it your way, would that remove the gray filling in the table cells with no button?

Currently, if the button does not appear then the cell is filled in gray.
0
 
Chris StanyonCommented:
The way you've got it at the moment, the IF statement will create an extra TD for the button, so if there's no need for the button there will be one less TD, which is probably why you're getting the grey fill - uneven numbers of the TDs! The grey fill will be down to your CSS which we haven't seen.

The uneven number of TDs is invalid HTML!! However, if that's the behaviour you really want just move the TD inside the IF statement:

<?php if ($row['Type'] == 2 && $row['Status'] <> "Completed"): ?>
<td>
	<form method="post" action="ProcessCompleted.php">
		<input type="hidden" name="action_token1" value="<?php echo html_escape($_SESSION['action_token1']) ?>" />
		<input type="hidden" name="DataEntryID" value="<?php echo html_escape($row['DataEntryID']) ?>" />
		<input class='button8' type='submit' value='Completed' />
	</form>
</td>
<?php endif; ?>

Open in new window

0
 
Marco GasiFreelancerCommented:
@Chris: "The uneven number of TDs is invalid HTML!! " Really?! Do you know what is the technical reason why a table shouldn't have an odd number of tds? This sounds like a MySql table must have an even number of columns, and the number of columns responds to the program logic, it's not a formal question, I think....

@Sim1980, thanks for points and good luck with your project.
0
 
Chris StanyonCommented:
When I said uneven, I didn't mean it in the context of odd/even - I meant it as in 'not the same'. The logic that was used in the original code meant that some rows would have 10 TDs and some would have 11 - which is invalid.

As for your mySQL analogy - you can't have 1 record with 10 columns and the next record with 11 - all records have to have the same number of columns - they all have 10 or they all have 11!
0
 
Marco GasiFreelancerCommented:
Oh, yes, I misunderstood your 'uneven' sense. About MySql analogy, it was a consequence of my misunderstanding...
Cheers
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 7
  • 7
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now