Reputation: 514
I want to make a list of four questions and four options for each question. I have successfully fetched the questions with foreach
loop but, radio buttons do not seem to work with foreach
loop.
Eg: I chose one answer form the first question and jump to second, but if I select an answer for the second question, the selected option of the first questions gets deselected. I have tried changing values of options, that did not work, I tried using for loop inside the foreach
loop and even that did not work.
Following is my code:
<form method="post" action="process/quiz.php">
<?php
$quizList = $quiz->getQuiz(4);
if($quizList){
foreach($quizList as $list){
?>
<div class="row rowpadding">
<div class="col-md-8 col-md-offset-2" id="panel1">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<?php echo $list->title; ?>
</h5>
</div>
<div class="panel-body two-col">
<div class="row">
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-1" name="ans1" value="<?php echo $list->option_A ?>">
<label for="radio-button-1">
<span class="frb-title"><?php echo $list->option_A ?> </span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-2" name="ans2" value="<?php echo $list->option_B ?>">
<label for="radio-button-2">
<span class="frb-title"><?php echo $list->option_B ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-3" name="ans3" value="<?php echo $list->option_C ?>">
<label for="radio-button-3">
<span class="frb-title"><?php echo $list->option_C ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-4" name="ans4" value="<?php echo $list->option_D ?>">
<label for="radio-button-4">
<span class="frb-title"><?php echo $list->option_D ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
}
}
?>
<div class="panel-footer rowpadding">
<div class="row">
<div class="col-md-6">
<button type="submit" class="btn btn-sm btn-block ">
<span class="fa fa-send"></span>
submit </button>
</div>
</div>
</div>
</form>
Is there anything that I am missing?
Upvotes: 2
Views: 246
Reputation: 21661
An even more simplified answer
foreach($quizList as $key => $list){ ?>
<form>
<input type="radio" id="radio-button-1" name="answer[<?php echo $key;?>]" value="<?php echo $list->option_A ?>"> <!-- answer_0 -->
<input type="radio" id="radio-button-1" name="answer[<?php echo $key;?>]" value="<?php echo $list->option_B ?>"> <!-- answer_0 -->
</form>
Then in php you should get something like this:
$_POST['answer'] = [
'0' => 'foo'
//'1' => 'biz' ....
];
With Ajax
One note with numbered keys. IF you use AJAX (if not you can basically ignore this) you may lose numeric indexes when converting to and from JSON, for example imagine we expect this:
$_POST['answer'] = [
'0' => 'foo'
'2' => 'biz' ....
];
When that is encoded in Json it will likly be something like this (where did the keys go)
'{"answer":["foo", "biz"]}`
Then when PHP converts that back we have lost our keys. And we we'll have something like this:
$_POST['answer'] = [
0 => 'foo'
1 => 'biz' ....
];
This is also true of any array function that doesn't preserve keys, sort
etc. The easy solution here is to just prefix the key with something like a
or _
even. Then they will be strings and translate to objects in the JSON. In PHP you could still match these like this:
if("a$id" == $post_id){}
if(substr($post_id,1) == $id){}
//remove all prefixes
print_r(array_combine(preg_replace('/^a/', '', array_keys($answers)),$answers));
//it feels wrong but if you have to append you can do this
var_dump((int)'2a' == 2); //true so your key would be 2a because how PHP converts strings to ints.
And so on.
Hope it helps!
Upvotes: 1
Reputation: 26450
Your problem is that you are re-using the names and the IDs of your inputs. Names and IDs have to be unique for the HTML to be valid, and to work as you intend it to. You can have the input-names as HTML arrays instead, and group by that.
Using the $key
of the array, you can define a unique name for each your group of answers. We also use this to define the IDs of your elements, since they must be unique.
Changes made are,
$key
in the loop-<?php echo $key; ?>
to all instances where you use the ID of the buttons (and the reference in the label), to ensure all IDs are uniquename="answer[<?php echo $key; ?>]"
instead of ans1
, ans2
, ans3
, ans4
. This ensures that only one radio button can be selected per answer, and that you have one array of answers, each element being the answer of one question.foreach ($quizList as $key=>$list){
?>
<div class="row rowpadding">
<div class="col-md-8 col-md-offset-2" id="panel1-<?php echo $key; ?>">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<?php echo $list->title; ?>
</h5>
</div>
<div class="panel-body two-col">
<div class="row">
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-1-<?php echo $key; ?>" name="answer[<?php echo $key; ?>]" value="<?php echo $list->option_A ?>">
<label for="radio-button-<?php echo $key; ?>">
<span class="frb-title"><?php echo $list->option_A ?> </span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-2-<?php echo $key; ?>" name="answer[<?php echo $key; ?>]" value="<?php echo $list->option_B ?>">
<label for="radio-button-2-<?php echo $key; ?>">
<span class="frb-title"><?php echo $list->option_B ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-3-<?php echo $key; ?>" name="answer[<?php echo $key; ?>]" value="<?php echo $list->option_C ?>">
<label for="radio-button-3-<?php echo $key; ?>">
<span class="frb-title"><?php echo $list->option_C ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
<div class="col-md-6">
<div class="frb frb-danger margin-bottom-none">
<input type="radio" id="radio-button-4-<?php echo $key; ?>" name="answer[<?php echo $key; ?>]" value="<?php echo $list->option_D ?>">
<label for="radio-button-4-<?php echo $key; ?>">
<span class="frb-title"><?php echo $list->option_D ?></span>
<span class="frb-description"></span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
}
Now, when you submit the form, the selected answers will be in an array where the name is answer
. So you will have to do something like
foreach ($_POST['answer'] as $key=>$value) {
// $key is the same key from the loop above
// $value is the value of the selected radio button
}
Upvotes: 4
Reputation: 5192
Radio buttons are tied together by name. In your foreach()
, you keep repeating the same names for each set of question answers. (You're also repeating the same ID, which is bad form, but won't break your script).
You need to restructure your radio buttons so that each group of buttons (that belong together) have the same name. And that name has to be unique per group.
A simplified example:
<form>
<p>These belong together, and all have the name "gender":</p>
<input type="radio" name="gender" value="male"> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<p>These belong together, and all have the name "team":</p>
<input type="radio" name="team" value="blue"> Blue<br>
<input type="radio" name="team" value="red"> Red<br>
</form>
Upvotes: 1