Hi I am making Quiz module. In which student can take quiz. once submitted, if the quiz is not passed, than students can 'retake quiz'. Once students click on 'retake quiz', only questions for which user gave wrong answer will be showed up. I am using php and HTML modal for showing the questions for the first time when student take quiz. Than using jquery and javascript, I am passing the responses of user to backend and checking if it is passed or failed. If failed, than I have wrong questions id, whihc I want to display when they take 'requiz'. Following a code:
Index.php
//When user clicks this button, modal will be pop-up and questions will be displayed one by one.
Start Quiz
<!-- 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 { ?>
Next Question
<? } ?>
</div>
</div>
<? } ?>
</div>
</div>
</div>
Following is <script> where I am doing couple of things: if there are more questions, button will show 'Next' and if it's a last question- button will show 'Submit'. Once submit the quiz, it will send user's responses to backend through $.post and get back the array of questions IDs that were wrong. Using this wrong question's ids, when user clicks on 'Retake Quiz', it should show quiz again with these ids only.
<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.log(checkbox)
$(checkbox).each(function(){
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($(this).children('.cb:checked').val());
console.log(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.log(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>
I would like to know you all that I have only one Modal- that shows the quiz questions one after another and when quiz is completed and user submit the quiz, it will show the message of pass or fail along with the respective button say 'Continue' or 'Retake Quiz'. If 'Retake Quiz' is clicked, wrong questions will be displayed on the modal. So I have only one modal, but just changing the contents dynamically through javascript.
I tried my best to explain my question and code. Hope to get some help. Help is highly appreciated.
Doing manipulating from two sides like this always ends up in a bit of a tizy. Instead of changing the questions by using jQuery, can you change your PHP endpoint to return modal content given a set of ids? Here is the big idea:
Your PHP code has an endpoint that takes in a list of ids. These ids get passed off to the PHP code which does it thing and returns a list of questions of the ids (and corresponding answers). When a user first visits your page, your PHP code auto-loads all of the questions into the modal so the user gets the entire quiz (similarly to how you are loading on initial page load now).
Once they finish the quiz, you said you stored the ids of the questions they got wrong. What I would recommend is sending the ids to your php code to return a newly generated modal only including the ids of questions they got wrong. Then, you can simply replace the modal content with the result. Something like this perhaps (this is all psuedo-code, but I hope it gets the idea across)
// user has finished taking the quiz
$.get({
"url": "/yourendpoint" + ids.toString()
"method": "GET"
}.then(function(data){
$(".modal-content").html(data);
});
My suggestion is to add attribute id to the every question divison with the value of question id like below
<? foreach ($questions as $i=>$question) { ?>
<div class='question' id="<? $question->id ?>">
// Your remaining code here
</div>
<? } ?>
After submitting the form, in your callback of ajax call, remove the question divs with the ids those are not present in the response like below
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();
}
});
}
Related
I am trying to create a shortcode that references content from a specific post ID. I have the code referenced below. It's set up so that if someone clicks the button, it will reveal content from the popup-id that will be defined in the shortcode. The popup-id is linked to a specific page/post.
function subscribe_link_att($atts, $content = null) {
$default = array(
'link' => '#',
'popup-id' => '4582'
);
$a = shortcode_atts($default, $atts);
$content = do_shortcode($content);
return '<button class="popup_button"> <span class="text">'.$content.'</span></button>
<div id="'.($a['popup-id']).'" style="display: none" class="hide">
<div class="social-popup-inner">
<img id="social-popup-close" src="/wp-content/themes/huh/_static/images/close-button.svg" alt="close">
<?php
$popup = get_post('.($a['popup-id']).');
echo $popup->post_content;
?>
</div>
</div>
';
}
add_shortcode('subscribe', 'subscribe_link_att');
The issue is that when I click the button, the content isn't pulling through (it just saying post_content; ?>).
It looks like the PHP code is being commented out (screenshot hyperlinked here)
I would love any feedback or direction.
I have a sample page here that I am playing with . It's formatted poorly but it's just for me to test things out in. The button called "TEXT HERE" is the button I am working on.
https://heyuhuman.com/melissa-test/
THANK YOU SO MUCH
I don't know if it's possible, but I need to send some information across a form ou inside url come from checkbox value.
This code below is inside a products loop and create a checkbox on every products (product comparison approach).
In my case, it's impossible to make this code below across a form.
<?php
echo '<div><input type="checkbox" value="' . $products_id .'" id="productsCompare" title="Compare" onclick="showProductsCompare()" /> Compare</div>';
?>
To resolve this point, I started to use an ajax approach and put the result inside a $_SESSION
My script to for the checbox value
$(function() {
$('input[type=checkbox]').change(function() {
var chkArray = [];
$('#container').html('');
//put the selected checkboxes values in chkArray[]
$('input[type=checkbox]:checked').each(function() {
chkArray.push($(this).val());
});
//If chkArray is not empty create the list via ajax
if (chkArray.length !== 0) {
$.ajax({
method: 'POST',
url: 'http://localhost/ext/ajax/products_compare/compare.php',
data: { product_id: chkArray }
});
}
});
});
And at the end to send information on another page by this code. Like you can see there is no form in this case.
<div class="col-md-12" id="compare" style="display:none;">
<div class="separator"></div>
<div class="alert alert-info text-md-center">
<span class="text-md-center">
<button class="btn">Compare</button>
</span>
</div>
</div>
No problem, everything works fine except in my compare.php file, I have not the value of my ajax. I inserted a session_start in ajax file
But not value is inserted inside compare.php.
I tried different way, include session_start() inside compare.php not work.
My only solution is to include in my products file a hidden_field and include the value of ajax across an array dynamically, if it's possible.
In this case, values of hidden_fields must be under array and sent by a form.
This script must be rewritten to include under an array the chechbox value
without to use the ajax. How to insert the good code?
$(function() {
$('input[type=checkbox]').change(function() {
var chkArray = [];
$('#container').html('');
//put the selected checkboxes values in chkArray[]
$('input[type=checkbox]:checked').each(function() {
chkArray.push($(this).val());
});
//If chkArray is not empty show the <div> and create the list
if (chkArray.length !== 0) {
// Remove ajax
// some code here I suppose to create an array with the checkbox value when it is on true
}
});
});
and this code with a form
<?php
echo HTML::form('product_compare', $this->link(null, 'Compare&ProductsCompare'), 'post');
// Add all the js values inside an array dynamically
echo HTML::hidddenField('product_compare', $value_of_javascript);
?>
<div class="col-md-12" id="compare" style="display:none;">
<div class="separator"></div>
<div class="alert alert-info text-md-center">
<span class="text-md-center">
<button class="btn">Compare</button>
</span>
</div>
</div>
</form>
Note : this code below is not included inside the form (no change on that).
<?php
echo '<div><input type="checkbox" value="' . $products_id .'" id="productsCompare" title="Compare" onclick="showProductsCompare()" /> Compare</div>';
?>
My question is :
How to populate $value_of_javascript in function of the checkbox is set on true to send the information correctly inside compare.php
If my question has not enought information, I will edit this post and update in consequence.
Thank you.
You cannot pass JavaScript Objects to a server process. You need to pass your AJAX data as a String. You can use the JavaScript JSON.stringify() method for this...
$.ajax({
method: 'POST',
url : 'http://localhost/ext/ajax/products_compare/compare.php',
data : JSON.stringify({product_id: chkArray})
});
Once that has arrived at your PHP process you can turn it back into PHP-friendly data with PHP JSON methods...
<?
$myArray = json_decode($dataString, true);
// ... etc ... //
?>
See:
JSON # MDN
JSON # PHP Manual
Example: Form Submission Using Ajax, PHP and Javascript
I am new to web development and javascript and jquery
I am working in auto created dynamic input field as much as user want and save that list in database , I already did that .
but I am facing 3 problem with that :
if the user want to reload the page I lose the already created list.
I had to show the same list from database in the same fields for update and
I don't know how to do it !!
The counter of the list works fine if i delete a row it decrement in right
way , but if i want to delete for example number 4 in list from 8 row the
counter doesn't work properly .
here is the list :
and here is the html code :
<div id="initRow" class="row">
<div class="form-group">
<div class="col-md-1">
<input class="form-control no-border text-center" id="count" value="1" readonly style="background-color:#FFFFFF">
</div>
<div class="col-md-6">
<input type="text" class="form-control" name="AssistantFactorsToSuccessProject[]" id="AssistantFactorsToSuccessProject" placeholder="Value" />
</div>
<div class="col-md-2">
<label class="control-label"><a class="rowDelete"><span class="glyphicon glyphicon-minus"></span></a></label>
</div>
</div>
</div>
and here is the javascript code :
var $counter = document.getElementById('count');
function addRow(section, initRow) {
var counter = 1;
var newRow = initRow.clone().removeAttr('id').addClass('new').insertBefore(initRow),
deleteRow = $('');
newRow.on('click', 'a.rowDelete', function() {
removeRow(newRow);
})
.slideDown(300, function() {
$(this)
.find('input').focus();
})
}
function removeRow(newRow) {
newRow
.slideUp(200, function() {
$(this)
.next('div:not(#initRow)')
.find('input').focus()
.end()
.end()
.remove();
$counter.value = parseInt($counter.value) - 1;
});
}
$("#FeasibiltyStudyDate").val( moment().format('YYYY-MM-DD') );
$(function () {
var initRow = $('#initRow'),
section = initRow.parent('section');
initRow.on('focus', 'input', function() {
addRow(section, initRow);
$counter.value = parseInt($counter.value) + 1;
}
});
});
and here is how I save it as array in db :
for ($i=0;$i<count($_POST['AssistantFactorsToSuccessProject']);$i++) {
$f = implode("</br>", $_POST['AssistantFactorsToSuccessProject']);
$AssistantFactorsToSuccessProject = $f;
}
answers for the mentioned points in the query.
1)if the user want to reload the page I lose the already created list.
Your not storing the data in database so on page refresh client side data will be cleared.
2)I had to show the same list from database in the same fields for update and I don't know how to do it !!
through ajax or form submit store the data in database.
refer to the below link: https://www.formget.com/insert-data-in-database-using-php/
3)The counter of the list works fine if i delete a row it decrement in right way , but if i want to delete for example number 4 in list from 8 row the counter doesn't work properly .
for delete you have to delete by id.
like. $('itemid').remove(); // it will remove html entity of that id.
This question already has answers here:
Submit form without page reloading
(19 answers)
Closed 6 years ago.
I was developing a system of Login and Register with PHP, HTML, MySql etc, so, i have a problem with my chat!
I want to get data from textarea, and if the button was clicked, empty the textarea, and send the text to database without refresh a page! I have a system that refresh the data from the database and refresh the div "chat" in index.php !
Help me!
You can use the following code:
The following uses AJAX and PHP,
First, make a function to the button, that when the send button is pressed, the AJAX function will be executed:
function msgsend()
{
var msg = $("#message").val();
if (msg!='')
{
$('#message').val("");
$.post("msgsubmit.php", { msg: msg },
function(result)
{
msgrecv();
});
}
}
And then check if new message is received and populate the Messages field:
function msgrecv(){
$.post("msgchk.php", {temp0 : 1},
function(result){
var div = document.getElementById('convo');
div.innerHTML = div.innerHTML + result;
if (result)
{
var elem = document.getElementById('convo');
elem.scrollTop = elem.scrollHeight;
}
});
}
So, the logic. Every user has a lastid which tells the message of the id last seen by the user, and then when a new message is added to the database by the user, the AJAX function is called and the message is submitted to the database and msgrecv () function is called to get the details of the message in the conversation box, note that the message box goes empty here, and on the other end, the function msgrecv() is automatically called every 10 seconds tto check for new messages or not, In the PHP code, I have a session variable created with $lastid which stores the id of last message and then check the database for message id > $lastid and if there is something, just echo/print it out which will be taken as the result of the AJAX function...
P.S. - I have used this code from one of my projects and since I don't know your code, so you may need to modify this according to your code...
And the elem.scrollTop = elem.scrollHeight; is just to scroll to bottom of the convo box (Which is the new message, as new messages appear in the bottom of the convo box), so whenever a new message arrives, the user won't have to scroll down to see that...
There is an error Updating the database:
Well, then you can see my PHP code for reference: (This is for Message Submit)
$msgcount = $row['messages'];
$msgcount = $msgcount + 1;
$chk=1;
$sql = "INSERT INTO ".$jobid."_conversation (date, from_id, from_username, to_writer, message, writer_read)
VALUES (now(), $userid, '$username', 0, '$message', 0)";
if (mysqli_query($con, $sql))
{
$sql1 = "UPDATE jobs SET messages='$msgcount' WHERE id=$jobid";
if(mysqli_query($con, $sql1))
{
echo 1;
}
else
{
echo 0;
}
}
else
{
echo 0;
}
Here, echo-ing 1 for succcess and 0 for failure in adding in the databse...
Now for Message Check:
$lastid = $row1['id'];
if ( $lastid > $id)
{
$to_writer = $row1['to_writer'];
$message = $row1['message'];
$rtrn = $rtrn."<div class=\"row\">";
if ($to_writer == 1)
{
$rtrn = $rtrn."<div class=\"well well-sm col-sm-offset-1 col-sm-8\">".nl2br($message)."</div>";
}
else
{
$rtrn=$rtrn."<div class=\"well well-sm col-sm-offset-3 col-sm-8\">".nl2br($message)."</div>";
}
$rtrn=$rtrn."</div>";
}
Here, $towriter is the username of the person to whom the message is sent, and this checks whether the message should be on the right side in the conversation box or in the left side of the conversation box, (Differentiating between sent and received messages)... And rest some HTML is there because I was using Bootstrap to display each message in a well...
Hope this helps... :)
You need to do a ajax event to get the content of your textarea and send it to the database, i recommend a simple framework like JQuery: http://api.jquery.com/jquery.ajax/
I have this code:
<?php
session_start();
require_once("conf/mysql.php");
$nome = $_SESSION["nome"];
$mensagem = $_POST["msg"];
mysqli_query($con, "INSERT INTO chat (user, message) VALUES ('$nome','$mensagem')");
?>
And the Index is:
<!-- Chat -->
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel container-fluid">
<center><h4><b> Chat: </b></h4></center>
<div class="well" >
<div class="loader"></div>
<script>
$(document).ready(function () {
$('#msg').change(function () {
if ($.trim($('#msg').val()).length < 1) {
$('#enviar').addClass('disabled');
} else {
$('#enviar').removeClass('disabled');
//No guarantee it isn't mindless gibberish, sorry.
}
});
});
</script>
<script type="text/javascript" language="javascript">
function msgsend()
{
var msg = $("#msg").val();
if (msg!='')
{
$('#msg').val("");
$.post("enviar.php", { msg: msg },
}
}
</script>
<div id="chat">
<div id="status" style="display: none;"></div>
</div>
</div>
<center>
<form id="ajax" role="form" method="post">
<div class="form-group">
<textarea id="msg" type="text" name="chat" class="form-control" placeholder="Digite aqui..."></textarea>
</div>
</form>
<button id="enviar" name="submit" class="btn btn-success disabled"> Enviar </button>
</center>
</div>
</div>
</div>
</div>
I have a simple log in at the top of my page that enables a user to enter a code - the code then reads the json file and pulls up the specific user of that code. I do have it showing in the alert, however I want the alert hidden before the user enters the code and displayed if the code is valid. In my json file I have the users code (which is currently named id) and when that is entered their name displays in the alert box. If nothing or an invalid code that is not apart of my code display I want an error alert to display.
This is what I have so far:
the log in text button:
<div class="alert alert-info"><input type="text" id="userName" value> <button type="button" id="loginbtn" class="btn btn-primary btn-md">Login</button></div>
the welcome/login alert:
<div class="alert alert-success" id="loginalert"<strong>Welcome</strong></div>
the error alert:
<div class="alert alert-danger" id="ErrorMessageAlert" <strong>Error</strong>invalid</div>
and the script ive been working on:
$(document).ready(function() {
$("#loginalert").hide();
$("#ErrorMessageAlert").hide();
$("#loginbtn").click(function(event){
$.getJSON('result.json', function(jd) {
var id = $('#userName').val();
for (var i=0; i<jd.user.length; i++) {
if (jd.user[i].ID == id) {
$('#loginalert').html('<p> Welcome: ' + jd.user[i].name + '</p>');
$("#loginalert").show();
}else
{
$("#ErrorMessageAlert").show();
}
);
}
}
});
}); });
A user from the json looks like {"user":[{"ID" : "001","name": "Zara Ali"}
So when the user writes in 001 the alert will display with that name
If the user enters nothing or an invalid code I want the error message to display.
Many thanks
I believe it would be easier to simply use ajax to get the JSON, as it makes your code more readable - that, and indentation and line breaks. The below should work but cannot be tested on Stack Overflow itself as it does not allow AJAX requests. The reason to use this piece of jQuery is that it has some neat built-in features and since this looks like it might be a login form, you might want to post some data over the web as well, which gets easier for later with ajax.
$(document).ready(function(){
$('#loginalert, #ErrorMessageAlert').hide();
$("#loginbtn").click(function(event){
// Every time you click the button, hide all alerts again
$('#loginalert, #ErrorMessageAlert').hide();
$.ajax({
url: 'result.json',
success: function(msg){
for(var i = 0; i < msg.user.length; i++){
if(msg.user[i].ID == id){
$('#loginalert')
.html('<p> Welcome: ' + msg.user[i].name + '</p>')
.show();
} else {
$('#ErrorMessageAlert').show();
}
}
},
error: function(e){
$('#ErrorMessageAlert').show();
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alert alert-info">
<input type="text" id="userName" value>
<button type="button" id="loginbtn" class="btn btn-primary btn-md">Login</button>
</div>
<div class="alert alert-success" id="loginalert"<strong>Welcome</strong></div>
<div class="alert alert-danger" id="ErrorMessageAlert" <strong>Error</strong>invalid</div>
There also seems to be a bit of a problem here in logic - can you have multiple users logged in at once in the same place? If not, then why are we looping through the results? You should return just one user, not nested. If you now get back multiple users, then only the last users name will be displayed, and that's odd. I would either change your JSOn to return only one user by default, or modify the javascript to only check for one:
success: function(msg){
if(msg.user[0] && msg.user[0].ID == id){
$('#loginalert').html('<p> Welcome: ' + msg.user[0].name + '</p>').show();
} else {
$('#ErrorMessageAlert').show();
}
}
The major thing is structure, though. Use tabs, line-breaks, and any kind of visual information to show what step nests in what other step, making your code easier to read at a glance.