Nicolas Nicolas - 1 month ago 11
MySQL Question

How to use checkboxes to retrieve specific data in a database

Lately i have been working on a form with which a user can select a checkbox and as a result of the selection it shows the database information in a table.

I browsed the stackoverflow questions and found a question that was almost the same, namely: Retrieve data from sql database and display in tables - Display certain data according to checkboxes checked

So with this information, and some other information from the web, i started to create my code. Though after completion i had several errors, namely my database fields were duplicate on output, the data that the field had isn't outputted and there were two warnings. After a lot of searching and editing/trying i couldn't find the right solution so hence me asking this question in here.

Before i display my code i first give some information about the checkboxes, database and table/fields (and a (small) note: it is a wordpress database).

I have 1 database called xxx_wp1. THis database contains various (wordpress) table's but the table i want to retrieve information from is called: wp_participants_database.

This table contains various columns (around 15). Though, for this testing example i used just 3 of the 15 columns named: authorss, research_source and research_title. I inserted some random information (3 rows) in these 3 columns.
The form i created has, kinda obviously, 3 checkboxes for each column (so 1 for authors, research source and title).

Based on the previous link and some wordpress information i started to create my code for the selection, it is as follows:

<form method="post">
<input type="checkbox" name="columns[]" value="1" /><label for="Authors">Authors</label><br />
<input type="checkbox" name="columns[]" value="2" /><label for="Research Source">Research Source</label><br />
<input type="checkbox" name="columns[]" value="3" /><label for="Research Title">Research Title</label><br />
<input type="submit" name="go" value="Submit"/>
</form>

<?php


$all = false;
$column_names = array('1' => 'Authors', '2'=>'Research Source', '3'=>'Research Title');
$column_entries = isset($_POST['columns']) ? $_POST['columns'] : array();
$sql_columns = array();
foreach($column_entries as $i) {
if(array_key_exists($i, $column_names)) {
$sql_columns[] = $column_names[$i];
}
}

if (empty($sql_columns)) {
$all = true;
$sql_columns[] = "*";
} else {
$sql_columns[] = "authorss,research_source,research_title,";
}
global $wpdb;

//DNI CHECKBOX + ALL
$tmp = $wpdb->get_results( "SELECT ".implode(",", $sql_columns)." FROM wp_participants_database");

$result = mysql_query($tmp);
echo "<table border='1' style='width:450px'>
<tr>
<th>authorss</th>
<th>research_source</th>
<th>research_title</th>";
foreach($column_names as $k => $v) {
if($all || (is_array($column_entries) && in_array($k, $column_entries)))
echo "<th>$v</th>";
}
echo "</tr>";
while( $row = mysql_fetch_assoc($result))
{
echo "<tr>";
echo "<td>" . $row['authorss'] . "</td>";
echo "<td>" . $row['research_source'] . "</td>";
echo "<td>" . $row['research_title'] . "</td>";
foreach($column_names as $k => $v) {
if($all || (is_array($column_entries) && in_array($k, $column_entries))) {
echo "<th>".$row[$v]."</th>";
}
}
echo "</tr>";
}
echo '</table>';


?>
<?php
mysql_close();
?>


As you can see, the quesry is a bit different because it has to connect to the Wordpress database (the global $wpdb and $wpdb->get_results). While typing this im thinking that this might also be part of the problem as this get_results is already getting results which i am also getting later on?

Anyway, while testing this i get a few errors / misbehavior which i cant seem to figure out.

The first errors are the following warnings:

- Warning: mysql_query() expects parameter 1 to be string, array given in /home/xxx/domains/mysite.nl/public_html/Recap/wp-content/themes/radiate/templates/pdb-search-new.php on line 32 --- which is this line of code: `$result = mysql_query($tmp);`
- Warning: mysql_fetch_assoc() expects parameter 1 to be resource, null given in /home/xxx/domains/mysite.nl/public_html/Recap/wp-content/themes/radiate/templates/pdb-search-new.php on line 43 --- which is this line of code: `while( $row = mysql_fetch_assoc($result))`


The second problem is that all of the columns are echo'd TWICE even before submitting. So this would mean this line of code is being done no matter what:

if (empty($sql_columns)) {
$all = true;
$sql_columns[] = "*";
} else {
$sql_columns[] = "authorss,research_source,research_title,";
}


