Link to home
Start Free TrialLog in
Avatar of Peter Kroman
Peter KromanFlag for Denmark

asked on

Collapse and expand HTML table created form mySQL query

Hi,
I am working on a project where I have a MySQL database with +6.000 lines. The database is designed to search and find genealogical books from various sources.
I display data from the database in a table, and I need to be able define some of the rows as rows that can be expanded with a subrows (not a fixed number of rows), and that can be collapsed again when the expanded view is no longer needed.
All rows in the table has exactly the same content structure, and should be presented exactly alike in the table.
So it just the feature to expand and collapse chosen rows in the table I am after here.

This is the code I use right now to display my table (not collapsible):

            echo "<table><tr><th>Sogn</th> <th>Kirkebog</th> <th>Herred</th> <th>Amt</th> <th>Info</th> </tr>  " .$results['Sogn'];
 
            while($row = $result=mysqli_fetch_array($raw_results)) {
            echo "<tr><td>" . $row["Sogn"]. "</td><td>";
            if ($row["URL"]=="")
            echo  $row["Kirkebog"]."<td>". $row["Herred"]. "<td>" . $row["Amt"]. $row["Info"]."<td>";  
              else
            echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" . $row["Kirkebog"]."<td>" .  $row["Herred"]. "<td>" . $row["Amt"]. "<td>"."<a href=\"".$row["Infourl"]."\"target=\"_blank\">" .$row["Info"]. "<td>". "</a>";
            echo "</td></tr>";
    }
             echo "</table>";
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

A simple way to do this is to wrap your 'groups' of records (main row and collapsed rows) into a container such as a <tbody>, hide the collapsible rows with CSS, add a toggle (expand) button and bind that to a jQuey event. The button will then toggle the visibility of the collapsed rows.

Have a look at this to get the idea: https://jsfiddle.net/ChrisStanyon/mo77z6p3/

You'll see each group is wrapped in a tbody. The collapsible rows have a class called expander, which are hidden with CSS. The toggle button then toggles the visibility of these rows as needed
Avatar of Peter Kroman

ASKER

Thanks @Chris Stanyon,

I will work with your proposed solution - it sounds simple and effective :)

Best regards
Peter
Hi @Chris Stanyon,

I have been working with your proposal. I believe that what you show is a little different from what I need.

I am creating a table from a mySQL query, and I what I need is some chosen rows in the table to be parent rows with a number of collapsible rows below.

I am showing the SQL query and the table display code below. It is all in php code.

So my question is: How do I  make use of your row collapse code in this scenario :)

   
    $query = trim($_POST['query_start']);
    $query2 = trim($_POST['query_end']);
     
   
    $min_length = 4;
   

    if(strlen($query) >= $min_length || strlen($query2) >= $min_length) {


        $query = htmlspecialchars($query,ENT_QUOTES,"utf-8");
        $query2 = htmlspecialchars($query2,ENT_QUOTES,"utf-8");
           

        $query = mysqli_real_escape_string($con, $query);
        $query2 = mysqli_real_escape_string($con, $query2);
   

        $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Aar = '$query') OR (Aar BETWEEN '$query' AND '$query2')")or die(mysql_error());
       

        if(mysqli_num_rows($raw_results) > 0){


             echo "<table><tr><th>Type</th> <th>Område</th> <th>År</th> <th>Link</th> </tr>  " .$results['Aar'];
             
 
            while($row = $result=mysqli_fetch_array($raw_results)) {
           

            echo "<tr><td>" . $row["Type"]. "</td><td>";


            if ($row["URL"]=="")
            echo  $row["Område"]."<td>". $row["Aar"]. "<td>" . $row["Info"]. "<td>";  
 
            else
            echo $row["Område"]."<td>" .  "<a href=\"".$row["URL"]."\"target=\"_blank\">" . $row["Aar"].  "<td>"."<a href=\"".$row["Infourl"]."\"target=\"_blank\">" .$row["Info"]. "<td>". "</a>";



            echo "</td></tr>";

           
    }
             echo "</table>";
The principle still applies. Wrap your groups in a <tbody>.

How in your code do you identify which is a parent row and which rows should be collapsible.

FYI - the code you've just posted will generate invalid HTML. You have no closing </td> tags and in the else block, you're dropping a <td> inside the <a> tag.
Hi again,

I have a column in the db-table I call "Collapse". Here I mark parent rows with "p" and child rows with "c".

The code I sent was just a part of the total code. It is working, I use it. Anyway I need to use the collapse function in another peace of code which I paste in total below.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<head>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="utf-8" lang="da" >
      <title>Christianshavns kvarter Matr. Nr. 001-200</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8; lang="da" />




<!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;


   
}

table, td {
   
   
    border-style: 1 px solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:#666666;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: left;


   
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}
</style>
<!-- End of search styles -->


</head>


<body>
 




<!-- Search code starts here -->
<?php
   
    $con=mysqli_connect("myserver", "myuser", "mypassword", "my db") or die("Error connecting to database: ".mysql_error());
   
    mysqli_select_db($con,"mydb");
   
    mysqli_set_charset($con,"utf8");
   
?>


   
<div class="flex-container" style="width:site-width; background-color:white;">
<div class="flex-item" style="margin-top:10px; float:left; margin-left:20px;width: site-width; overflow:auto;">

<?php

$sql = "SELECT Område, Aar, Matr, Gade, URL, Info, Infourl FROM ft_kbh_kvarter_gader WHERE `Område` = 'Christianshavns kvarter Matr. Nr. 001-200' ";

$result = $con->query($sql);

if ($result->num_rows > 0) {
   
   


             echo "<table><tr><th>Område</th> <th>Aar</th> <th>Matr</th> <th>Gade</th> <th>Bogen</th> </tr>  ";
             
 
            while($row = $result->fetch_assoc()) {
           

            echo "<tr><td>" ;


           
            echo $row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" .$row["Gade"].  "<td>". "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";

            echo "</td></tr>";

           
    }
             echo "</table>";
                       

        }else{

            echo "Der er ingen resultater i denne søgning";
        }        
   
mysqli_close($con);

?>


   
</div>
</div>





<!-- End of search code -->



</body>






</html>
@Chris Stanyon

Hi Chris,

Is there a chance that you can help me with some inspiration on how to write the "collapse - code" into the scenario above.
I have tried, but I can't get it working.
Hope you can help me out with this :)

Best regards
Peter
Sure. Have a read through this and see if it makes sense. As I've said previously, basically you wrap your collapsible group into a <tbody> and then expand and collapse that. Obviously this will only work if the records in your query are returned in a sensible order - i.e. the relevant child records are returned after the parent record:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Chris Stanyon</title>

        <style type="text/css">
            tbody tr { display: none; background-color: #d5d5d5; }
            tbody tr.expander { display: table-row; background-color: initial; }
            span { cursor: pointer; color: #aa0000; }
            span:hover { color: #00aa00; }
        </style>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {
                $('#myTable').on('click', '.toggle', function() {
                    $(this).parents('tr').nextAll('tr').toggle();
                });
            });
        </script>
    </head>

    <body>
        <table id="myTable">
            <col style="width: 100px;" />
            <col style="width: 100px;" />
            <col style="width: 100px;" />
            <col style="width: 50px;" />

            <?php
            // Connect to your Db
            $con = mysqli_connect("localhost", "yourUsername", "yourPassword", "yourDb");

            // Run your Query
            $rows = $con->query("SELECT Collapse, Field1, Field2, Field3 FROM yourTable");

            // Loop through the results
            while ($row = $rows->fetch_object()):
            ?>

                <?php if ($row->Collapse == 'p'): ?>

                <tbody>
                <tr class='expander'>
                    <td><?php echo $row->Field1 ?></td>
                    <td><?php echo $row->Field2 ?></td>
                    <td><?php echo $row->Field3 ?></td>
                    <td><span class='toggle'>Toggle</span></td>
                </tr>

                <?php else: ?>

                <tr>
                    <td><?php echo $row->Field1 ?></td>
                    <td><?php echo $row->Field2 ?></td>
                    <td><?php echo $row->Field3 ?></td>
                    <td></td>
                </tr>

                <?php endif; ?>

            <?php endwhile; ?>

        </table>
    </body>
</html>

Open in new window

Thanks a lot Chris,

I will work with it, and let you know if I can get it working :)

Best regards
Peter
Hi Chris,

This is really teasing me :)

