Add buttons to go to the next/previous question
This commit is contained in:
parent
965cd99aeb
commit
5519b04a46
@ -1,5 +1,5 @@
|
||||
import os
|
||||
from flask import request, render_template, jsonify, Flask, url_for, redirect, flash
|
||||
from flask import request, render_template, jsonify, Flask, url_for, redirect, flash, session
|
||||
from flask_security import Security, SQLAlchemySessionUserDatastore, login_user, logout_user, current_user
|
||||
from QuizTheWord import database
|
||||
from QuizTheWord.admin import admin
|
||||
@ -72,6 +72,36 @@ def check_answer():
|
||||
return jsonify(database.check_answer(question_id, answer))
|
||||
|
||||
|
||||
@app.route("/category/hidden_answer/next_question")
|
||||
def next_hidden_answer():
|
||||
if "hidden_answer_ids" not in session:
|
||||
session["hidden_answer_ids"] = []
|
||||
difficulty = request.args.get("difficulty", 1)
|
||||
next_question = database.next_hidden_answer(session["hidden_answer_ids"], difficulty)
|
||||
if next_question:
|
||||
session["hidden_answer_ids"].append(next_question.question_id)
|
||||
session.modified = True
|
||||
return jsonify(next_question.get_dict())
|
||||
else:
|
||||
session.pop("hidden_answer_ids", None)
|
||||
return jsonify(None)
|
||||
|
||||
|
||||
@app.route("/category/multiple_choice/next_question")
|
||||
def next_multiple_choice():
|
||||
if "multiple_choice_ids" not in session:
|
||||
session["multiple_choice_ids"] = []
|
||||
difficulty = request.args.get("difficulty", 1)
|
||||
next_question = database.next_multiple_choice(session["multiple_choice_ids"], difficulty)
|
||||
if next_question:
|
||||
session["multiple_choice_ids"].append(next_question.question_id)
|
||||
session.modified = True
|
||||
return jsonify(next_question.get_dict_shuffled_choices())
|
||||
else:
|
||||
session.pop("multiple_choice_ids", None)
|
||||
return jsonify(None)
|
||||
|
||||
|
||||
@app.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
next_page = request.args.get("next", default=url_for("index"))
|
||||
|
@ -5,7 +5,7 @@ import sqlalchemy
|
||||
from typing import Union, Optional, Literal, Type, List, Tuple
|
||||
import random
|
||||
from sqlalchemy import Column, JSON, String, Integer, create_engine, ForeignKey, func, Boolean, UnicodeText, DateTime
|
||||
from sqlalchemy.sql.expression import or_, and_
|
||||
from sqlalchemy.sql.expression import and_
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import sessionmaker, relationship, scoped_session
|
||||
@ -410,11 +410,27 @@ def query_users(offset, limit, query: dict = None, sort=None, order=None) -> Tup
|
||||
if sort and order:
|
||||
order_by = getattr(getattr(User, sort), order)()
|
||||
q = session.query(User).filter(*query_params).order_by(order_by)
|
||||
questions = q.offset(offset).limit(limit).all()
|
||||
users = q.offset(offset).limit(limit).all()
|
||||
count = q.count()
|
||||
return questions, count
|
||||
return users, count
|
||||
|
||||
|
||||
def get_all_roles() -> List[Role]:
|
||||
session = get_session()
|
||||
return session.query(Role).all()
|
||||
|
||||
|
||||
def next_hidden_answer(previous_questions: List[int], difficulty) -> HiddenAnswer:
|
||||
session = get_session()
|
||||
return session.query(HiddenAnswer)\
|
||||
.filter(HiddenAnswer.hidden_answer_difficulty == difficulty,
|
||||
HiddenAnswer.question_id.notin_(previous_questions))\
|
||||
.order_by(func.random()).first()
|
||||
|
||||
|
||||
def next_multiple_choice(previous_questions: List[int], difficulty) -> MultipleChoice:
|
||||
session = get_session()
|
||||
return session.query(MultipleChoice)\
|
||||
.filter(MultipleChoice.multiple_choice_difficulty == difficulty,
|
||||
MultipleChoice.question_id.notin_(previous_questions))\
|
||||
.order_by(func.random()).first()
|
||||
|
67
QuizTheWord/static/js/script.js
Normal file
67
QuizTheWord/static/js/script.js
Normal file
@ -0,0 +1,67 @@
|
||||
let difficulty_selection = $(".difficulty-selection");
|
||||
let btn_previous_question = $("#btn-previous-question");
|
||||
let btn_next_question = $("#btn-next-question");
|
||||
let control_btns = $(".control-btn");
|
||||
let current_difficulty = 1;
|
||||
|
||||
difficulty_selection.on("click", change_difficulty);
|
||||
btn_next_question.on("click", next_question);
|
||||
btn_previous_question.on("click", previous_question);
|
||||
|
||||
update_question();
|
||||
|
||||
function get_new_question(difficulty) {
|
||||
control_btns.attr("disabled", true);
|
||||
$.ajax(next_question_url, {
|
||||
method: "GET",
|
||||
cache: false,
|
||||
data: {difficulty: difficulty},
|
||||
dataType: "json",
|
||||
success: (data, textStatus, jqXHR) => {
|
||||
control_btns.attr("disabled", false);
|
||||
question_received(data);
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function change_difficulty(event) {
|
||||
difficulty_selection.removeClass("active");
|
||||
let target = $(event.target);
|
||||
target.addClass("active");
|
||||
if (target.prop("innerText") === "Easy") {
|
||||
current_difficulty = 1;
|
||||
} else if (target.prop("innerText") === "Medium") {
|
||||
current_difficulty = 2;
|
||||
} else {
|
||||
current_difficulty = 3;
|
||||
}
|
||||
update_question();
|
||||
}
|
||||
|
||||
function next_question() {
|
||||
let difficulty = questions[current_difficulty-1]
|
||||
let question_index = difficulty["current_question"]+1;
|
||||
if (difficulty["questions"].length === question_index) {
|
||||
get_new_question(current_difficulty);
|
||||
} else {
|
||||
difficulty["current_question"] += 1;
|
||||
update_question();
|
||||
}
|
||||
}
|
||||
|
||||
function previous_question() {
|
||||
questions[current_difficulty-1]["current_question"] -= 1;
|
||||
update_question();
|
||||
}
|
||||
|
||||
function question_received(data) {
|
||||
let difficulty = questions[current_difficulty-1];
|
||||
if (data) {
|
||||
difficulty["questions"].push(data);
|
||||
difficulty["current_question"] += 1;
|
||||
update_question();
|
||||
} else {
|
||||
difficulty["last_index"] = difficulty["current_question"];
|
||||
update_question();
|
||||
}
|
||||
}
|
@ -11,20 +11,22 @@
|
||||
<p id="question-answer" class="d-none answer"></p>
|
||||
<div id="bible-verses"></div>
|
||||
</div>
|
||||
<button id="btn-previous-question" class="btn btn-primary mt-2 float-start control-btn">Previous</button>
|
||||
<button id="btn-next-question" class="btn btn-primary mt-2 float-end">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-pills justify-content-center mt-2">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active difficulty-selection" id="btn-show-easy" type="button" aria-controls="easy" aria-selected="true">Easy
|
||||
<button class="nav-link active difficulty-selection control-btn" id="btn-show-easy" type="button" aria-controls="easy" aria-selected="true">Easy
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link difficulty-selection" id="btn-show-medium" type="button" aria-controls="medium" aria-selected="false">Medium
|
||||
<button class="nav-link difficulty-selection control-btn" id="btn-show-medium" type="button" aria-controls="medium" aria-selected="false">Medium
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link difficulty-selection" id="btn-show-hard" type="button" aria-controls="hard" aria-selected="false">Hard
|
||||
<button class="nav-link difficulty-selection control-btn" id="btn-show-hard" type="button" aria-controls="hard" aria-selected="false">Hard
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@ -34,36 +36,41 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
next_question_url = "{{ url_for("next_hidden_answer") }}";
|
||||
let questions = [
|
||||
{{ easy.get_dict()|tojson }},
|
||||
{{ medium.get_dict()|tojson }},
|
||||
{{ hard.get_dict()|tojson }},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ easy.get_dict()|tojson }}],
|
||||
},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ medium.get_dict()|tojson }}],
|
||||
},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ hard.get_dict()|tojson }}],
|
||||
},
|
||||
];
|
||||
let difficulty_selection = $(".difficulty-selection");
|
||||
let btn_show_answer = $("#btn-show-answer");
|
||||
let question_answer = $("#question-answer");
|
||||
let current_difficulty = 1;
|
||||
|
||||
change_difficulty(current_difficulty);
|
||||
|
||||
difficulty_selection.on("click", (event) => {
|
||||
difficulty_selection.removeClass("active");
|
||||
let target = $(event.target);
|
||||
target.addClass("active");
|
||||
if (target.prop("innerText") === "Easy") {
|
||||
current_difficulty = 1;
|
||||
} else if (target.prop("innerText") === "Medium") {
|
||||
current_difficulty = 2;
|
||||
} else {
|
||||
current_difficulty = 3;
|
||||
}
|
||||
change_difficulty(current_difficulty);
|
||||
})
|
||||
|
||||
btn_show_answer.on("click", showAnswer);
|
||||
|
||||
function change_difficulty(difficulty) {
|
||||
let question = questions[difficulty-1];
|
||||
function update_question() {
|
||||
let difficulty = questions[current_difficulty-1];
|
||||
let question_index = difficulty["current_question"];
|
||||
let question = difficulty["questions"][question_index];
|
||||
if (question_index === 0) {
|
||||
btn_previous_question.attr("disabled", true);
|
||||
} else {
|
||||
btn_previous_question.attr("disabled", false);
|
||||
}
|
||||
if (question_index === difficulty["last_index"]) {
|
||||
btn_next_question.attr("disabled", true);
|
||||
} else {
|
||||
btn_next_question.attr("disabled", false);
|
||||
}
|
||||
|
||||
if (question["answer_visible"]) {
|
||||
btn_show_answer.css("display", "none");
|
||||
question_answer.removeClass("d-none");
|
||||
@ -77,9 +84,12 @@
|
||||
}
|
||||
|
||||
function showAnswer() {
|
||||
questions[current_difficulty-1]["answer_visible"] = true;
|
||||
let question_index = questions[current_difficulty-1]["current_question"];
|
||||
let question = questions[current_difficulty-1]["questions"][question_index];
|
||||
question["answer_visible"] = true;
|
||||
question_answer.removeClass("d-none");
|
||||
btn_show_answer.css("display", "none");
|
||||
}
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
@ -9,20 +9,22 @@
|
||||
<h5 id="question-text"></h5>
|
||||
<div id="question-choices" class="list-group"></div>
|
||||
</div>
|
||||
<button id="btn-previous-question" class="btn btn-primary mt-2 float-start control-btn">Previous</button>
|
||||
<button id="btn-next-question" class="btn btn-primary mt-2 float-end control-btn">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-pills justify-content-center mt-2">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active difficulty-selection" id="btn-show-easy" type="button" aria-controls="easy" aria-selected="true">Easy
|
||||
<button class="nav-link active difficulty-selection control-btn" id="btn-show-easy" type="button" aria-controls="easy" aria-selected="true">Easy
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link difficulty-selection" id="btn-show-medium" type="button" aria-controls="medium" aria-selected="false">Medium
|
||||
<button class="nav-link difficulty-selection control-btn" id="btn-show-medium" type="button" aria-controls="medium" aria-selected="false">Medium
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link difficulty-selection" id="btn-show-hard" type="button" aria-controls="hard" aria-selected="false">Hard
|
||||
<button class="nav-link difficulty-selection control-btn" id="btn-show-hard" type="button" aria-controls="hard" aria-selected="false">Hard
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@ -32,32 +34,37 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
next_question_url = "{{ url_for("next_multiple_choice") }}";
|
||||
let questions = [
|
||||
{{ easy.get_dict_shuffled_choices()|tojson }},
|
||||
{{ medium.get_dict_shuffled_choices()|tojson }},
|
||||
{{ hard.get_dict_shuffled_choices()|tojson }},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ easy.get_dict_shuffled_choices()|tojson }}],
|
||||
},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ medium.get_dict_shuffled_choices()|tojson }}],
|
||||
},
|
||||
{
|
||||
"current_question": 0,
|
||||
"questions": [{{ hard.get_dict_shuffled_choices()|tojson }}],
|
||||
},
|
||||
];
|
||||
let difficulty_selection = $(".difficulty-selection");
|
||||
let current_difficulty = 1;
|
||||
|
||||
change_difficulty(current_difficulty);
|
||||
|
||||
difficulty_selection.on("click", (event) => {
|
||||
difficulty_selection.removeClass("active");
|
||||
let target = $(event.target);
|
||||
target.addClass("active");
|
||||
if (target.prop("innerText") === "Easy") {
|
||||
current_difficulty = 1;
|
||||
} else if (target.prop("innerText") === "Medium") {
|
||||
current_difficulty = 2;
|
||||
function update_question() {
|
||||
let difficulty = questions[current_difficulty-1];
|
||||
let question_index = difficulty["current_question"];
|
||||
let question = difficulty["questions"][question_index];
|
||||
if (question_index === 0) {
|
||||
btn_previous_question.attr("disabled", true);
|
||||
} else {
|
||||
current_difficulty = 3;
|
||||
btn_previous_question.attr("disabled", false);
|
||||
}
|
||||
if (question_index === difficulty["last_index"]) {
|
||||
btn_next_question.attr("disabled", true);
|
||||
} else {
|
||||
btn_next_question.attr("disabled", false);
|
||||
}
|
||||
change_difficulty(current_difficulty);
|
||||
})
|
||||
|
||||
function change_difficulty(difficulty) {
|
||||
let question = questions[difficulty-1];
|
||||
$("#question-text").text(question["question_text"]);
|
||||
$("#bible-verses").text(question["addresses"]);
|
||||
$("#question-choices").empty();
|
||||
@ -83,7 +90,9 @@
|
||||
}
|
||||
|
||||
function checkAnswer(question_id, button_index, answer) {
|
||||
let question = questions[current_difficulty-1];
|
||||
let difficulty = questions[current_difficulty-1];
|
||||
let question_index = difficulty["current_question"];
|
||||
let question = difficulty["questions"][question_index];
|
||||
question["chosen_answer"] = button_index;
|
||||
let loading_spinner = $("<div>")
|
||||
.attr("id", "check-answer")
|
||||
@ -116,4 +125,5 @@
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user