When i check a option and press the submit button, the right column is being showed (so yay that works), though all the 3 columns are still being showed (no matter what) as well as the selected one, so i got this if i select the first option:
authorss research_source research_title Authors (notice the first 3 are from my defined while the last one is from my defined $column_names.

The last problem is that the field values of the columns isn't being showed, the columns are just empty.

So the question is of anybody could give me some pointers about what is going wrong.

Thank you in advance!

*****UPDATE*****

I made some adjusting with the help of @Zeusarm

So firstly i changed the warnings (among others the
$wpdb->get_results
is changed to
$wpdb->query
) and the warnings are all gone. For some reason i gave the
$array_names
just their front-end names (stupid me), so i changed it, like you suggested to the proper column names as they are in the database table. So field 1,2,3 became: authors, research_source and research_title.

I also added the other changes. Although the errors are all gone, i still get all 3 the columns showed + 1 duplicate (depending on the number of checkboxes selected). Plus i still don't get the database data which is stored in the columns (for example: authorss has the following stored values in it: Barry, Henk and Nicolas.).

The code now looks like (with the form left out as it remained the same):

<?php
$all = false;
$column_names = array('1' => 'authorss', '2' => 'research_source', '3' => 'research_title');
if(isset($_POST['columns'])){
$column_entries = $_POST['columns'];
$sql_columns = array();
foreach($column_entries as $i) {
if(array_key_exists($i, $column_names)) {
$sql_columns[] = $column_names[$i];
}
}
$sql_columns[] = "authorss";
$sql_columns[] = "research_source";
$sql_columns[] = "research_title";
} else {
$all = true;
$sql_columns[] = "*";
}
global $wpdb;

//DNI CHECKBOX + ALL
$tmp = $wpdb->query( "SELECT ".implode(",", $sql_columns)." FROM wp_participants_database");

$result = mysql_query($tmp);
echo "<table border='1' style='width:450px'>
<tr>
<th>authorss</th>
<th>research_source</th>
<th>research_title</th>";
foreach($column_names as $k => $v) {
if($all || (is_array($column_entries) && in_array($k, $column_entries)))
echo "<th>$v</th>";
}
echo "</tr>";

if($result!==false && mysql_num_rows($result)>0){
while( $row = mysql_fetch_assoc($result)){
echo "<tr>";
echo "<td>" . $row['authorss'] . "</td>";
echo "<td>" . $row['research_source'] . "</td>";
echo "<td>" . $row['research_title'] . "</td>";
foreach($column_names as $k => $v) {
if($all || (is_array($column_entries) && in_array($k, $column_entries))) {
echo "<th>".$row[$v]."</th>";
}
}
echo "</tr>";
}
echo '</table>';
}

?>
<?php
mysql_close();
?>


*****UPDATE 2*****

So i changed the code and finally i am retrieving the data of the database! So i guess i should just work with the wordpress get_results for querying from now on.
Although i am retrieving the information i still have duplicates. When i go to the page, at first i have all 3 duplicates and the data retrieving is being output in the first 3 columns. When i select 1 checkbox option, the correct data of that checkbox is being displayed and the other data from the other checkboxes isn't (so that works). Though, for example when i only choose the authors checkbox, the data of authors is being displayed in the first authors checkbox and only 1 duplicate (namely 'authors') is being showed. Though when i click only the second checkbox, research source (column research_source) then the data of that column is only being showed (what is correct) BUT that data is being output in thew first authors column and again, 1 duplicate with the correct column name namely 'research_source'.

But because a picture says more than a 1000 words, i added some images to clear it up. (sorry for the links to the pictures but missing 2 reputation to post pics directly)

The starting columns/page (untouched):

The starting columns/page (untouched)

Only authors selected and submitted:

Left this one out as i can also only upload 2 links withh less than 10 rep...

Only Research Source selected and submitted:

enter image description here

Answer

I see at least 2 errors in your code.

  1. the $column_names associative array values are supposed to be passed as field names, so I assume that they are not correct, as you have spaces in them (and as I know wordpress by default does not have such field names.

  2. if some selection is provided by user you are adding some extra field names to the once which are passed by user and you have a colon after them so it will generate an error.

I would rewrite the code like this

<?php
$all = false;
$column_names = array('1' => '`field1`', '2' => '`field2`', '3' => '`field3`');
if(isset($_POST['columns'])){
    $column_entries = $_POST['columns'];
    $sql_columns = array();
    foreach($column_entries as $i) {
        if(array_key_exists($i, $column_names)) {
            $sql_columns[] = $column_names[$i];
        }
    }
    $sql_columns[] = "authorss";
    $sql_columns[] = "research_source";
    $sql_columns[] = "research_title";
} else {
    $all = true;
    $sql_columns[] = "*";
}

Also as you have said $wpdb->get_results returns already the results - array so that's why you get the errors. Plus before calling mysql_fetch_assoc it is better to check if the passed parameter is recource and if the number of rows is not 0.

if($result!==false && mysql_num_rows($result)>0){
    while( $row = mysql_fetch_assoc($result)){
        ...
    }
}  

*********** UPDATE ***********

according to last changes try this code:

<?php
$all = false;
$column_names = array('1' => '`authorss`', '2' => '`research_source`', '3' => '`research_title`');
if(isset($_POST['columns'])){
    $column_entries = $_POST['columns'];
    $sql_columns = array();
    foreach($column_entries as $i) {
        if(array_key_exists($i, $column_names)) {
            $sql_columns[] = $column_names[$i];
        }
    }
} else {
    $all = true;
    $sql_columns[] = "authorss";
    $sql_columns[] = "research_source";
    $sql_columns[] = "research_title";
}

global $wpdb;

//DNI CHECKBOX + ALL
$tmp = $wpdb->get_results( "SELECT ".implode(",", $sql_columns)." FROM wp_participants_database"); 


echo "<table border='1' style='width:450px'>
    <tr>
    <th>authorss</th>
    <th>research_source</th>
    <th>research_title</th>";
foreach($column_names as $k => $v) { 
    if($all || (is_array($column_entries) && in_array($k, $column_entries)))
        echo "<th>$v</th>";
}
echo "</tr>";

if(count($tmp)>0){
    for($i=0;$i<count($tmp);$i++){
        echo "<tr>";  
            foreach($tmp[$i] as $key=>$value){
                echo "<td>" . $value . "</td>";   
            }
            foreach($column_names as $k => $v) { 
                if($all || (is_array($column_entries) && in_array($k, $column_entries))) {
                    echo "<th>".$row[$v]."</th>";
                }
            }
        echo "</tr>";
    }
}

echo '</table>';
?>