I can get your code working - take a look here: http://kroweb.dk/gfdev/collapse/
But this is only part of the way.
My site looks like this: http://kroweb.dk/gfdev/ft_raw/
As you can see I have three search fields at the top. If you type 1860 in the first (far left) field it returns a very long list where it all rows under a black + I need to toggle.

I am presenting the search results a little different depending on content/no content in searchfield 3 ($query3)
The toggle is only needed when searchfield 3 ($query3) is empty.

I have tried all the ways I could think of to work your code into mine, but I can't get it working.

I paste in my full working code here, and mark inside the code with bold and underlined where I believe the toggle code should be located, and hope that you can give me the direction on how to place the code right.

I also need your help on to smaller issues: 1. I would like to have the toggle link placed to the left in stead of to the right of the rows. 2. I would like to use an icon in stead of a text to activate the toggle.

Hope you have the patience to help me out here.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<head>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="utf-8" lang="da" >
      <title>ft_raw_dev</title>
 <meta http-equiv="Content-Type" content="text/html"; charset=utf-8; lang="da" /> 




<!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;



    
}

table, td {
   
    border: 1px  #f6f6f6;
    border-style: none;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: padding-left;


    
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}

.flex-container {
    display: -webkit-flex;
    display: inline-flex;
    flex-direction:row;
    background-color:#f6f6f6;
    width:100%;
}



</style>
<!-- End of search styles -->


</head>


<body>
   <!-- Søge felt til folketællinger -->
  
    <div class="flex-container">
   
    <div class="flex-item"><form action="" style="padding-top:10px; padding-bottom:10px; " method="POST" > 
    
    <input type="text" style="margin-left:30px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_start"  />
    Start år
 
</div>  
   
    <div class="flex-item "style="padding-top:10px; padding-bottom:10px; ">
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_end"  />
    Slut år


    
        <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>

        <input type="submit" style="margin-left:5px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);;" value="Nulstil"/>
</div>  


   <div class="flex-item" style="padding-top:10px; padding-bottom:10px; " > 
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:250px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_gade"  />
    

 <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>
 
  

   



 

</div>  


</form>

 

<!-- Search code starts here -->
<?php
     if ((isset($_POST['query_start'])) && (trim($_POST['query_start'])!="") || (isset($_POST['query_end'])) && (trim($_POST['query_end'])!="") || (isset($_POST['query_gade'])) && (trim($_POST['query_gade'])!="")) {
    $con=mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database: ".mysql_error());
    
    mysqli_select_db($con,"genealogiskforum_dk_db9");
    
    mysqli_set_charset($con,"utf8");

    
    
?> 


</div>    
<div class="flex-container" style="width:site-width; background-color:white;">
<div class="flex-item" style="margin-top:10px; float:left; margin-left:20px;width: site-width; overflow:auto;">



<?php
    
    $query = trim($_POST['query_start']); 
    $query2 = trim($_POST['query_end']);
    $query3 = trim($_POST['query_gade']);
      
//echo "Det virker hertil 0";
    
    $min_length = 4;
   

    if(strlen($query) >= $min_length || strlen($query2) >= $min_length || strlen($query3) >= $min_length) {


         $query = htmlspecialchars($query,ENT_QUOTES,"utf-8"); 
        $query2 = htmlspecialchars($query2,ENT_QUOTES,"utf-8");
        $query3 = htmlspecialchars($query3,ENT_QUOTES,"utf-8");
            

        $query = mysqli_real_escape_string($con, $query);
        $query2 = mysqli_real_escape_string($con, $query2);
        $query3 = mysqli_real_escape_string($con, $query3);
        // makes sure nobody uses SQL injection

//echo "Det virker hertil 1";        

         if ($query3=="")
{
[u][b]          //I belive the code shoul be located around here, because I am handling the situation where $query3 is empty right here[/b][/u]
         
            $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Aar = '$query') OR (Aar BETWEEN '$query' AND '$query2') ")or die(mysql_error());
}
else
{
         
         $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Gade LIKE '%".$query3."%')")or die(mysql_error());
}
         



        

        if(mysqli_num_rows($raw_results) > 0){ 

//print "query_start= " .$query;
//print "  ";
//print "query_end= " .$query2;
//print "  ";
//print "query_gade= " .$query3;
//echo "Det virker hertil 2";

             echo "<table><tr><th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> </tr>  " .$results['Aar'];
             
 
            while($row = $result=mysqli_fetch_array($raw_results)) {
           

            echo "<tr><td>" ;

            

            if ($row["Collapse"]=="")
            echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";

   
           elseif ($row["Collapse"]<>"")
            echo $row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" .$row["Gade"].  "<td>".  $row["Info"].  "<td>"."</a>";

        
   // Sæt tbody ind her
           


            echo "</td></tr>";
//Fjernes
            
    }
             echo "</table>"; 

                 

        }else{ // if there is no matching rows do following

            echo "Der er ingen resultater for denne søgning";
        }         
    }else{ // if query length is less than minimum

        echo "Mindste antal tegn er ".$min_length;
    }
mysqli_close($con);
}
?>


 
</div> 
</div> 

<!-- End of search code -->




</body>

</html>

Open in new window

Perhaps you would see the code that I have got working too. It only works partly because it only shows the toggle rows, and all other functionality is not there. Just a thought :)

