If/stomp() in a while loop?

Im displaying every item/record from a mysql table as a checkbox using

                while ($row = $stmt->fetch())
                {
                    echo '<div class="checkbox">';
                    echo '<label>';
                    echo "<input type='checkbox' 
					name='Amenities[]' 
					value='".$row['name']."' 
					>";
                    echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
                    echo $row['name'];
                    echo '</label>';
                    echo '</div>';
                }

the result…


I am trying to only have the check boxes all ready checked if 2 strings are equal (so I have three amenities assigned to this property in another table and want those amenities to be checked.
This is my if…

if($row2['amenity'] == $row['name']) 
	{
	echo "checked";
	}
					

or do you think it would be better to use stomp()?
How do I put that statement into the while()?

I’ve never heard of stomp() and a quick google turned nothing relevant. Here’s what I’d do:

  • Get rid of all those echos
  • Figure out whether to use “checked” or not before the content, not inline
  • Simply echo out the “$isChecked” string to the input
while ($row = $stmt->fetch()) :
  $isChecked = $row2['amenity'] === $row['name'] ? 'checked' : '';
  ob_start(); ?>

    <div class="checkbox">
      <label>
        <input type="checkbox" name="Amenities[]" value="<?= $row['name'] ?>" <?= $isChecked ?>>
        <span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
        <?= $row['name'] ?>
      </label>
    </div>
    
  <?php echo ob_get_clean();
endwhile;

ok, changed the code and get…


This property has 3 amenities (Bar, New furnishings, Garage parking)
So im guessing the space must be the culprit…
Do you see why?

I can’t see why a space would cause a problem when comparing two strings. To see if that’s the cause, why not set the “Balcony” option and see if that is checked? If it is, then it might be something to do with spaces and you can look further at that, if it is not then you know not to waste any time on it.

It’s hard to know what might be causing it without knowing exactly what’s in $row and $row2. Could you show var_dump() results for each of them? If you right-click and look at the html source your code has generated, does anything jump out?

when I add

var_dump($row2['amenity'],$row['name']);

into the loop, I get

string(3) “Bar” string(7) “Balcony”
string(3) “Bar” string(3) “Bar”
string(3) “Bar” string(8) “Bay View”
string(3) “Bar” string(14) “Garage parking”
string(3) “Bar” string(13) “Internet/WiFi”
string(3) “Bar” string(12) “Maid Service”
string(3) “Bar” string(15) “New furnishings”
string(3) “Bar” string(10) “Ocean View”
string(3) “Bar” string(12) “Pet Friendly”
string(3) “Bar” string(18) “Recently remodeled”
string(3) “Bar” string(2) “TV”
string(3) “Bar” string(12) “Washer/Dryer”

So it looks like my 2nd query is not working., but when I add

while($row2=$stmt2->fetch()) {
echo $row2['amenity']." ";	
}

Bar seems to turn to null as its output is

Garage parking New furnishings NULL

what query? if this is PDO, use var_dump($stmt->errorInfo());

Yes, there are no queries in your code so it’s difficult to figure out how your comparisons work. For what it’s worth, I would probably do something like:

// retrieve all possible values for amenities into an array $amenities
// retrieve the property details
// display the fixed property details
// foreach $amenities:
//   display the amenity checkbox
//   if this property has that amenity, display "checked"
//    end of foreach

sorry, should of explained better…
I have a table of names of amenities (Bar, Ocean view, Garage parking, Ocean vie etc)
I have another table which holds the amenities for a property.
what im trying to do is create an edit property form wherw someone can see the properties current amenities (and add/remove them)
So I thought I could do this (but not really)
Here what I came up with

//query to show ALL amenities
$stmt = $conn->query('SELECT name FROM amenities');
//do I need to do this?
$conn2 = new PDO("mysql:host=$hostname;dbname=shores", $username, $password);
//query to show only the amenities for this property
$stmt2 = $conn2->query('SELECT amenity FROM properties_amenities WHERE propertyID='.$_GET['id']);
			
var_dump($stmt->errorInfo());
echo "<br>";
var_dump($stmt2->errorInfo());

the result
array(3) { [0]=> string(5) “00000” [1]=> NULL [2]=> NULL }
array(3) { [0]=> string(5) “00000” [1]=> NULL [2]=> NULL }

Im not sure what that tells me, but it seems i might be going at this all wrong (and use a foreach loop instead of a while one

foreach ($row = $stmt->fetch())  {

$isChecked = $row2['amenity'] === $row['name'] ? 'checked' : '';

echo '<div class="checkbox">';
echo	'<label>';
echo '<input type="checkbox" name="Amenities[]" value="'.$row['name'].'"'.$isChecked.'>';
echo	'<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo	$row['name'];
echo '</label>';
echo	'</div>';

}

Try playing about with this standalone fixed array version.

Once you are familiar then try to substitute the fixed array values from the tables.

<?php
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', 'true');

$title = 'Just testing';

echo $hdr = <<< ____TMP
<!DOCTYPE HTML>
<html lang="en"> 
<head>
<title> $title </title>
<style type="text/css">
label {display:inline-block; width:10em;}
</style>
</head>
<body>
____TMP;

$rows = [
  "Balcony"             => 'yes',
  "Bar"                 => '',
  "Bay View"            => 'yes',
  "Garage parking"      => 'yes',
  "Internet/WiFi"       => '',
  "Maid Service"        => '',
  "New furnishings"     => 'yes',
  "Ocean View"          => '',
  "Pet Friendly"        => '',
  "Recently remodeled"  => 'yes',
  "TV"                  => '',
  "Washer/Dryer"        => '',
];


// while ($row = $stmt->fetch())
//                {
echo '<form class="checkbox" method="post">';

  foreach($rows as $row => $checked):
    echo "\n<label>" .$row  ."</label>\n";

    if( 'yes' === $checked ):
      $checked = 'checked';
    endif;  
    echo "<input type='checkbox' name='Amenities[]' value='" .$row ."' "  .$checked ." />";
    // echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
    echo "\n";
  endforeach;
  echo '<input type="submit">';
echo '</form>';
echo '<hr>';

fred($_POST, '$_POST');
fred($rows, 'fixed $rows which should be populated from database');

echo '</body></html>';

//==============================
function fred($val, $title=NULL)
{
  echo '<pre>';
    if($title):
      echo '<b>'.$title . '</b> ===>  &nbsp; ';
    endif;  
    print_r($val);
  echo '</pre>';
}///

1 Like

Part of the difficulty there is that you don’t show how that loop relates to the retrieval of each row from your query results. If you get them one row at a time (let’s say it is one fetch() from each query at the same time) then this line

$isChecked = $row2['amenity'] === $row['name'] ? 'checked' : '';

relies on the values coming out in the same order, so at the very least you need to ORDER BY. But that won’t work, because your query from the amenities table will always have all amenities, and the query for the property probably won’t. So they’ll quickly get out of sync.

So have an array with the complete list of amenities (which you can use to draw the checkboxes) and retrieve the setting for each property while you’re doing that. The code from @John_Betong shows you how to do it, the only thing you need then is to retrieve the amenities from your table at the start.

You might want to look at changing the way you store that information - normally you’d give each amenity a unique id, and store that id in the property-amenities table, rather that storing and comparing the text strings. Apart from anything else it makes it much easier if you want to change the name of one of the amenities once you have a few thousand properties in the database, or if you want to provide a version of your web site in a different language.

1 Like

Man, I guess I have to figure out a query which would output both every amenity as well as the selected ones so I can create an array like yours

$amenities = [
$amenity => $isChecked;
]
//then put that in a loop with the query to make an array
//then, in order to draw the checkboxes, do
  foreach($amenities as $row => $checked):
    echo "\n<label>" .$row  ."</label>\n";

    if( 'yes' === $checked ):
      $checked = 'checked';
    endif;  
    echo "<input type='checkbox' name='Amenities[]' value='" .$row ."' "  .$checked ." />";
    // echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
    echo "\n";
  endforeach;

You’ve already got that query. The only issue is that you try to step through both result sets in the same loop and you don’t want to do that. Run the first query and gather the results into your array of amenities. Then run the query on the property-amenities and compare it to the array.

1 Like

Try passing the query results to the debug function fred(...):

//fill it up
while ($row = $stmt->fetch()) {
// $row[‘name’] =>$row[‘property_1_amenity’];

fred( $row );
// observe results and create array.
}//

when I do that…


Which is right, but why wont it let me do

//instead of the output, put it in another array
$rows =  $row['name'] => '.$row['property_1_amenity'].'

Try this:

$rows [ $row['name'] ] = $row['property_1_amenity'] ;

Edit:
Quotation marks may be required.

1 Like

Can’t you just do

$amenities = $stmt->fetchAll();

to build the array of all amenities?

1 Like

I was hoping @lurtnowski would be able to use the supplied script and then be able to spot how the intermediate array could be eliminated. Once working then optimise to make the solution simpler :slight_smile:

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.