Quizy / stylesheet.py
Abhinav
Refactor AI integration and enhance quiz functionality with validation
484bee1
def style():
css = """
.submit-btn {
padding: 10px 20px;
color: #333;
background-color: #face00;
border: 1px solid #ddd;
border-radius: 5px;
margin-top: 20px;
cursor: pointer;
transition: all 0.3s ease;
}
.submit-btn.disabled {
background-color: #cccccc;
color: #666666;
cursor: not-allowed;
opacity: 0.7;
}
.validation-alert {
background-color: #ffdddd;
color: #990000;
padding: 10px;
margin-bottom: 15px;
border-radius: 5px;
font-weight: bold;
text-align: center;
animation: fadeIn 0.5s;
}
.invalid-question {
border: 2px solid #ff0000;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
}
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
#result {
display: none;
margin: 0;
padding-left: 20px;
padding-bottom: 20px;
color: #000000;
background-color: darkviolet
}
input[type="text"] {
width: 100%;
padding: 10px;
color: #333333;
border-radius: 5px;
}
#quiz-answers {
margin-top: 30px;
padding: 20px;
background-color: #dfdfdf;
border: 1px solid #ddd;
border-radius: 5px;
}
#quiz-answers summary {
display: inline-block;
padding-bottom: 5px;
cursor: pointer;
}
#quiz-answers summary, #quiz-answers h2 {
color: #383838;
}
.answers-container {
display: flex;
flex-direction: column;
gap: 20px;
}
.answer-item {
padding: 15px;
background-color: #e1ece4;
border: 2px solid lightgreen;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.answer-item h3 {
margin-top: 0;
color: #333;
font-size: 18px;
}
.answer-item p {
margin-bottom: 0;
color: #009214;
font-size: 16px;
font-weight: 500;
}
.answer-item p strong {
color: #1636d5;
}
"""
js = """
<script>
function validateForm() {
const questions = document.querySelectorAll(".question");
let isValid = true;
questions.forEach((question) => {
const questionType = question.getAttribute("data-type");
const inputs = question.querySelectorAll("input");
if (questionType === "single_choice" || questionType === "true_false") {
// Check if at least one radio button is selected
let hasChecked = false;
inputs.forEach((input) => {
if (input.checked) {
hasChecked = true;
}
});
if (!hasChecked) {
isValid = false;
// Highlight the question that needs attention
question.style.border = "2px solid red";
question.style.padding = "10px";
question.style.borderRadius = "5px";
} else {
question.style.border = "none";
question.style.padding = "0";
}
} else if (questionType === "multiple_choice") {
// Check if at least one checkbox is selected
let hasChecked = false;
inputs.forEach((input) => {
if (input.checked) {
hasChecked = true;
}
});
if (!hasChecked) {
isValid = false;
question.style.border = "2px solid red";
question.style.padding = "10px";
question.style.borderRadius = "5px";
} else {
question.style.border = "none";
question.style.padding = "0";
}
} else if (questionType === "fill_in_the_blank") {
// Check if the text input has a value
if (inputs[0].value.trim() === "") {
isValid = false;
question.style.border = "2px solid red";
question.style.padding = "10px";
question.style.borderRadius = "5px";
} else {
question.style.border = "none";
question.style.padding = "0";
}
}
});
return isValid;
}
function checkAnswers(event) {
event.preventDefault();
// First validate the form
if (!validateForm()) {
// Show an alert message
const alertDiv = document.createElement('div');
alertDiv.className = 'validation-alert';
alertDiv.innerHTML = '<p>Please answer all questions before submitting!</p>';
alertDiv.style.backgroundColor = '#ffdddd';
alertDiv.style.color = '#990000';
alertDiv.style.padding = '10px';
alertDiv.style.borderRadius = '5px';
alertDiv.style.marginBottom = '15px';
alertDiv.style.fontWeight = 'bold';
alertDiv.style.textAlign = 'center';
// Insert at the top of the form
const form = document.getElementById('quiz-form');
const existingAlert = document.querySelector('.validation-alert');
if (existingAlert) {
form.removeChild(existingAlert);
}
form.insertBefore(alertDiv, form.firstChild);
// Scroll to the top
window.scrollTo({ top: 0, behavior: 'smooth' });
return;
}
let score = 0;
let total = 0;
const questions = document.querySelectorAll(".question");
let userAnswer = "";
const resultElement = document.getElementById("result");
questions.forEach((question) => {
total++;
const questionType = question.getAttribute("data-type");
const correctAnswerJSON = question.getAttribute("data-answer");
const correctAnswer = JSON.parse(correctAnswerJSON);
const inputs = question.querySelectorAll("input");
if (questionType === "single_choice" || questionType === "true_false") {
// For radio buttons (single selection)
inputs.forEach((input) => {
if (input.checked) {
userAnswer = input.value;
}
});
if (userAnswer === correctAnswer) {
score++;
}
} else if (questionType === "multiple_choice") {
// For checkboxes (multiple selection)
const selectedOptions = Array.from(inputs)
.filter((input) => input.checked)
.map((input) => input.value);
// Compare arrays (needs to match exactly)
const correctArray = Array.isArray(correctAnswer)
? correctAnswer
: [correctAnswer];
if (
selectedOptions.length === correctArray.length &&
selectedOptions.every((opt) => correctArray.includes(opt))
) {
score++;
}
} else if (questionType === "fill_in_the_blank") {
// For text input
userAnswer = inputs[0].value.trim().toLowerCase();
const correctText = String(correctAnswer).trim().toLowerCase();
if (userAnswer === correctText) {
score++;
}
}
}); // Remove any validation alerts once submitted successfully
const existingAlert = document.querySelector('.validation-alert');
if (existingAlert) {
existingAlert.remove();
}
// Remove any highlight on questions
document.querySelectorAll('.question').forEach(q => {
q.style.border = 'none';
q.style.padding = '0';
});
// Display the result
resultElement.style.display = "block";
if (score === total) {
resultElement.innerHTML = `<h2>Result: </h2> <br />
<h3>Congratulations! You answered all questions correctly!</h3>
<h3>Your score: ${score}/${total}</h3>`;
} else if (score < total / 2) {
resultElement.innerHTML = `<h2>Result: </h2> <br /> <h3>Keep trying! You can do better!</h3> <h3>Your score: ${score}/${total}</h3>`;
} else {
resultElement.innerHTML = `<h2>Result: </h2> <br />
<h3>Good job! You answered ${score} out of ${total} questions correctly.</h3>
<h3>Your score: ${score}/${total}</h3>`;
}
// resultElement.style.backgroundColor = score > (total/2) ? '#e6ffe6' : '#fff0f0';
resultElement.style.border = "1px solid #ddd";
resultElement.style.borderRadius = "5px";
resultElement.style.marginTop = "20px";
answerContainer = document.getElementById('quiz-answers');
answerContainer.style.display = 'block';
}
</script>
"""
return css, js