I am doing an AJAX call on my django application to update data on the page without refreshing. When I submit the AJAX request and use replaceWith() the element I am trying to replace is getting added to the page, but not replacing the original.
Simplified code:
page.html
<table>
{% for form in formset %}
<tr>
<td>{{form.evidence}}</td>
{% include 'detail.html' %}
</tr>
{% endfor %}
</table>
detail.html
{% if obj %}
{% if updated %}
<td id='{{obj.id}}-detail' colspan=2>Updated</td>
{% else %}
<td id='{{obj.id}}-detail'>not updated</td>
{% include 'save_container.html' %}
{% endif %}
{% else %}
{% include 'save_container.html' %}
{% endif %}
save_container.html
<div class='btn-group mr-1 mb-1'>
<button id='{{ form.instance.id }}-save-button' action="{% url 'results:save_class' %}"
type='button' class="btn btn-warning save-classification">Save</button>
</div>
views.py
def save_class(request):
data = dict()
if request.method == 'POST' and request.is_ajax():
obj = Table.objects.get(id=request.POST['id'])
form = Form(data=request.POST, instance=obj, saved=True)
if form.is_valid():
... save form to table ...
data['form_is_valid'] = True
obj = VariantClassification.objects.get(id=obj.id)
data['html_detail'] = render_to_string(
'details.html',
{'obj': obj,
'updated': True
})
else:
data['form_is_valid'] = False
data['form_errors'] = form.errors.values()
return JsonResponse(data)
save.js
$(function () {
$(".save-classification").click(function () {
var id = $(this).attr('id').replace('-save-button','');
var url = $(this).attr('action');
var var_n = $(this)
var evidence = $(this).closest("tr").find("td." + id + '-evidence-cell').find("li.evidence-cohort-li").find("input.textinput").val();
// some validation...
data = {
id: id,
evidence: evidence,
save: true,
}
$.ajax({
url: url,
type: 'post',
data: data,
dataType: 'json',
success: function (data){
if (data.form_is_valid) {
console.log('Save variant form is valid')
console.log(data['variant_classification_id'])
var cell = $('#'.concat(data['variant_classification_id']
).concat('-detail'))
cell.replaceWith(data.html_detail);
} else {
alert('Form is not valid. '.concat(data['form_errors']).concat(
' Please save any other classified variants and then refresh the page to continue.'))
// if(confirm('Form is not valid. '.concat(data['form_errors']))){
// window.location.reload();
// }
}
},
error: function () {
console.log('Error: Not saved with AJAX')
},
});
return false;
});
});
So I am trying to replace the contents of the tag in detail.html with the new contents of html_detail, which should update the obj.updated=True, and therefore only display Updated as below in detail.html:
{% if obj.updated %}
<td id='{{obj.id}}-detail' colspan=2>Updated</td>
{% else %}
<td id='{{obj.id}}-detail'>not updated</td>
{% include 'save_container.html' %}
{% endif %}
However, the page updated to have both of the above tags i.e:
<td id='{{obj.id}}-detail' colspan=2>Updated</td>
<td id='{{obj.id}}-detail'>not updated</td>
{% include 'save_container.html' %}
How can I fully replace the not updated tag in detail.html using obj.updated=True once the AJAX call and form validation is completed?