<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8" lang="da">
        <title>collapse</title>
        <meta http-equiv="Content-Type" content="text/html"; charset=utf-8; lang="da" /> 

        <style type="text/css">
            tbody tr { display: none; background-color: #d5d5d5; }
            tbody tr.expander { display: table-row; background-color: initial; }
            tr:nth-child(even){background-color: #f6f6f6}
            span { cursor: pointer; color: #aa0000; }
            span:hover { color: #00aa00; }
        </style>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {
                $('#myTable').on('click', '.toggle', function() {
                    $(this).parents('tr').nextAll('tr').toggle();
                });
            });
        </script>
        <!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;



    
}

table, td {
   
    border: 1px  #f6f6f6;
    border-style: none;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: padding-left;


    
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}

.flex-container {
    display: -webkit-flex;
    display: inline-flex;
    flex-direction:row;
    background-color:#f6f6f6;
    width:100%;
}

.expander {
  display: none;
}

.expander td:first-child {
  text-indent: 20px
}





</style>
<!-- End of search styles -->


    </head>

    <body>
          
   <table id="myTable">
       

        
 <!-- Search code starts here -->
<?php
    
    $con=mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database: ".mysql_error());
    
    mysqli_select_db($con,"genealogiskforum_dk_db9");
    
    mysqli_set_charset($con,"utf8");

    
    

    
            // Run your Query
            $rows = $con->query("SELECT Collapse, Område, Aar, Matr, Gade, Info FROM folketaellinger");

            // Loop through the results
            while ($row = $rows->fetch_object()):
            ?>

                <?php if ($row->Collapse == 'p'): ?>

                <tbody>
                <tr class='expander'>
                    <td><?php echo $row->Område ?></td>
                    <td><?php echo $row->Aar ?></td>
                    <td><?php echo $row->Matr ?></td>
                    <td><?php echo $row->Gade ?></td>
                    <td><?php echo $row->Info ?></td>
                    <td><span class='toggle'>Toggle</span></td>
                </tr>

                <?php else: ?>

                <tr>
                    <td><?php echo $row->Område ?></td>
                    <td><?php echo $row->Aar ?></td>
                    <td><?php echo $row->Matr ?></td>
                    <td><?php echo $row->Gade ?></td>
                    <td><?php echo $row->Info ?></td>
                    <td></td>
                </tr>

                <?php endif; ?>

            <?php endwhile; ?>

        </table>
 



<!-- End of search code -->



    </body>
</html>

Open in new window

In your full code above, you would need to build the table at around line 216. To have the toggle icon the left, just set the content of the first TD instead of the last

while($row = mysqli_fetch_array($raw_results)) {
    if ($row['Collapse'] == 'p'):

        echo "<tbody>";
        echo "<tr class='expander'>";
        // echo your row data here
        echo "<td><span class='toggle'>yourIcon</span><td><td>...</td><td>...</td>
        echo "</tr>";

    else:

        echo "<tr>"
        // echo your row data here
        echo "<td><td><td>...</td><td>...</td>
        echo "</tr>";

    endif;
endwhile;

Open in new window

The easiest way to not add the toggle functionality would probably be to set a flag and then use this to echo out (or not) various parts of the HTML. For example:

if ($query3=="")
{
    $toggle = false;
    $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger WHERE (Aar = '$query') OR (Aar BETWEEN '$query' AND '$query2') ") or die(mysql_error());
}
else
{
    $toggle = true;
    $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger WHERE (Gade LIKE '%".$query3."%')") or die(mysql_error());
}

Open in new window

The in your HTML you can choose which parts to echo (using the tenary operator):

echo ($toggle) ? "<tbody>" : "";
....
echo ($toggle) ? "<span class='toggle'>yourIcon</span>" : "";
....
echo ($toggle) ? "<tr class='expander'>" : "<tr>";

Open in new window


You may also need to edit your query so that the field Collapse is always returned as empty instead of the 'p' text:

SELECT '' AS Collapse, Field1, Field2, Field3 FROM yourTable;
I am still struggling :) But I believe that we are getting closer now.

I have managed to get the toggle code into my code, but it doses not return the table headlines or a table at all, and it only returns the values for the row "Område" . But it does return something, which is a step forward I believe.
You can check here entering e.g. 1860 in the first search field: http://kroweb.dk/gfdev/ft_raw/

Here is the code as it is now:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<head>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="utf-8" lang="da" >
      <title>gfdev/ft_raw</title>
 <meta http-equiv="Content-Type" content="text/html"; charset=utf-8; lang="da" /> 

      <style type="text/css">
            tbody tr { display: none; background-color: #d5d5d5; }
            tbody tr.expander { display: table-row; background-color: initial; }
            tr:nth-child(even){background-color: #f6f6f6}
            span { cursor: pointer; color: #aa0000; }
            span:hover { color: #00aa00; }
        </style>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {
                $('#myTable').on('click', '.toggle', function() {
                    $(this).parents('tr').nextAll('tr').toggle();
                });
            });
        </script>


<!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;



    
}

table, td {
   
    border: 1px  #f6f6f6;
    border-style: none;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: padding-left;


    
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}

.flex-container {
    display: -webkit-flex;
    display: inline-flex;
    flex-direction:row;
    background-color:#f6f6f6;
    width:100%;
}

.expander {
  display: none;
}

.expander {
  display: none;
}

.expander td:first-child {
  text-indent: 10px
}

span {
  cursor: pointer;
  color: grey;
  font-family: FontAwesome;
}

span:hover {
  color: black;
}

span.toggle:after {
  content: '\f055';
}


</style>
<!-- End of search styles -->


</head>


<body>
   <!-- Søge felt til folketællinger -->
  
    <div class="flex-container">
   
    <div class="flex-item"><form action="" style="padding-top:10px; padding-bottom:10px; " method="POST" > 
    
    <input type="text" style="margin-left:30px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_start"  />
    Start år
 
</div>  
   
    <div class="flex-item "style="padding-top:10px; padding-bottom:10px; ">
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_end"  />
    Slut år


    
        <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>

        <input type="submit" style="margin-left:5px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);;" value="Nulstil"/>
</div>  


   <div class="flex-item" style="padding-top:10px; padding-bottom:10px; " > 
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:250px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_gade"  />
    

 <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>
 
  

   



 

</div>  


</form>

 

<!-- Search code starts here -->

<?php
     if ((isset($_POST['query_start'])) && (trim($_POST['query_start'])!="") || (isset($_POST['query_end'])) && (trim($_POST['query_end'])!="") || (isset($_POST['query_gade'])) && (trim($_POST['query_gade'])!="")) {
    $con=mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database: ".mysql_error());
    
    mysqli_select_db($con,"genealogiskforum_dk_db9");
    
    mysqli_set_charset($con,"utf8");

    
    
?> 


</div>    
<div class="flex-container" style="width:site-width; background-color:white;">
<div class="flex-item" style="margin-top:10px; float:left; margin-left:20px;width: site-width; overflow:auto;">



<?php
    
    $query = trim($_POST['query_start']); 
    $query2 = trim($_POST['query_end']);
    $query3 = trim($_POST['query_gade']);
      

    
    $min_length = 1;
   

    if(strlen($query) >= $min_length || strlen($query2) >= $min_length || strlen($query3) >= $min_length) {


         $query = htmlspecialchars($query,ENT_QUOTES,"utf-8"); 
        $query2 = htmlspecialchars($query2,ENT_QUOTES,"utf-8");
        $query3 = htmlspecialchars($query3,ENT_QUOTES,"utf-8");
            

        $query = mysqli_real_escape_string($con, $query);
        $query2 = mysqli_real_escape_string($con, $query2);
        $query3 = mysqli_real_escape_string($con, $query3);
        // makes sure nobody uses SQL injection

       

         if ($query3=="")
{
          
          $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Aar = '$query') OR (Aar BETWEEN '$query' AND '$query2') ")or die(mysql_error());
}
else
{
         
         $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Gade LIKE '%".$query3."%')")or die(mysql_error());
}
         


?>
<table id="myTable">
   
    <?php
        

        if(mysqli_num_rows($raw_results) > 0){ 



             echo "<table><tr><th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> </tr>  " .$results['Aar'];
             
 
            while($row = $result=mysqli_fetch_array($raw_results)) {
           

            if ($row['Collapse'] == 'p')
{                
        echo "<table>";
        echo "<tbody>";
        echo "<tr class='expander'>";
        // echo your row data here
         echo "<td><span class='toggle'";
         echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"];
         echo "</tr>";
}
    else
{
        echo "<tr>";
        // echo your row data here
        echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";
        echo "</tr>";
}
//    endif;
//endwhile;

            //echo "<tr><td>" ;

            

            //if ($row["Collapse"]=="")
            //echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";

   
           //elseif ($row["Collapse"]<>"")
            //echo $row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" .$row["Gade"].  "<td>".  $row["Info"].  "<td>"."</a>";

        

           


            //echo "</td></tr>";

            
    }
             echo "</table>"; 

                 

        }else{ // if there is no matching rows do following

            echo "Der er ingen resultater for denne søgning";
        }         
    }else{ // if query length is less than minimum

        echo "Mindste antal tegn er ".$min_length;
    }
mysqli_close($con);
}
?>


 
</div> 
</div> 

<!-- End of search code -->




</body>

</html>

Open in new window

On lines 245 and 262 you seem to have extra <table> tags that you don't need. Remove them. You're currently wrapping tables inside tables inside tables!!
I have removed lines 245 and 262. It does not make any difference.
OK Peter. I think many of these problems are because you have invalid HTML. If you're using Firefox, then load up your page and your table rows and then View Source (Ctrl+U) - anything you see in Red is an HTML error. For your site to work correctly, you need ZERO errors.

If you look at line 274 for example:

  echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";

This basically comes out as:

<a href="someLink"target="_blank">text<td>text<td>text<td>text<td><a href="someLink"target="_blank">text<td></a>

You can see from that line alone there are at least 8 HTML errors.
     
You have no opening <TD> tag, and no closing <TD> tags. You also have no closing </A> tag on the first link and the second one is outside of the <TD>. Because you have no matching <TD>, your table is not valid HTML, so it can't be displayed correctly.

When you're doing this sort of string building, I often find it easier to use printf() instead of echo - you can read about it here: http://php.net/manual/en/function.printf.php

That line 274 then becomes easier to read:

printf(
	"<tr> <td><a href="%s" target="_blank">%s</a></td> <td>%s</td> <td>%s</td> <td>%s</td> <td><a href="%s" target="_blank">%s</a></td></tr>" . PHP_EOL,
	$row["URL"], $row["Område"], $row["Aar"], $row["Matr"], $row["Gade"], $row["Infourl"], $row["Info"]
);

Open in new window

Basically you build your string, with %s as plaeholders, and then pass in the values to replace those placeholders. You can immediately check your HTML string
OK. Well, i really don't understand that I have a lot of HTML errors. Exactly the same HTML code works fine here:
http://genealogiskforum.dk/ft_raw/
This page holds the original code I would like to enter the toggle possibility to, and it have no errors.

Anyway, I believe it is too difficult to work the toggle code into my code, so I will make this another way.

I have this page partly working, http://kroweb.dk/gfdev/collapse/ and I will use that as a separate page in stead.

There are two minor things about that page that I hope you can guide me in the right direction on.

1. I need to display the table headlines on the page which are not returned as it is now
2. When toggling I need that the parent row child rows holds the same formatting. Right now the parent row is moved to the right when toggling, and the child rows are moved to the left

If you could help me to fix those two issues I would be very happy :)

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8" lang="da">
        <title>gfdev/collapse</title>
        <meta http-equiv="Content-Type" content="text/html"; charset=utf-8; lang="da" /> 

        <style type="text/css">
            tbody tr { display: none; background-color: #d5d5d5; }
            tbody tr.expander { display: table-row; background-color: initial; }
            tr:nth-child(even){background-color: #f6f6f6}
            span { cursor: pointer; color: #aa0000; }
            span:hover { color: #00aa00; }
        </style>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {
                $('#myTable').on('click', '.toggle', function() {
                    $(this).parents('tr').nextAll('tr').toggle();
                });
            });
        </script>
        <!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;



    
}

table, td {
   
    border: 1px  #f6f6f6;
    border-style: none;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: padding-left;


    
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}

.flex-container {
    display: -webkit-flex;
    display: inline-flex;
    flex-direction:row;
    background-color:#f6f6f6;
    width:100%;
}

.expander {
  display: none;
}

.expander {
  display: none;
}

.expander td:first-child {
  text-indent: 0px
}

.expander td:last-child {
  text-indent: 0px
}

span {
  cursor: pointer;
  color: grey;
  font-family: FontAwesome;
}

span:hover {
  color: black;
}

span.toggle:after {
  content: '\f055';
}




</style>
<!-- End of search styles -->


    </head>

    <body>
          
   <table id="myTable">
       

        
 <!-- Search code starts here -->
<?php
    
    $con=mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database: ".mysql_error());
    
    mysqli_select_db($con,"genealogiskforum_dk_db9");
    
    mysqli_set_charset($con,"utf8");

    
    

    
            // Run your Query
            $rows = $con->query("SELECT Collapse, Område, Aar, Matr, Gade, Info FROM folketaellinger");



            

            // Loop through the results
            while ($row = $rows->fetch_object()):
            ?>

                <?php if ($row->Collapse == "p"): ?>

                <tbody>
                <tr class='expander'>
                    <td><span class='toggle'>
                    <td><?php echo $row->Område ?></td>
                    <td><?php echo $row->Aar ?></td>
                    <td><?php echo $row->Matr ?></td>
                    <td><?php echo $row->Gade ?></td>
                    <td><?php echo $row->Info ?></td>
                    
                </tr>

                
                
                <?php else: ?>

                <tr>
                    <td><?php echo $row->Område ?></td>
                    <td><?php echo $row->Aar ?></td>
                    <td><?php echo $row->Matr ?></td>
                    <td><?php echo $row->Gade ?></td>
                    <td><?php echo $row->Info ?></td>
                    <td></td>
                </tr>  

                <?php endif; ?>
             
            <?php endwhile; ?> 
 
            
            

        </table>
 



<!-- End of search code -->



    </body>
</html>

Open in new window

OK. The code is not exactly the same between the 2 pages - in the page that didn't work, you had no opening TD tag on the first element:

echo "<a href=\"".$row["URL"]."\"target=\"_blank\">"

Looks like you've now fixed that so you have a table back again. Whether or not you choose to fix your HTML elements is up to you, but not doing so will reduce the effectiveness of your page. Different browsers will render invalid HTML in different ways, so you're likely to lose cross-browser compatibility. I'll leave it up to you to decide whether you think it's worth the effort to correct the errors.

To add your table header in just add the relevant code after the <table> tag, around line 143:

<table id="myTable">
  <tr>
    <td>Header 1</td>
    <td>Header 2</td>
    <td>Header 3</td>
    <td>Header 4</td>
    <td>Header 5</td>
    <td>Header 6</td>
  </tr>

The reason your columns are jumping about is because when the child rows are hidden you first column only contains the toggle icon, and the width is wide enough to hold that icon. Once you expand the child rows, the first column now contains a long string so the first column has to expand to accommodate this. Move all your child row columns along by one, around line 188:

 <tr>
  <td></td>
  <td><?php echo $row->Område ?></td>
  <td><?php echo $row->Aar ?></td>
  <td><?php echo $row->Matr ?></td>
  <td><?php echo $row->Gade ?></td>
  <td><?php echo $row->Info ?></td>
</tr>
Well - I took your advice and worked on to integrate the toggle function on the page.

And I am moving forward :)

I have two problems now:

1. The parent lines are displayed wrongly (you have explained earlier how I can fix that, but I am afraid that I did not quite understand it)
2. There is no toggle when clicking the toggle icon, but all the rows (parent and child) are returned

You can see it live here (enter 1860 in the first searchfield): http://kroweb.dk/gfdev/ft_raw/

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang="da-DK">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<head>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="utf-8" lang="da" >
      <title>ft_raw_desktop_virker_ med_to_tre_ind</title>
 <meta http-equiv="Content-Type" content="text/html"; charset=utf-8; lang="da" /> 

       <script type="text/javascript">
            $(document).ready(function() {
                $('#myTable').on('click', '.toggle', function() {
                    $(this).parents('tr').nextAll('tr').toggle();
                });
            });
        </script>


<!-- Search styles -->
<link rel="stylesheet" type="text/css" href="style.css"/>
<style>
table, th {
   
    border-bottom: 1px  #666666;
    border-top: 0px;
    border-right: 0px;
    border-left: 0px;
    border-style: solid;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: Serif;
    font-size: 20px;
    font-weight: bold;
    text-align: left;



    
}

table, td {
   
    border: 1px  #f6f6f6;
    border-style: none;
    border-collapse: collapse;
    padding-top:10px;
    padding-left:20px;
    color:black;
    font-family: arial;
    font-size: 14px;
    font-weight: normal;
    text-align: padding-left;


    
}

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}

.flex-container {
    display: -webkit-flex;
    display: inline-flex;
    flex-direction:row;
    background-color:#f6f6f6;
    width:100%;
}

.expander {
  display: none;
}

.expander {
  display: none;
}

.expander td:first-child {
  text-indent: 10px
}

span {
  cursor: pointer;
  color: grey;
  font-family: FontAwesome;
}

span:hover {
  color: black;
}

span.toggle:after {
  content: '\f055';
}

</style>
<!-- End of search styles -->


</head>


<body>
   <!-- Søge felt til folketællinger -->
  
    <div class="flex-container">
   
    <div class="flex-item"><form action="" style="padding-top:10px; padding-bottom:10px; " method="POST" > 
    
    <input type="text" style="margin-left:30px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_start"  />
    Start år
 
</div>  
   
    <div class="flex-item "style="padding-top:10px; padding-bottom:10px; ">
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_end"  />
    Slut år


    
        <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>

        <input type="submit" style="margin-left:5px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);;" value="Nulstil"/>
</div>  


   <div class="flex-item" style="padding-top:10px; padding-bottom:10px; " > 
    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:250px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_gade"  />
    Gader i København i 1860

 <input type="submit" submit title="Klik her, eller tast Enter, for at aktivere søgningen."style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);" value="Søg"/>
 

