Привет, я делаю модуль викторины. В котором студент может пройти тест. после отправки, если викторина не пройдена, студенты могут «пересдать тест». После того, как учащиеся нажмут «повторно пройти викторину», будут отображаться только вопросы, на которые пользователь дал неправильный ответ. Я использую модальные окна php и HTML для первого показа вопросов, когда студент проходит тест. Вместо использования jquery и javascript я передаю ответы пользователя бэкэнду и проверяю, прошел ли он или нет. В случае неудачи у меня неправильный идентификатор вопросов, который я хочу отображать, когда они берут запрос. После кода:
Index.php
//When user clicks this button, modal will be pop-up and questions will be displayed one by one.
<a href = "#" class = "btn btn-danger btn-lg" data-toggle = "modal" data-target = "#Quiz" id = "start-quiz">Start Quiz</a>
<!-- Quiz Modal -->
<div class = "modal fade quiz-modal" id = "Quiz">
<div class = "modal-dialog modal-lg">
<div class = "modal-content">
<? foreach ($questions as $i=>$question) { ?>
<div class='question'>
<div class = "modal-header">
<div class = "row">
<h4>QUIZ</h4>
</div>
</div>
<div class = "modal-body">
<div class = "row">
<div id = "quest-content" class = "quest">
<h4 class = "question-title"><?=$question->number?>) <?=$question->title?></h4>
<ul class = "list-unstyled">
<? foreach ($question->getAnswers() as $answer) { ?>
<li>
<div class = "checkbox">
<input class = "cb" type = "checkbox" name = "answer[]" value = "<?=$answer->title?>">
<?=$answer->title?>
</div>
</li>
<? } ?>
</ul>
<br>
<br>
<p class='error'>Please select an answer</p>
</div>
</div>
</div>
<div class = "modal-footer">
<p class='quest_num'><?=$question->number?> of <?=count($questions)?></p>
<? if ( count($questions) === 1 ) { ?>
<a class = "btn button btn-lg quiz-btn">Submit Quiz</a>
<? } else if ( count($questions) === $i +1 ) { ?>
<a class = "btn button btn-lg quiz-btn">Submit Quiz</a>
<? } else { ?>
<a href = "" class = " btn button btn-lg quiz-btn">Next Question</a>
<? } ?>
</div>
</div>
<? } ?>
</div>
</div>
</div>
Ниже приведен <script>, где я делаю несколько вещей: если есть еще вопросы, кнопка будет показывать «Далее», а если это последний вопрос, кнопка покажет «Отправить». После отправки викторины он отправит ответы пользователя на серверную часть через $.post и вернет массив неверных идентификаторов вопросов. Используя эти неправильные идентификаторы вопроса, когда пользователь нажимает «Повторно пройти тест», он должен снова отображать тест только с этими идентификаторами.
<script type = "text/javascript">
$(document).on('ready', function(){
var answers = [];
$('.quiz-btn').click(function(e){
e.preventDefault()
var checkbox = $(this).parents('.question').children('.modal-body').children('.row').children('.quest').children('ul').children('li').children('.checkbox').children('.icheckbox_square');
var btn = $(this).parents('.question').children('.modal-footer').children('.quiz-btn')
var next = false
var submit = false
console.info(checkbox)
$(checkbox).each(function(){
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($(this).children('.cb:checked').val());
console.info(answers);
next = true
}
else if ($(this).hasClass('checked') && $(btn).html() == 'Submit Quiz') {
answers.push($(this).children('.cb:checked').val());
submit = true
}
});
if ( next ) {
e.preventDefault();
$(this).parents('.question').slideUp(500);
$(this).parents('.question').next('.question').delay(500).slideDown(500);
} else if ( submit ) {
e.preventDefault();
$.post('/student/submit_quiz',{answers: answers, module: <?=$model->course_module->id?>}, function(data){
var correct = data['correct'];
var incorrect = data['incorrect'];
if (incorrect){
if (incorrect.length > 0){
var div = $('.quest')[$('.quest').length - 1];
var footer = $('.modal-footer')[$('.modal-footer').length - 1];
var progress = (correct.length*100)/(<?=count($questions)?>);
div.innerHTML = "<h4 class='question-title'>" + (correct.length)+"/<?=count($questions)?> questions correct <h4>";
div.innerHTML += "<div class='error'><p><strong>We are sorry but you have " + incorrect.length +" answers incorrect</strong><br>Please go back and review and reanswer those questions.</p></div>";
footer.innerHTML = "<a onclick='retakeQuiz(["+incorrect+"])' class='btn btn-success btn-lg quiz-btn'>Retake Quiz</a>";
} else {
var div = $('.quest')[$('.quest').length - 1];
var footer = $('.modal-footer')[$('.modal-footer').length - 1];
var progress = (correct.length*100)/(<?=count($questions)?>);
div.innerHTML = "<h4 class='question-title'> Congratulations!! You Passed this Module.<h4>";
footer.innerHTML = "<a href='/student/course/<?=$model->course->id?>' class='btn btn-default btn-lg'>Continue</a>";
}
}
});
} else {
console.info(next)
$('.quest .error').fadeIn();
}
});
});
function retakeQuiz(incorrect) {
$.each(incorrect, function(key, val) {
alert('index ' + key + ' points to file ' + val);
//Here incorrect is the array of Wrong Question's IDs. How can I use that id to show only this questions in my above modal.
});
}
</script>
Я хотел бы знать вас всех, что у меня есть только один модальный, который показывает вопросы викторины один за другим, и когда тест завершен и пользователь отправит тест, он покажет сообщение о прохождении или неудаче вместе с соответствующей кнопкой, говорящей «Продолжить 'или' Пройдите тест еще раз '. Если нажать кнопку «Повторно пройти тест», в модальном окне будут отображаться неправильные вопросы. Итак, у меня есть только один модальный код, но я просто динамически меняю содержимое с помощью javascript.
Я изо всех сил старался объяснить свой вопрос и код. Надеюсь на помощь. Помощь очень ценится.
Вначале это напрямую через PHP
В вашем вопросе $question->number - это идентификатор вопроса?
Нет, это вопрос о порядке отображения. Идентификатор вопроса может быть $question->id



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Подобные манипуляции с двух сторон всегда заканчиваются небольшими затруднениями. Можно ли вместо изменения вопросов с помощью jQuery изменить конечную точку PHP для возврата модального содержимого с учетом набора идентификаторов? Вот большая идея:
В вашем PHP-коде есть конечная точка, которая принимает список идентификаторов. Эти идентификаторы передаются PHP-коду, который делает это и возвращает список вопросов идентификаторов (и соответствующих ответов). Когда пользователь впервые посещает вашу страницу, ваш PHP-код автоматически загружает все вопросы в модальное окно, чтобы пользователь получил весь тест (аналогично тому, как вы загружаете сейчас при начальной загрузке страницы).
Как только они закончили тест, вы сказали, что сохранили идентификаторы вопросов, которые они ошиблись. Я бы порекомендовал отправляет идентификаторы в ваш php-код, чтобы вернуть только что сгенерированное модальное окно, включая только идентификаторы вопросов, которые они ошиблись. Затем вы можете просто заменить модальное содержимое на результат. Возможно, что-то вроде этого (это все псевдокод, но я надеюсь, что он передаст идею)
// user has finished taking the quiz
$.get({
"url": "/yourendpoint" + ids.toString()
"method": "GET"
}.then(function(data){
$(".modal-content").html(data);
});
Спасибо. Я думал примерно так, но не знаю, как это сделать. Но обязательно попробую.
1. Напишите код PHP, который возвращает вопросы 2. На вашей конечной точке, которая возвращает страницу HTML, вызовите код PHP, который возвращает вопросы, и загрузите его на свою страницу, как в примере выше 3. После того, как пользователь завершит тест, запросите другую конечную точку (вам нужно написать эту новую конечную точку), которая возвращает содержимое modal-contents с вопросами, введенными в 4. Перезаписать HTML-код modal-content, как показано во фрагменте. Надеюсь, это даст немного больше подробностей
Спасибо. Это дает мне представление о том, как это сделать. Я ценю.
Я предлагаю добавить атрибут я бы к каждому разделу вопросов со значением идентификатора вопроса, как показано ниже.
<? foreach ($questions as $i=>$question) { ?>
<div class='question' id = "<? $question->id ?>">
// Your remaining code here
</div>
<? } ?>
После отправки формы в обратном вызове ajax-вызова удалите блоки вопросов с идентификаторами, которых нет в ответе, как показано ниже.
function retakeQuiz(incorrect) {
// I am assuming incorrect as [id, id, id] for example
$('.question').each(function (index, question) {
if (!incorrect.includes($(question).attr('id'))) {
$(question).remove();
}
});
}
Прохладный. Сейчас пробую. Но как я могу показать Вопросы с этими изменениями?
Вы динамически строите html вопросы, верно? Что произойдет, если вы нажмете на повторную викторину? Я думаю, это вернет студентов к html вопросам. Но если вы попробуете мое предложение, то сейчас вы не увидите исправленных вопросов. Вы пробовали?
Да, я попробовал ваше предложение и могу получить требуемый результат. Но на экране этого не видно. Когда я отлаживаю и вижу тот конкретный <div>, который показывает вопрос, он показывает правильный вывод, как требуется. Но как показать вопросы на экране.
@JohnCaverns Давайте рассмотрим два подразделения, например, одно для отображения вопросов, а другое для отображения Продолжать или Пройти тест еще раз могут быть с оценками. Таким образом, мы должны скрыть вторую (кнопки div) и должны снова отображать div вопросов, если был нажат Пройти тест еще раз. При повторном отображении div вопросов вы должны снова добавить отфильтрованные вопросы в div вопросов.
@JohnCaverns Если возможно, вы можете дать мне ответы на вопросы в формате JSON с ответами с сервера, я сделаю скрипку здесь, чтобы вы могли понять.
Я пошел за твоим шагом. теперь это сработало. Спасибо за помощь
@JohnCaverns, если мое предложение вам помогло, я очень рад. Сможете ли вы сделать ответ принятым и проголосовать за?
Каким образом вы отображаете вопросы в начале викторины? Я имею в виду напрямую через php или через вызов Ajax?