#php #html #foreach #radio-button
#php #HTML #foreach #переключатель
Вопрос:
Я хочу составить список из четырех вопросов и четырех вариантов для каждого вопроса. Я успешно извлек вопросы с помощью foreach
цикла, но переключатели, похоже, не работают с foreach
циклом.
Например: я выбрал один ответ на первый вопрос и перешел ко второму, но если я выберу ответ на второй вопрос, выбранный вариант первых вопросов будет отменен. Я пробовал изменять значения параметров, это не сработало, я пробовал использовать цикл for внутри foreach
цикла, но даже это не сработало.
Ниже приведен мой код:
<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>
Есть ли что-нибудь, чего мне не хватает?
Комментарии:
1. С помощью этого скрипта вы сгенерируете несколько входных данных с одинаковым идентификатором, который является недопустимым HTML.
2. @Qirel Я удалил идентификатор из формы, но это сделало то же самое, что и при наличии идентификатора.
3. Да, идентификатор не имеет значения, важно то, что вы продолжаете использовать одни и те же имена для одних и тех же вопросов. Смотрите мой ответ ниже для решения.
4. Это был просто комментарий, а не ответ, @dearsina. 😉
5. @Qirel, ваш комментарий попал в точку, идентификаторы имеют значение.
Ответ №1:
Ваша проблема в том, что вы повторно используете имена и идентификаторы ваших входных данных. Имена и идентификаторы должны быть уникальными, чтобы HTML был действительным и работал так, как вы предполагаете. Вместо этого вы можете использовать входные имена в виде HTML-массивов и группировать по ним.
Используя $key
из массива, вы можете определить уникальное имя для каждой вашей группы ответов. Мы также используем это для определения идентификаторов ваших элементов, поскольку они должны быть уникальными.
Внесенные изменения являются,
- Включите
$key
в цикл - Добавление
-<?php echo $key; ?>
ко всем экземплярам, где вы используете идентификатор кнопок (и ссылку в метке), чтобы гарантировать, что все идентификаторы уникальны - Использование
name="answer[<?php echo $key; ?>]"
вместоans1
,ans2
,ans3
,ans4
. Это гарантирует, что для каждого ответа можно выбрать только один переключатель и что у вас есть один массив ответов, каждый элемент которого является ответом на один вопрос.
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
}
Теперь, когда вы отправляете форму, выбранные ответы будут в массиве, где имя answer
. Итак, вам нужно будет сделать что-то вроде
foreach ($_POST['answer'] as $key=>$value) {
// $key is the same key from the loop above
// $value is the value of the selected radio button
}
Комментарии:
1. Как я могу узнать вопрос об ответах, поступающих в массиве?
2.
$key
В каждом массиве один и тот же. Так$_POST['answers'][0]
будет получен ответ на вопрос, где$key
в цикле с вопросами (foreach ($quizList as $key=>$list) {
) было 0. Если вы определите, что этот ключ является идентификатором вопроса, у вас тогда будет идентификатор вопроса как в цикле ответов, так и в цикле вопросов.
Ответ №2:
Переключатели связаны между собой по имени. В вашем foreach()
вы продолжаете повторять одни и те же имена для каждого набора ответов на вопрос. (Вы также повторяете один и тот же идентификатор, что является дурным тоном, но не нарушит ваш скрипт).
Вам нужно реструктурировать ваши переключатели так, чтобы каждая группа кнопок (которые принадлежат друг другу) имела одинаковое имя. И это имя должно быть уникальным для каждой группы.
Упрощенный пример:
<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>
Комментарии:
1. есть ли какой-либо возможный способ сделать это с помощью цикла foreach? Из-за цикла переключатели работали отлично.
2. Да, безусловно, я считаю, что ответ на этот вопрос уже есть, так что взгляните туда.
Ответ №3:
Еще более упрощенный ответ
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>
Тогда в php вы должны получить что-то вроде этого:
$_POST['answer'] = [
'0' => 'foo'
//'1' => 'biz' ....
];
С помощью Ajax
Одна заметка с пронумерованными клавишами. ЕСЛИ вы используете AJAX (если нет, вы можете в принципе игнорировать это), вы можете потерять числовые индексы при преобразовании в JSON и из него, например, представьте, что мы ожидаем этого:
$_POST['answer'] = [
'0' => 'foo'
'2' => 'biz' ....
];
Когда это закодировано в Json, это, скорее всего, будет что-то вроде этого (куда делись ключи)
'{"answer":["foo", "biz"]}`
Затем, когда PHP преобразует это обратно, мы потеряли наши ключи. И у нас у нас будет что-то вроде этого:
$_POST['answer'] = [
0 => 'foo'
1 => 'biz' ....
];
Это также верно для любой функции массива, которая не сохраняет ключи sort
и т.д. Простое решение здесь — просто добавить к ключу что-то вроде a
или _
четного. Тогда они будут строками и преобразуются в объекты в формате JSON. В PHP вы все равно могли бы сопоставить их следующим образом:
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.
И так далее.
Надеюсь, это поможет!