</div>  
</form>


<!-- Search code starts here -->
<?php
     if ((isset($_POST['query_start'])) && (trim($_POST['query_start'])!="") || (isset($_POST['query_end'])) && (trim($_POST['query_end'])!="") || (isset($_POST['query_gade'])) && (trim($_POST['query_gade'])!="")) {
    $con=mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database: ".mysql_error());
    
    mysqli_select_db($con,"genealogiskforum_dk_db9");
    
    mysqli_set_charset($con,"utf8");

    
    
?> 


</div>    
<div class="flex-container" style="width:site-width; background-color:white;">
<div class="flex-item" style="margin-top:10px; float:left; margin-left:20px;width: site-width; overflow:auto;">

<table id="myTable">

<?php
    
    $query = trim($_POST['query_start']); 
    $query2 = trim($_POST['query_end']);
    $query3 = trim($_POST['query_gade']);
      
//echo "Det virker hertil 0";
    
    $min_length = 4;
   

    if(strlen($query) >= $min_length || strlen($query2) >= $min_length || strlen($query3) >= $min_length) {


         $query = htmlspecialchars($query,ENT_QUOTES,"utf-8"); 
        $query2 = htmlspecialchars($query2,ENT_QUOTES,"utf-8");
        $query3 = htmlspecialchars($query3,ENT_QUOTES,"utf-8");
            

        $query = mysqli_real_escape_string($con, $query);
        $query2 = mysqli_real_escape_string($con, $query2);
        $query3 = mysqli_real_escape_string($con, $query3);
        // makes sure nobody uses SQL injection

//echo "Det virker hertil 1";        

         if ($query3=="")
{
          
          $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Aar = '$query') OR (Aar BETWEEN '$query' AND '$query2') ")or die(mysql_error());
}
else
{
         
         $raw_results = mysqli_query($con, "SELECT * FROM folketaellinger
            WHERE (Gade LIKE '%".$query3."%')")or die(mysql_error());
}
         



        

        if(mysqli_num_rows($raw_results) > 0){ 

print "query_start= " .$query;
print "  ";
print "query_end= " .$query2;
print "  ";
print "query_gade= " .$query3;
echo "Det virker hertil 2";

             echo "<table><tr><th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> </tr>  " .$results['Aar'];
             
 
            while($row = $result=mysqli_fetch_array($raw_results)) {
           

            echo "<tr><td>" ;

            

   
           if ($row["Collapse"]=="p") {
            echo "<tbody>";
            echo "<tr class='expander'>";
            echo "<tr><td>";
            // echo your row data here
           
            echo "<td>".$row["Område"];
             echo "<td><span class='toggle'>";
            echo "</tr></td>"; }

            else{

            //echo "<tr><td>";
            // echo your row data here
            echo $row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>". $row["Info"];
           echo "</tr></td>"; }



   

            //if ($row["Collapse"]=="") {
            //echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>"; }
           


            echo "</td></tr>";

            
    }
             echo "</table>"; 

                 

        }else{ // if there is no matching rows do following

            echo "Der er ingen resultater for denne søgning";
        }         
    }else{ // if query length is less than minimum

        echo "Mindste antal tegn er ".$min_length;
    }
mysqli_close($con);
}
?>


 
</div> 
</div> 

<!-- End of search code -->




</body>

</html>

Open in new window

Hey Peter,

I'm gong to revisit the point I made earlier. It is really important that you understand the need for valid HTML. Without it, nothing will work properly. Take a look at these lines. Read through them and try and imagine the HTML that it's creating:

while($row = $result=mysqli_fetch_array($raw_results)) {

  echo "<tr><td>" ;

  if ($row["Collapse"]=="p") {
    echo "<tbody>";
    echo "<tr class='expander'>";
    echo "<tr><td>";
    echo "<td>".$row["Område"];
    echo "<td><span class='toggle'>";
    echo "</tr></td>";
  } else {
    echo $row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>". $row["Info"];
    echo "</tr></td>";
  }

  echo "</td></tr>";

}

Open in new window


For each row in your Database, it's creating the following:

If collapse = p then you get this:

<tr><td><tbody><tr class='expander'><tr><td><td>Område<td><span class='toggle'></tr></td></td></tr>
            
If collapse doesn't = p then you get this:

<tr><td>Område<td>Aar<td>Matr<td>Gade<td>Info</tr></td></td></tr>

Neither of these lines make any sense - they are completely invalid, which is the root cause of your problem. I've just tried running your page through the W3C Validator and it crashed!! That really isn't good

What it should be creating is:

<tbody>
<tr class='expander'> <td><span class='toggle'></td> <td>Område</td> <td></td> <td></td> <td></td> <td></td> </tr>

or
<tr> <td></td> <td>Område</td> <td>Aar</td> <td>Matr</td> <td>Gade</td> <td>Info</td> </tr>

I'll post up a refactored version of your code in a few minutes that will show you how you should be doing this
Thanks Chris,

I really appreciate your help
But I need to be able to differentiate between rows with content "Collapse", and rows with no content there.
Rows with content is marked with "p" and "c" in "Collapse", and all other rows  is empty in "Collapse"

It is rows with content I need to collapse/expand, and rows without content should not be collapsed/expanded.

Hope it makes sense
Right Peter. I've refactored your code in a cleaner way. It generates valid html and will do what you need. Simply copy / paste and run. It should be fairly straight forward to see whats going on, and make it easier to test and develop from.

Give this a go and then we'll look at the non-collapsible rows.

FYI - You've been posting your real username, password and db in these posts so I suggest you change them as a matter or urgency!

<?php
// Turn on error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Do we need the database
if (!empty($_POST)):

    // Connect to the database is we have a POST
    $mysqli = mysqli_connect("mysql31.unoeuro.com", "genealogisk_dk1", "JX1wt77k7m", "genealogiskforum_dk_db9") or die("Error connecting to database!");
    $mysqli->set_charset("utf8");

    // Trim the input values
    $start = trim($_POST['query_start']); 
    $end = trim($_POST['query_end']);
    $gade = trim($_POST['query_gade']);
    
    if (!empty($gade)):

        // We have a 'gade' value
        $gade = "%".$gade."%";

        $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE (Gade LIKE ?)");
        $query->bind_param("s", $gade);

    else:

        if (!empty($start) && !empty($end)):
            // We have a 'start' and 'end' value
            $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE Aar BETWEEN ? AND ?");
            $query->bind_param("ss", $start, $end);

        elseif (!empty($start) && empty($end)):
            // We have a 'start' value
            $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE Aar = ?");
            $query->bind_param("s", $start);

        endif;

    endif;

    // Do we have a query to run
    if (isset($query) && $query):
        $query->execute();
        $results = $query->get_result();
    endif;

