Avoiding empty rows in a table

Hi,

I have this code creating a row in a table if there is content in the corresponding db row:
<tr>   
               <td><? if (empty($row->Faldne_5)): ?>              
                <? else: ?>
                   <? echo $row->faldne?> 
               <? endif; ?> </td>

             </tr> 

Open in new window


The problem is, that if there is no content in the db for this row, it displays an empty row in the table, and that is exactly what I would avoid.

You can see an example here: https://kroweb.dk/gfdev/collecting_page2/soegedb/soegeDatabaser.php?sogn=Bjerning&amt=Haderslev in the table in the column to the left. Here are displayed two rows with content (which is correct) and one empty row (which actually also is correct) and here I need the empty row not to be displayed.

If anybody have some ideas on how to make that work I would be very happy :)
Peter KromanSenior Proposal SpecialistAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Leonidas DosasCommented:
I show a JQuery solution.If you see the code checks every td and if its value is empty string thet it removes the tr.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<title>HTML, CSS and JavaScript demo</title>
</head>
<body>
<!-- Start your code here -->

  <table>
    <tr><td>aaa</td></tr>
    <tr><td></td></tr>
    <tr><td>bbb</td></tr>
    <tr><td>ccc</td></tr>
    <tr><td></td></tr>
    <tr><td></td></tr>
     <tr><td>ddd</td></tr>
  </table>
  <script>
   $('td').each(function(){
  if($(this).text()===''){
    $(this).remove();
  }
});
  </script>
<!-- End your code here -->
</body>
</html>

Open in new window

0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Thansk Leonidas,

It works - but there is a little problem.

When I put in the js script type line after my datatables script line it works but then datatables is not working.
When I put it in the before the datatables line datatables is working but your solution is not working.

After:
<script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
        <script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>

Open in new window


Before:
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
        <script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>

Open in new window

0
Olaf DoschkeSoftware DeveloperCommented:
The problem with your code is, that it would need to know in advance whether all $row columns are empty.

So a solution should be using a variable to accumulate anything from <tr> to </tr> and another boolean $rowhasdata variable should keep track whether any case of non empty value happened and finally (before fetching the next row) echo the accumulated <tr>...</tr> HTML or not and therefore skip it. So having <tr> and </tr> and every <td> and </td> in the static non PHP part of your script already outputs it prematurely.

Bye, Olaf.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Julian HansenCommented:
Create a function called renderRow()
Pass the current $row to it
In the function create a variable that determines the empty state of the row
Based on this render out the row
while($row = ...) {
   renderRow($row);
...
}
...
function renderRow($row)
{
  // Modify to test the conditions that mean the row is empty
  $rowEmpty = empty($row->faldne) && empty($row->someotherfield) && ....;

  // If row has content then HEREDOC it out
  if (!rowEmpty) {
   echo <<< ROW
    <tr>
       <td>{$row->faldne}</td>
    </tr>
ROW;
  }
}

Open in new window

EDIT: Fixed typo in ROW output
0
Olaf DoschkeSoftware DeveloperCommented:
You might also fix your SQL to not return rows having all empty columns, eg WHERE col1+col2+col3+....<>=''. That might need taking care of data types and NULL.

Bye, Olaf.
1
Peter KromanSenior Proposal SpecialistAuthor Commented:
Well - I have 208 columns and 2219 rows in the database table.
It is  - throughout the db-table- very different which columns has content in a given row and which is empty.
But there is content in some of the 208 columns in every of the 2219 rows.

@Olaf : So I don't think the SQL model is the right thing to do here ??

@Julian: I am not sure that I fully understand your suggestion. Do you mean that I should set check this up for all the 208 columns one by one, or is there an easier way to get around this? Could I ask you to fill out a little more of the code example you posted - especially the ...'s :)
0
Olaf DoschkeSoftware DeveloperCommented:
Well, if every row has some data you can't leave out whole rows. And leaving out TDs means you shift columns, surely also not, what you'd want to do.

You can only skip whole rows if you only display part of all table columns and these group of columns is all empty. Your where clause would then reflect that, too. Just pick out the columns you also display, of course.

Bye, Olaf.
0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Yeah - I can't leave out any db-columns since there is content in some rows in all columns.

So it is actually in the HTML table alone, I want to control empty or not empty columns :)
0
Olaf DoschkeSoftware DeveloperCommented:
You can't, just skipping <td></td> empty columns all further columns are shifted to the left. Do you want that? You can only remove all empty rows and you said there aren't any. Then I don't see any options.
Are you looking into removing grid lines? Notice, that'll make values appear as the value for two or more columns or multiple rows, even though they only belong into a single cell.

Therefore I don't see any sense in trying to reduce the HTML.

Only if you say just display 50 of the 208 columns and all 50 columns are empty for the row. Any of the other 158 columns in the database may have a value, but that's not listed anyway.

Bye, Olaf.
0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Just to clarify a little more.

I am doing a foreach loop through the array $data generated from the db query.

Looks something like this:
<?php foreach ($data as $row): ?>
            <tr> 
                <td><? if (empty($row->Nygaard_3)): ?> <!-- Do nothing --> 
                <? else: ?>
                   <? echo $row->nygaard?> 
               <? endif; ?> </td>
            </tr>
            
            <tr>   
               <td><? if (empty($row->Faldne_5)): ?>              
                <? else: ?>
                   <? echo $row->faldne?> 
               <? endif; ?> </td>

             </tr> 

            <tr>   
               <td><? if (empty($row->Oeders_10)): ?>
                <? else: ?>
                   <? echo $row->oeders?> 
               <? endif; ?> </td>

             </tr> 


        <?php endforeach; ?>

Open in new window


