Django and AJAX - replaceWith not replacing my element, it is adding it and not removing the original

195 Views Asked by At

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?

0

There are 0 best solutions below