endif;
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Chris Stanyon</title>

        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

        <script type="text/javascript">
        $(function(){
            $('#myTable').on('click', '.toggle', function() {
                $(this).parents('tr').nextAll('tr').toggle();
            });
        });
        </script>

        <style type="text/css">
            #header { margin-top: 30px; margin-bottom:30px; }
            tbody tr { display: none; background-color: #d5d5d5; }
            tbody tr.expander { display: table-row; background-color: initial; }
            span.toggle { cursor: pointer; color: #aa0000; font-family: 'FontAwesome'; }
            span.toggle:hover { color: #00aa00; }
            span.toggle:after { content: '\f055' };
        </style>

    </head>

    <body>
        <div class="container">

            <!-- HEADER START -->
            <div class="row" id="header">
                <form method="POST"> 
                    <input type="text" name="query_start">
                    Start år
         
                    <input type="text" name="query_end">
                    Slut år

                    <input type="submit" title="Klik her, eller tast Enter, for at aktivere søgningen." value="Søg">
                    <input type="submit" value="Nulstil">

                    <input type="text" name="query_gade">
                    <input type="submit" title="Klik her, eller tast Enter, for at aktivere søgningen." value="Søg">
                </form>
            </div>  
            <!-- HEADER END -->

            <!-- DATA START -->
            <div class="row">

            <!-- Have we ran a query -->
            <?php if (isset($results)): ?>

                <!-- Do we have any results -->
                <?php if ($results->num_rows): ?>

                <table id="myTable" class="table">
                    <colgroup>
                        <col style="width:20px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                    </colgroup>

                    <tr>
                        <th>&nbsp;</th> <th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> <th>Info</th>
                    </tr>

                    <!-- Loop through the results of the query -->
                    <?php while ($row = $results->fetch_object()): ?>

                        <?php if ($row->Collapse == 'p'): ?>

                            <!-- We have a parent row -->
                            <tbody>
                            <tr class="expander">
                                <td><span class='toggle'></td>
                                <td><?php echo $row->Område ?></td>
                                <td><?php echo $row->Aar ?></td>
                                <td><?php echo $row->Matr ?></td>
                                <td><?php echo $row->Gade ?></td>
                                <td><?php echo $row->Info ?></td>
                            </tr>

                        <?php else: ?>

                            <!-- We have a child row -->
                            <tr>
                                <td>&nbsp;</td>
                                <td><?php echo $row->Område ?></td>
                                <td><?php echo $row->Aar ?></td>
                                <td><?php echo $row->Matr ?></td>
                                <td><?php echo $row->Gade ?></td>
                                <td><?php echo $row->Info ?></td>
                            </tr>

                        <?php endif; ?>

                    <?php endwhile; ?>

                </table>

                <?php else: ?>

                    <p>There are no records to show</p>

                <?php endif; ?>

            <?php endif; ?>

            </div>
            <!-- DATA END -->

        </div>
    </body>
</html>

Open in new window

Thanks Chris,
This works beautifully for entries with content in the row "Collapse". Thanks for that.
But I need to be able to display all the rows with no content in that row too.
How do I do that?

And - yes - I will change the password to the database at once.
OK. For that, you'll need to change the HTML that generates the rows slightly. Switch it out for this code (which generates 3 different 'types' of row: expander / child / non:

<!-- Loop through the results of the query -->
<?php while ($row = $results->fetch_object()): ?>

	<?php if ($row->Collapse == 'p'): ?>

	<!-- We have a parent row -->
	<tbody>
	<tr class="expander">
		<td><span class='toggle'></td>
		<td><?php echo $row->Område ?></td>
		<td><?php echo $row->Aar ?></td>
		<td><?php echo $row->Matr ?></td>
		<td><?php echo $row->Gade ?></td>
		<td><?php echo $row->Info ?></td>
	</tr>

	<?php elseif ($row->Collapse == 'c'): ?>

	<!-- We have a child row -->
	<tr class="child">
		<td>&nbsp;</td>
		<td><?php echo $row->Område ?></td>
		<td><?php echo $row->Aar ?></td>
		<td><?php echo $row->Matr ?></td>
		<td><?php echo $row->Gade ?></td>
		<td><?php echo $row->Info ?></td>
	</tr>

	<?php else: ?>

	<!-- We have a non-collapsible row -->
	<tr class="non">
		<td>&nbsp;</td>
		<td><?php echo $row->Område ?></td>
		<td><?php echo $row->Aar ?></td>
		<td><?php echo $row->Matr ?></td>
		<td><?php echo $row->Gade ?></td>
		<td><?php echo $row->Info ?></td>
	</tr>

	<?php endif; ?>

<?php endwhile; ?>

Open in new window

You will also need to change the toggle script slightly so that it only hides and shows child rows. Notice I've added the child class to the rows which are toggled:

$(function(){
	$('#myTable').on('click', '.toggle', function() {
		$(this).parents('tr').nextAll('tr.child').toggle();
	});
});

Open in new window

And finally a couple of change to the CSS to take care of the non-toggle rows (I've set them to yellow):

#header { margin-top: 30px; margin-bottom:30px; }
tbody tr.child { display: none; background-color: #d5d5d5; }
tbody tr.expander { display: table-row; background-color: initial; }
tbody tr.non { display: table-row; background-color: yellow; }
span.toggle { cursor: pointer; color: #aa0000; font-family: 'FontAwesome'; }
span.toggle:hover { color: #00aa00; }
span.toggle:after { content: '\f055' };

Open in new window

Beautifull :)

Now we only have one issue left.
The third searchfield should return entries with content is like the serachfield.
RIght now it returns nothing at all.
Can we fix that too?
That's already be in place and I've tested it locally:

$gade = trim($_POST['query_gade']);
    
if (!empty($gade)):
        // We have a 'gade' value
        $gade = "%".$gade."%";

        $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE (Gade LIKE ?)");
        $query->bind_param("s", $gade);

Open in new window

If it's not returning anything, then check your database. Basically it checks to see if POST['query_gade'] is not empty. It then wraps it in % ready for the LIKE query, and then builds the query before executing it:
The post Gade is empty in all rows where Collapse is empty. Databese is OK . it works with my initial code.
and it is not working. Enter e.g. Ny here: http://kroweb.dk/gfdev/ft_raw/
It is returning nothing, but should return this:

Område      Aar      Matr. / Nr.      Gade
Købmager kvarter Matr. Nr. 251-356, samt u.nr.      1860      277      Ny Adelsgade            
Købmager kvarter Matr. Nr. 251-356, samt u.nr.      1860      314 - 328      Ny Adelgade            
Købmager kvarter Matr. Nr. 251-356, samt u.nr.      1860      353 - 354      Kongens Nytorv            
Købmager kvarter Matr. Nr. 251-356, samt u.nr.      1860      356      Kongens Nytorv            
Købmager kvarter Matr. Nr. 251-356, samt u.nr.      1860      Uden nr      Kongens Nytorv, Hovedvagten            
Nørre kvarter Matr. Nr 120-235      1860      235      Nymølle            
Sankt Annæ Vester kvarter Matr. Nr. 454-504, Sankt Annæ      1860      504 F1 - G      Gernersgade, Nygade            
Sankt Annæ Vester kvarter Matr. Nr. 454-504, Sankt Annæ      1860      504 G2      Nygade            
Sankt Annæ Vester kvarter Nyboder, Sankt Annæ      1860      169 - 172      Ny Østergade            
Sankt Annæ Vester kvarter Nyboder, Sankt Annæ      1860      173      Ny Østergade, Svanegade            
Sankt Annæ Øster kvarter Matr. Nr. 001-082, Sankt Annæ      1860      1- 35      Nyhavn            
Sankt Annæ Øster kvarter Matr. Nr.150-235, Sankt Annæ      1860      205 - 215      Kongens Nytorv            
Snarens kvarter Matr. Nr. 002-066      1860      2 - 3      Nybrogade            
Snarens kvarter Matr. Nr. 002-066      1860      4 - 5      Nybrogade ,Sanregade            
Snarens kvarter Matr. Nr. 002-066      1860      6      Nybrogade            
Snarens kvarter Matr. Nr. 002-066      1860      16 - 19 A      Nybrogade            
Snarens kvarter Matr. Nr. 002-066      1860      20 - 21      Nybrogade            
Snarens kvarter Matr. Nr. 002-066      1860      22 - 24      Nybrogade, Magstræde            
Snarens kvarter Matr. Nr. 067-147      1860      85 - 87      Nytorv            
Snarens kvarter Matr. Nr. 067-147      1860      88      Nytorv, Knabrostræde            
Snarens kvarter Matr. Nr. 067-147      1860      89      Nytorv, Nygade            
Snarens kvarter Matr. Nr. 067-147      1860      90 - 92      Nygade            
Snarens kvarter Matr. Nr. 067-147      1860      94 - 97      Nygade            
Strand kvarter Matr. Nr. 001-090, samt u.nr.      1860      61 - 70      Ny Børs            
Udenbys Klædebo kvarter Matr. Nr. 001-036U6A, Udenbys      1860      36 F6B      Ny Østergade            
Udenbys Klædebo kvarter Matr. Nr. 001-036U6A, Udenbys      1860      36 F10      Ny Østergade            
Udenbys Klædebo kvarter Matr. Nr. 113A-172NO, samt u.nr., Udenbys      1860      171 N3 - 171 N7      Ny Bredgade, Gormsgade            
Udenbys Klædebo kvarter Matr. Nr. 113A-172NO, samt u.nr., Udenbys      1860      171 N8 - 171 N12      Ny Bredgade            
Udenbys Klædebo kvarter Matr. Nr. 113A-172NO, samt u.nr., Udenbys      1860      171_06 - 171_08      Ny Bredgade            
Vester kvarter Matr. Nr. 001-137      1860      1 - 2      Nytorv            
Vester kvarter Matr. Nr. 001-137      1860      3 - 4 A      Nytorv, Frederiksberggade            
Vester kvarter Matr. Nr. 001-137      1860      114      Hestemøllestræde, Nytorv            
Vester kvarter Matr. Nr. 001-137      1860      115 - 117      Nytorv            
Vester kvarter Matr. Nr. 138-265      1860      208 - 220      Ny Vestergade            
Vester kvarter Matr. Nr. 138-265      1860      221 - 226      Ny Kongensgade            
Vester kvarter Matr. Nr. 138-265      1860      228 - 236      Ny Kongensgade            
Vester kvarter Matr. Nr. 138-265      1860      241      Ny Vestergade            
Vester kvarter Matr. Nr. 138-265      1860      242      Ny Vestergade, Frederiksholms Kanal            
Vester kvarter Matr. Nr. 138-265      1860      243      Frederiksholms Kanal, Ny Kongensgade            
Øster kvarter Matr. Nr. 001-076      1860      1 - 2      Kongens Nytorv            
Øster kvarter Matr. Nr. 001-076      1860      3 - 4      Kongens Nytorv, Lille Kongensgade            
Øster kvarter Matr. Nr. 001-076      1860      5      Kongens Nytorv            
Øster kvarter Matr. Nr. 001-076      1860      6 - 7      Kongens Nytorv, Østergade            
Øster kvarter Matr. Nr. 148-285      1860      267 - 271      Kongens Nytorv            
Øster kvarter Matr. Nr. 148-285      1860      272 - 285      Nyhavn
Sorry for the "typos" above. Hope it makes sense anyway. Hard to write and hold fork and knife at the same time :) :)
OK. The code's sort of working, but all your returned records have 'c' in Collapse so they're hidden. If you type NY in the search and then check the source, you'll see all your records.

You've also messed up the CSS slightly. Rather than replacing with my latest code, you just added to it.

I think with a slight change to the CSS and a little code edit we can get around the issue. Replace your CSS with this:

#header { margin-top: 30px; margin-bottom:30px; }
tbody.toggle tr.child { display: none; background-color: #d5d5d5; }
tbody.toggle tr.expander { display: table-row; background-color: initial; }
tbody.toggle tr.non { display: table-row; background-color: yellow; }
span.toggle { cursor: pointer; color: #aa0000; font-family: 'FontAwesome'; }
span.toggle:hover { color: #00aa00; }
span.toggle:after { content: '\f055' };

Open in new window

And add the toggle class to the <tbody> we created:

<!-- We have a parent row -->
<tbody class='toggle'>

Open in new window

Finally, I would wrap the header row in the proper <thead> tag:

<thead>
  <tr>
    <th>&nbsp;</th> <th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> <th>Info</th>
  </tr>
</thead>

Open in new window

At some point you're going to have to consider how your data is stored. Basically, this whole code relies on your data being in the exact order it needs to be. When you do a search (for NY for example) there's no guarantee that a record with 'c' is going to be a child of the preceding record with 'p', but currently it will be grouped with it.
Hi CHris,
These changes is not making any difference, and I can see why with the way the code is set up now.
I will try to explain what it is I am after here.
I have a table with around 1000 rows, and increasing.
Some of these rows I need to be collapsible and some not. This function relates to specific years - right now only the year 1860, but more years will come as we move on. That is one function.
Then I need another function, totally independant of the collapse function, where I can search for a "Gade" independant of where in the table it might be found. At this point "Gade" is only present in rows marked with "c" in the row "Collapse", but later there might be some "Gade" in other rows too.
So the need is that the collapse function relating to years you search for (Start and End) and the search function for Gade to be completely independant.
It is my trying to create a code for this that made me mess around so much with my initial code. Sorry for that.

Well - I did delete all the old code and copied your new code in instead, but i had copied the CSS code in twice by mistake. Anyway I don't see any differences between the latest CSS code you sent compared to the first you sent?
Now I am working with your code to style it the way I want it to look.
But the most important issue is to separate the two functions mentioned above.
Do you see any possibility to do that?

Then I have a question to a statement like this: $query->bind_param("s", $gade); - I believe "s" is a parameter, but why "s" and what does it actually do?
I have one more very important issue.

I need to add links to a number of the items in the various searches.
Here is an example from my initial code - but it is only an example. E.g here the field "Område" relates to the link in the field "URL" and opens the link in a new tab
           if ($row["Collapse"]=="")
            echo "<a href=\"".$row["URL"]."\"target=\"_blank\">" .$row["Område"]."<td>" .$row["Aar"]. "<td>" . $row["Matr"].  "<td>". $row["Gade"].  "<td>".  "<a href=\"".$row["Infourl"]."\"target=\"_blank\">" . $row["Info"].  "<td>"."</a>";

I cant use the syntax I used before in the code you have made, som what I am after is the right syntax to add links to fields in your code.
I hope you can help me with that too :)
Hey Peter. The difference in the 2 CSS blocks is the addition of the toggle class to the tbody:

tbody.toggle tr.child { display: none; background-color: #d5d5d5; }
tbody.toggle tr.expander { display: table-row; background-color: initial; }
tbody.toggle tr.non { display: table-row; background-color: yellow; }

Open in new window

This means that child rows will only be hidden if they are in a <tbody class='toggle'>. If you only select rows with a 'c' in collapse, there will be no tbody toggle class so they won't be hidden, as in the case of your 'gade' search.

I would advise against working on the styling until you have the functionality completely locked down. It just adds extra 'fluff' to your page that complicates the testing phase.  

When you bind parameters to a query, you specify the 'type' of the data to be bound. The 's' indicates that you're binding a String (text). If you were binding an integer (whole number), you would use 'i' instead. Of course, you bind different types:

$query->bind_param("si", $someText, $someNumber);

How you create your links will depend on your own logic, but it's straight forward enough. If you explain the logic I can offer you a suggestion. For example, if each row needs a link, then just build the link at the start of the while() loop, and then inject it into your HTML when needed:

<?php while ($row = $results->fetch_object()): ?>

	<?php
	$link1 = sprintf("<a href='%s' target='_blank'>%s</a>", $row->URL, $row->Område); 
	$link2 = sprintf("<a href='%s' target='_blank'>%s</a>", $row->Infourl, $row->Info);
	?>

	<?php if ($row->Collapse == 'p'): ?>

	<!-- We have a parent row -->
	<tbody>
	<tr class="expander">
		<td><span class='toggle'></td>
		<td><?php echo $link1 ?></td>
		<td><?php echo $row->Aar ?></td>
		<td><?php echo $row->Matr ?></td>
		<td><?php echo $row->Gade ?></td>
		<td><?php echo $link2 ?></td>
	</tr>

	<?php elseif ($row->Collapse == 'c'): ?>

	<!-- We have a child row -->
	<tr class="child">
		<td>&nbsp;</td>
		<td><?php echo $link1 ?></td>
		...

Open in new window

Thanks,
I will work with the links.
About the .toggle it makes it possible to search for Gade, but the toggle function vanishes.
I have made e little styling. Hope it is not too disturbing - and I will not make anymore before the core functionality is in place :)

<?php
// Turn on error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Do we need the database
if (!empty($_POST)):

    // Connect to the database is we have a POST
    $mysqli = mysqli_connect("db credentials") or die("Error connecting to database!");
    $mysqli->set_charset("utf8");

    // Trim the input values
    $start = trim($_POST['query_start']); 
    $end = trim($_POST['query_end']);
    $gade = trim($_POST['query_gade']);
    
    if (!empty($gade)):

        // We have a 'gade' value
        $gade = "%".$gade."%";

        $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE Gade LIKE ?");
        $query->bind_param("s", $gade);
        //print "query_gade= " .$gade;

    else:

        if (!empty($start) && !empty($end)):
            // We have a 'start' and 'end' value
            $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE Aar BETWEEN ? AND ?");
            $query->bind_param("ss", $start, $end);

        elseif (!empty($start) && empty($end)):
            // We have a 'start' value
            $query = $mysqli->prepare("SELECT * FROM folketaellinger WHERE Aar = ?");
            $query->bind_param("s", $start);

        endif;

    endif;

    // Do we have a query to run
    if (isset($query) && $query):
        $query->execute();
        $results = $query->get_result();
    endif;

endif;
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>gfdev/ft_raw Chris Stanyon</title>
        <html lang="da-DK">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

        <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

        <script type="text/javascript">
        $(function(){
        $('#myTable').on('click', '.toggle', function() {
        $(this).parents('tr').nextAll('tr.child').toggle();
    });
});
        </script>

        <link rel="stylesheet" type="text/css" href="style.css"/>
        <style type="text/css">
 
          #header { margin-top: 10px; margin-bottom:10px; }
          tbody.toggle tr.child { display: none; background-color: #f6f6f6; }
          tbody.toggle tr:nth-child(even){background-color: #d5d5d5}
          tbody.toggle tr.expander { display: table-row; background-color: #f6f6f6; }
          tbody.toggle tr.non { display: table-row; background-color: #f6f6f6; }
          span.toggle { cursor: pointer; color: grey; font-family: 'FontAwesome'; }
          span.toggle:hover { color: cornflowerblue; }
          span.toggle:after { content: '\f055' };




 

a:link {
    color: black;
    text-decoration: underline;
}
a:visited {
    color: #e08a94;
    text-decoration: underline;
}
a:hover {
    color: cornflowerblue;
    text-decoration: underline;
    font-weight:normal;
}
a:active {
    color: black;
    text-decoration: underline;
}



 </style>



    </head>

    <body>
          <!-- Søge felt til folketællinger -->
        <div class="container" style="width:100%;">

            <!-- HEADER START -->
            <div class="row" id="header">
                <form method="POST"> 
                    <input type="text" style="margin-left:30px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;"name="query_start">
                    Start år
         
                    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:50px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_end">
                    Slut år

                    <input type="submit" title="Klik her, eller tast Enter, for at aktivere søgningen." style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);"value="Søg">

                    <input type="submit" style="margin-left:5px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);;"value="Nulstil">

                    <input type="text" style="padding-top:10px; padding-bottom:10px;margin-left:10px; height:25px;width:250px;border: 1px solid #666666;border-radius:2px;color:#666666;" name="query_gade">
                    Gader i København i 1860

                    <input type="submit" title="Klik her, eller tast Enter, for at aktivere søgningen." style="margin-left:5px;padding-right:10px;height:25px;font-family:arial; font-size: 12px; text-align:left; background-color:#cccccc; border: 2px solid #grey;border-radius:2px; color:black; background-color:#cccccc; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);"value="Søg">
                </form>
            </div>  
            <!-- HEADER END -->

            <!-- DATA START -->
            <div class="row">

            <!-- Have we ran a query -->
            <?php if (isset($results)): ?>

                <!-- Do we have any results -->
                <?php if ($results->num_rows): ?>

                <table id="myTable" class="table">
                    <colgroup>
                    <col style="width:20px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">
                        <col style="width:100px;">   
                    </colgroup>

                    <thead>
                    <tr>
                        <th>&nbsp;</th> <th>Område</th> <th>Aar</th> <th>Matr. / Nr.</th> <th>Gade</th> <th>Info</th>
                    </tr>
                    </thead>

                    <!-- Loop through the results of the query -->
<?php while ($row = $results->fetch_object()): ?>

  <?php if ($row->Collapse == 'p'): ?>

  <!-- We have a parent row -->
  <tbody class='toggle'>
  <tbody>
  <tr class="expander">
    <td><span class='toggle'></td>
    <td><?php echo $row->Område ?></td>
    <td><?php echo $row->Aar ?></td>
    <td><?php echo $row->Matr ?></td>
    <td><?php echo $row->Gade ?></td>
    <td><?php echo $row->Info ?></td>
  </tr>

  <?php elseif ($row->Collapse == 'c'): ?>

  <!-- We have a child row -->
  <tr class="child">
    <td>&nbsp;</td>
    <td><?php echo $row->Område ?></td>
    <td><?php echo $row->Aar ?></td>
    <td><?php echo $row->Matr ?></td>
    <td><?php echo $row->Gade ?></td>
    <td><?php echo $row->Info ?></td>
  </tr>

  <?php else: ?>

  <!-- We have a non-collapsible row -->
  <tr class="non">
    <td>&nbsp;</td>
     <td><?php echo $row->Område ?></td>
    <td><?php echo $row->Aar ?></td>
    <td><?php echo $row->Matr ?></td>
    <td><?php echo $row->Gade ?></td>
    <td><?php echo $row->Info ?></td>
  </tr>

  <?php endif; ?>

<?php endwhile; ?>

                </table>

                <?php else: ?>

                    <p>There are no records to show</p>

                <?php endif; ?>

            <?php endif; ?>

            </div>
            <!-- DATA END -->

        </div>
    </body>
</html> 

Open in new window

OK. You've manged to add an extra <tbody> into your code which is why the toggle isn't working:

 <!-- We have a parent row -->
  <tbody class='toggle'>
  <tbody> <!-- NO NEED FOR THIS -->

Also, it's up to you if you add styling in, but already by doing so you've introduced some HTML errors on your search form, simply by missing a space between the style and name attributes:

style="...."name="...."

You need a space between attributes:

style="...." name="...."

Also, you've added in a new <html> tag inside the <head>, so that's another HTML error.

I know they may seem trivial when you view your site and it looks OK, but they're not trivial when your site is accessed across multiple devices / browsers etc. Also, any HTML errors will likely get you pinged by the search engines. Like I said before, if you're using something like Firefox, just do a quick 'View Source' - all your errors will stand out in Red.
Thanks Chris,

It is working now.
I am not using Firefox - i am primarily using Chrome - can I do the same thing with Chrome? I can view the source but it does not seem to show any errors, Or do you recommend that I use Firefox for developing issues?
You can continue to use Chrome if you like (although generally with any web development you'll probably want a few Browsers installed - IE / Edge / Chrome / Firefox etc.)

Chrome doesn't show the errors in the same way as Firefox does (both do have Developer tools built in - press F12), but you can download a Chrome extension that will check the validity of your HTML. Haven't used any of them in Chrome so can't tell you which ones are good or bad.
FYI - You've still got a rogue <html> tag in your <head> :)
Thanks Chris,

Firefox shows no errors right now :)
Nice ... Looking good :)
Just one more little question.

Why do I have these grey lines between the entries?
The black line under the table header is OK - that one I will have, but the other ones i'd life to get rid of, and I can't figure out how to do it.
Can you help?
Those styles are defined in the bootstrap stylesheet. You can override them in your own stylesheet with the following:

.table > tbody + tbody { border-top: none; }
.table > tbody > tr > td { border-top: none; }

Open in new window

Thanks - that helped :)
I still have no red lines in Firefox. That was a very useful tip you gave me there :)
Excellent Peter.

Ensuring you have valid HTML / CSS / Javascript etc will keep your site running smoother and certainly help in maintainability. The same goes for building your pages in a logical way, like I've tried to do here. Pretty much every web developer starts off by throwing html / javascript / css and php at the page in no particular order and it becomes impossible to maintain really quickly - spaghetti code !! What I did with refactoring your code here is really only the start but hopefully you're already seeing the benefits of developing this way.
Chris,

I feel a need to say many, many thank you for all your help and patience with me in this project.

I have learned so much more than I ever dared to think of  during our dialogue here. Thanks again for that.

In the future I will be very much more systematic when designing and coding my pages and sites.

I have now (thanks to you) published an error free page on my main page, of which my users are very fond.
It ia all about genealogy, and my wife and I are running several non-commercial sites and groups and the project here is a part of one of those.

I hope that i may contact you if I get in trouble again (very probably :) here in this forum?

Thanks again, and have a nice week-end.

Besr regards
Peter
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Chris Stanyon has been a fantastic helper, and has helped me to understand much more of php, sql, and js.