@Julian - How do I work your suggestion into that setup :)
0
Olaf DoschkeSoftware DeveloperCommented:
I already thought you had a foreach of rows, that's logical. But OK, that shows you only display 3 of the 208 columns in this case. Then you can query

WHERE (...) AND `nygaard`+`faldne`+`oeders`<>''

Open in new window


Bye, Olaf.
0
Chris StanyonWebDevCommented:
Peter,

If your foreach is as simple as you've just shown, then why not wrap each <TR> in the empty check. That way, you only output the <TR> if the values are not empty.

<?php foreach ($data as $row): ?>
    <?php if ( ! empty($row->Nygaard_3)): ?>
        <tr> 
            <td><?php echo $row->nygaard ?></td>
        </tr>
    <?php endif; ?>

    <?php if ( ! empty($row->Faldne_5)): ?>
        <tr>   
            <td><?php echo $row->faldne ?></td>
        </tr>
    <?php endif; ?>

    ....

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Olaf DoschkeSoftware DeveloperCommented:
@Chris: Making every cell its own table row this way, that pushes everything not empty to the leftmost column. Oh I see, that's already the case in Peters original code.
Peter, why do you have multiple <tr></tr> pairs, each one is becoming it's own row, do you want that, is your table just a single column? The original code you posted only had one <tr></tr>.

Bye, Olaf.
0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Beautiful :)
Thanks Chris,

This works nicely.

Just one little question more.

When here is no data to display, it returns this english message: No data available in table

I have in the code set it up to return this danish message: Der er ingen resultater for denne søgning

Can you see why that is? I give you the full code (as it is right at this moment) here:

<?php require_once('lokale_data_SQL.php') ?>

<?php if (count($data)): ?>


    <div id= "soegLokale">

    <table id="LokaleTable" class="table">


        <!-- Top head -->
         <?php foreach ($data as $row): ?>
        <thead>
            <tr>
                <th class="sorting" aria-controls="LokaleTable"><? echo $row->sogn?> Sogn i <? echo $row->herred?> Herred, <?echo $row->amt?> Amt</th>          
            </tr>
        </thead>
        <?php endforeach; ?>


        <?php foreach ($data as $row): ?>
            <?php if ( ! empty($row->Nygaard_3)): ?>
            <tr> 
                <td><?php echo $row->nygaard ?></td>
            </tr>
            <?php endif; ?>

            
            <?php if ( ! empty($row->Faldne_5)): ?>
            <tr>   
                <td><?php echo $row->faldne ?></td>
            </tr>
            <?php endif; ?>

            
            <?php if ( ! empty($row->Oeders_10)): ?>
            <tr>   
                <td><?php echo $row->oeders ?></td>
            </tr>
            <?php endif; ?>

            
            <?php if ( ! empty($row->Skanderborg_12)): ?>
            <tr>   
                <td><?php echo $row->skanderborglex ?></td>
            </tr>
            <?php endif; ?>

            
            <?php if ( ! empty($row->FolketiMidten_13)): ?>
            <tr>   
                <td><?php echo $row->folketimidten ?></td>
            </tr>
            <?php endif; ?>
             
            
            <?php if ( ! empty($row->ejrs_14)): ?>
            <tr>   
                <td><?php echo $row->sejrssedler ?></td>
            </tr>
            <?php endif; ?>
             





        <?php endforeach; ?>




    </table>

 </div>    

<?php else: ?>

    <h6>Der er ingen resultater for denne søgning</h6>

<?php endif; ?>

Open in new window

0
Olaf DoschkeSoftware DeveloperCommented:
That code so far works for you, really? Do you notice that you put each column of the sql result $row into its own row?

Bye, Olaf.
0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Yep Olaf,

That is just what I need here :)
0
Chris StanyonWebDevCommented:
Hey Peter,

If you're getting the English message, then it's possible that it's coming in as part of the $data variable. Therefore count($data) will return true and echo it out instead of failing the 'if' test and echoing out your Danish version.

For testing purposes, var_dump your $data variable before you count it and run the test with data you know should be empty.
0
Peter KromanSenior Proposal SpecialistAuthor Commented:
Nice and simple :)

Thanks a lot Chris.
Just what I needed here.

About my last question, just forget about it. It is purely academic, because when I am finished building this page, there will be no situations where the any of the tables are totally empty.
0
Chris StanyonWebDevCommented:
No worries Peter - glad it's working :)
0
Julian HansenCommented:
@Julian - How do I work your suggestion into that setup :)
Fairly simple - instead of using the function to output the data for a row simply pass the data item to the function and test it there.
A lot cleaner than a bunch of if statements in your code

while($row = ...) {
   renderRow($row->Nygaard_3);
   renderRow($row->Faldne_5);
...
}
...
function renderRow($data)
{
  if (!empty($data)) {
   echo <<< ROW
    <tr>
       <td>{$data}</td>
    </tr>
ROW;
  }
}

Open in new window

0
Olaf DoschkeSoftware DeveloperCommented:
Yes, that's one the base principle of all programming, DRY: Don't repeat yourself. Functions can implement some test and result once and you just pass in the different values. I would keep all echoing of output on the topmost level and let a function only return its result value, but that's a matter of taste.

I just have to admit I misread your code to create one row per loop iteration, putting the three table fields in one row.

Bye, Olaf.
0
Julian HansenCommented:
I would keep all echoing of output on the topmost level and let a function only return its result value
Except where the function exists solely to encapsulate output.
1
Olaf DoschkeSoftware DeveloperCommented:
In this case, it is but I think more general. If I want to orchestrate output and collect HTML snippets from several modules I don't want them to autonomically output anything. I might take the table HTML from here and some other HTML from over there and put it together in some other way than it was generated chronologically.

Bye, Olaf.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
HTML

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.