Add support for editing questions through the admin site
Need to accept the input from the hidden_answer and multiple_choice Disable input when loading data to make /admin/questions/ more robust
This commit is contained in:
parent
b4efbc8f3f
commit
f3a089df24
@ -20,10 +20,20 @@ def questions():
|
||||
return render_template("admin/question_list.html")
|
||||
|
||||
|
||||
@Admin.route("/admin/questions/edit/<int:question_id>")
|
||||
@Admin.route("/admin/questions/edit/<int:question_id>", methods=["GET", "POST"])
|
||||
@roles_required("admin")
|
||||
def edit_question(question_id):
|
||||
if request.method == "POST":
|
||||
print(f"edit question: {request.form.get('question_text')}")
|
||||
database.update_question(question_id,
|
||||
request.form.get("question_text"),
|
||||
request.form.get("answer"),
|
||||
request.form.get("addresses")
|
||||
)
|
||||
return redirect(url_for("admin.edit_question", question_id=question_id))
|
||||
question: database.AllQuestions = get_question(database.AllQuestions, question_id)
|
||||
if "application/json" in request.accept_mimetypes.values():
|
||||
return jsonify(question.get_dict())
|
||||
return render_template("admin/edit_question.html", question=question)
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>Admin</title>
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<script src="https://kit.fontawesome.com/f2d4307e62.js" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/cosmo/bootstrap.min.css">
|
||||
{% block head %}{% endblock %}
|
||||
|
67
admin/templates/admin/edit_question.html
Normal file
67
admin/templates/admin/edit_question.html
Normal file
@ -0,0 +1,67 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<form class="container mt-5" method="post">
|
||||
<div class="form-group">
|
||||
<label for="question_text">Question</label>
|
||||
<input id="question_text" name="question_text" type="text" class="form-control" value="{{ question.question }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="answer">Answer</label>
|
||||
<input id="answer" name="answer" type="text" class="form-control" value="{{ question.answer }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="addresses">Bible Verses</label>
|
||||
<input id="addresses" name="addresses" type="text" class="form-control" value="{{ question.addresses }}">
|
||||
</div>
|
||||
{% if question.multiple_choice is not none %}
|
||||
<label class="mt-3">Multiple Choice</label>
|
||||
<div class="form-group">
|
||||
<label for="multiple_choice_difficulty">Difficulty</label>
|
||||
<div class="form-group">
|
||||
<select id="multiple_choice_difficulty" name="multiple_choice_difficulty" class="custom-select">
|
||||
<option {% if question.multiple_choice.difficulty is none %}selected=""{% endif %}>None</option>
|
||||
<option {% if question.multiple_choice.difficulty == 1 %}selected=""{% endif %} value="1">Easy</option>
|
||||
<option {% if question.multiple_choice.difficulty == 2 %}selected=""{% endif %} value="2">Medium</option>
|
||||
<option {% if question.multiple_choice.difficulty == 3 %}selected=""{% endif %} value="3">Hard</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Wrong Answers</label>
|
||||
<ul class="list-group">
|
||||
{% for answer in question.multiple_choice.wrong_answers %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<input id="answer_{{ loop.index0 }}" name="wrong_answers" class="form-control" value="{{ answer }}">
|
||||
<button class="btn" type="button" onclick="$(this).parent().remove()"><i class="fas fa-times"></i></button>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<button id="add_wrong_answer" class="btn btn-secondary" type="button">Add Answer</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if question.hidden_answer is not none %}
|
||||
<label class="mt-3">Hidden Answer</label>
|
||||
<div class="form-group">
|
||||
<label for="hidden_answer_difficulty">Difficulty</label>
|
||||
<div class="form-group">
|
||||
<select id="hidden_answer_difficulty" name="hidden_answer_difficulty" class="custom-select">
|
||||
<option {% if question.hidden_answer.difficulty is none %}selected=""{% endif %}>None</option>
|
||||
<option {% if question.hidden_answer.difficulty == 1 %}selected=""{% endif %} value="1">Easy</option>
|
||||
<option {% if question.hidden_answer.difficulty == 2 %}selected=""{% endif %} value="2">Medium</option>
|
||||
<option {% if question.hidden_answer.difficulty == 3 %}selected=""{% endif %} value="3">Hard</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button id="save" name="save" type="submit" class="btn btn-primary">Save</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
$("#add_wrong_answer").on("click", () => {
|
||||
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,7 +1,6 @@
|
||||
{% extends "admin/base.html" %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.18.2/dist/bootstrap-table.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.2/extensions/filter-control/bootstrap-table-filter-control.min.css">
|
||||
{% endblock %}
|
||||
@ -22,6 +21,16 @@
|
||||
|
||||
var filter_data = [true, false]
|
||||
|
||||
function disable_input() {
|
||||
console.log("disable");
|
||||
$("input, select").attr("disabled", true);
|
||||
}
|
||||
|
||||
function enable_input() {
|
||||
console.log("enable");
|
||||
$("input, select").removeAttr("disabled");
|
||||
}
|
||||
|
||||
$("#question-table").bootstrapTable({
|
||||
url: "/admin/question_query",
|
||||
pagination: true,
|
||||
@ -30,6 +39,15 @@
|
||||
queryParams: query_params,
|
||||
showRefresh: true,
|
||||
searchOnEnterKey: true,
|
||||
{#disableControlWhenSearch: true,#}
|
||||
onClickRow: (item, element) => {
|
||||
console.log(item);
|
||||
console.log(element);
|
||||
window.location.href = `/admin/questions/edit/${item["question_id"]}`
|
||||
},
|
||||
onLoadSuccess: enable_input,
|
||||
onPageChange: disable_input,
|
||||
onSearch: disable_input,
|
||||
columns: [
|
||||
{
|
||||
field: "question_id",
|
||||
|
37
database.py
37
database.py
@ -71,6 +71,19 @@ class AllQuestions(Base):
|
||||
def __repr__(self):
|
||||
return f"<Question: {self.question_id}>"
|
||||
|
||||
def get_dict(self):
|
||||
result = {
|
||||
"question_id": self.question_id,
|
||||
"question": self.question,
|
||||
"answer": self.answer,
|
||||
"addresses": self.addresses,
|
||||
}
|
||||
if self.hidden_answer:
|
||||
result["hidden_answer"] = self.hidden_answer.get_dict()
|
||||
if self.multiple_choice:
|
||||
result["multiple_choice"] = self.multiple_choice.get_dict()
|
||||
return result
|
||||
|
||||
|
||||
class HiddenAnswer(Base):
|
||||
__tablename__ = "category_hidden_answer"
|
||||
@ -93,6 +106,13 @@ class HiddenAnswer(Base):
|
||||
def __repr__(self):
|
||||
return f"<Question Hidden Answer: {self.question_id}>"
|
||||
|
||||
def get_dict(self):
|
||||
return {
|
||||
"question_id": self.question_id,
|
||||
"difficulty": self.difficulty,
|
||||
"hint": self.hint,
|
||||
}
|
||||
|
||||
|
||||
class MultipleChoice(Base):
|
||||
__tablename__ = "category_multiple_choice"
|
||||
@ -123,6 +143,14 @@ class MultipleChoice(Base):
|
||||
def __repr__(self):
|
||||
return f"<Question Multiple Choice: {self.question_id}>"
|
||||
|
||||
def get_dict(self):
|
||||
return {
|
||||
"question_id": self.question_id,
|
||||
"difficulty": self.difficulty,
|
||||
"hint": self.hint,
|
||||
"wrong_answers": self.wrong_answers,
|
||||
}
|
||||
|
||||
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
@ -208,3 +236,12 @@ def query_all_questions(offset, limit, query: dict = None, sort=None, order=None
|
||||
questions = q.offset(offset).limit(limit).all()
|
||||
count = q.count()
|
||||
return questions, count
|
||||
|
||||
|
||||
def update_question(question_id, question_text, answer, addresses):
|
||||
session: sqlalchemy.orm.session.Session = Session()
|
||||
question: AllQuestions = session.query(AllQuestions).get(question_id)
|
||||
question.question = question_text
|
||||
question.answer = answer
|
||||
question.addresses = addresses
|
||||
session.commit()
|
||||
|
Loading…
Reference in New Issue
Block a user