By standard scenario I mean you have a base page A, with a button for adding an item to a list, the button is the submit button of a form so that you make a “POST” request to the page with some data. So then I reserve GET requests for just showing the page. That would result in 4-6 items being added to my UL instead of just 1.
Now I’m doing it with AJAX which is the proper way I guess and it’s doing much worse!
Here is relevant code:
ArrowGlue/db/views.py:
statement = Statement.nodes.get(uid=statement_id)
if statement is None:
return HttpResponseRedirect('test1') # TODO error page
add_given_form = add_goal_form = None
if request.method == 'POST':
part = request.POST.get('statement_part')
if part == 'given':
index = len(statement.given_indices)
statement.given_indices.append(index)
form = add_given_form = AddToStatementForm(request.POST)
elif part == 'goal':
index = len(statement.goal_indices)
statement.goal_indices.append(index)
form = add_goal_form = AddToStatementForm(request.POST)
else:
assert 0
content = Content(display_index=index, maintainer='Debug')
content.save()
if form.is_valid():
kind = form.cleaned_data['kind']
if kind == 'sketch':
sketch = DiagramSketch()
sketch.save()
content.sketch.connect(sketch)
content.save()
elif kind == 'text':
pass
else:
assert 0
statement.content.connect(content)
statement.save()
else:
return redirect(reverse('test1')) #TODO
if add_given_form is None:
add_given_form = AddToStatementForm()
if add_goal_form is None:
add_goal_form = AddToStatementForm()
if len(statement.given_indices) + len(statement.goal_indices):
query = f'''
MATCH (s:Statement)-[r:CONTAINS]->(c:Content)
RETURN c
'''
results = db.cypher_query(query)
if results:
results = results[0]
results = [Content.inflate(res[0]) for res in results if res]
givens = set(statement.given_indices)
goals = set(statement.goal_indices)
givens = list(filter(lambda c: c.display_index in givens, results))
goals = list(filter(lambda c: c.display_index in goals, results))
else:
givens = []
goals = []
else:
givens = []
goals = []
context = {
'statement': statement,
'givens': givens,
'goals': goals,
'add_goal_form': add_goal_form,
'add_given_form': add_given_form,
}
return render(request, 'db/edit_statement.html', context)
ArrowGlue/db/urls.py:
import db.views as views
from django.urls import path
urlpatterns = [
path("react-example1/", views.react_index1, name="react_example1"),
path("test1/", views.test1, name='test1'),
path("edit-statement/<str:statement_id>", views.edit_statement, name='edit_statement'),
path("new-statement/", views.new_statement, name='new_statement'),
path("edit-proof/<str:proof_id>", views.edit_proof, name='edit_proof'),
path("new-proof/", views.new_proof, name='new_proof')
]
from django import forms
from ArrowGlue.settings import MAX_DB_TEXT_LENGTH
class NewProofForm(forms.Form):
title = forms.CharField(label="Proof Title", max_length=MAX_DB_TEXT_LENGTH)
class NewStatementForm(forms.Form):
title = forms.CharField(label="Statement Title", max_length=MAX_DB_TEXT_LENGTH)
class AddToStatementForm(forms.Form):
kind = forms.ChoiceField(choices=(('text', 'Purely textual language'),('sketch', 'Diagram sketch')))
ArrowGlue/templates/db/edit_statement.html:
{% load crispy_forms_tags %}
{% block content %}
<h1>{{ statement.text }}</h1>
<p>
<h2>Givens</h2>
<ul id="given-list">
{% for given in givens %}
<li>{{ given.text }}</li>
{% endfor %}
<li>
<form method="POST" id="add-given-form" action="#">
{% csrf_token %}
{{ add_given_form|crispy }}
<input type="hidden" name="statement_part" value="given">
<button type="submit" class="btn btn-primary">+</button>
</form>
</li>
</ul>
</p>
<p>
<h2>Goals</h2>
<ul id="goal-list">
{% for goal in goals %}
<li>{{ goal.text }}</li>
{% endfor %}
<li>
<form method="GET" id="add-goal-form">
{% csrf_token %}
{{ add_goal_form |crispy }}
<input type="hidden" name="statement_part" value="goal">
<button type="submit" class="btn btn-primary">+</button>
</form>
</li>
</ul>
</p>
<script>
function ajax_post_form(form, on_success)
{
form.submit(function() {
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'),
url: $(this).attr('action'),
success: on_success,
});
}
}
$(document).ready(function() { // this waits until the document is fully loaded
// Put custom logic here
$("#add-given-form").submit(function() { // catch the form's submit event
ajax_post_form($(this), function(response) {
$("#given-list").append(response['text']);
});
return false;
});
$("#add-goal-form").submit(function() { // catch the form's submit event
ajax_post_form($(this), function(response) {
$("#given-list").append(response['text']);
});
return false;
});
}
</script>
{% endblock %}
Not sure how to fix this one!
Debug output:
[07/Aug/2024 15:37:00] “GET /db/new-statement/ HTTP/1.1” 200 1056
[07/Aug/2024 15:37:00] “GET /db/new-statement/ HTTP/1.1” 200 1056
[07/Aug/2024 15:37:07] “POST /db/new-statement/ HTTP/1.1” 302 0
[07/Aug/2024 15:37:08] “GET /db/edit-statement/4a266da937a348ff9772b9afb8316c45 HTTP/1.1” 200 3288
[07/Aug/2024 15:43:30] “POST /db/edit-statement/4a266da937a348ff9772b9afb8316c45 HTTP/1.1” 200 3762
[07/Aug/2024 15:46:35] “GET /db/edit-statement/4a266da937a348ff9772b9afb8316c45?csrfmiddlewaretoken=hymoTjeYxoW31rrYEOvyxGdyYm719aRPGL79tt2h45UtDmdXTzS3QwdFIhqyc0iW&kind=text&statement_part=goal HTTP/1.1” 200 3753
[07/Aug/2024 15:46:40] “POST /db/edit-statement/4a266da937a348ff9772b9afb8316c45?csrfmiddlewaretoken=hymoTjeYxoW31rrYEOvyxGdyYm719aRPGL79tt2h45UtDmdXTzS3QwdFIhqyc0iW&kind=text&statement_part=goal HTTP/1.1” 200 4196
Granted this looks normal, but when I’m debugging it’s seeming like it’s not my code but Django calling the view 4-20 times!
IDK what’s going on… -_-
Picture of unuseable UX: