AJAX does not work correctly

Hi! Sorry for the bad English…Here’s the problem…Here is the code using ajax to add and remove records to the table. If you open a page with data, you can both delete and add… But! after adding, deleting does not work… the id value becomes ". But if you refresh the page, everything works again. Can you tell me what the reason is?

<script>
 output='';
 
$('#post-form').on('submit',function(e){
event.preventDefault();
var self = this;
let _tlt=$("#idtitle").val();
 
let csr=$("input[name=csrfmiddlewaretoken]").val();
console.log($(this).attr('action'))
mydata={
title:_tlt,
csrfmiddlewaretoken:csr,
}
 
$.ajax({
url:$(this).attr('action'),
method:"POST",
data:mydata,
dataType:"json",
 
success:function(data){
    x=data.unit_data;
    if (data.status=='Save'){
    for(i=0;i<x.length;i++){
    output +='<tr><td class="align-middle" style="width:960px;">'+ x[i].title+'</td>'+
    '<td class="text-center align-middle">'+'<input data-sid="{{item.pk}}" value="Update" type="image" src="../static/images/update.png" style="width:25px;">'+'</td>'
    +
    '<td class="text-center align-middle">'+'<input data-sid="{{item.pk}}" data-del="{{url_delete}}" class="btn-del" value="Delete" type="image" src="../static/images/del.png" style="width:28px;">'+'</td></tr>'
    }
 
    $('#tbody').html(output)
    output='';
    $("form")[0].reset();
    //location.reload();
    }
    if (data.status == 0){
    alert('Запись не добавлена. Возможно, такая уже есть в справочнике...');
    }
}
});
}
);
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////Delete SPR
$('#tbody').on('click','.btn-del',function(){
let id=$(this).attr('data-sid');
alert(id);
let pth='/'+$(this).attr('data-del')+'/';
let csr=$("input[name=csrfmiddlewaretoken]").val();
 
mydata={sid:id, csrfmiddlewaretoken:csr,};
mythis=$(this);
$.ajax({
url:pth,
method:'POST',
data:mydata,
success:function(data){
if(data.status =='Del'){
$(mythis).closest("tr").fadeOut();
 
}
 
if(data.status ==0){
console.log('NO');
}
},
});
 
});
 
</script>

View here:

def SprDelete(request):
    if request.method == 'POST':
        id=request.POST.get('sid')
        print(id)
        pi=Unit.objects.get(pk=id)
        pi.delete()
        return JsonResponse({'status':'Del',})
    else:
        return JsonResponse({'status':0,})
def UnitList(request):
   unit = Unit.objects.all()
   form=UnitForm()
   return render(request,'store/spr/SprList.html',{'title':"Единицы измерения",
   'unit':unit,'form':form,'pic_label':'Единицы измерения','url_name': reverse('SprSave'),
   'url_delete': reverse('SprDelete'),})

HTML page:

{% extends 'store/menu.html' %}
{% load static %}
{% block DataArea %}

<div class="row">
    <div class="col-md-1  ">{{pic_label}}</div>
<div class="col-md-11 mx-auto shadow">
<table class="table  shadow ">
 <thead>

    <tr>
      <th  >
<form action={{url_name}} method="post" id="post-form">
        {% csrf_token %}
        {{ form.as_p}}</th>
<th class="pt-4 "> <button type="submit" class="btn  btn-primary btn-sm mb-3 pt-2 pb-2 " id="savebtn">Добавить</button>


</form>
</th>
    </tr>
  </thead>
</table>
<div class="scrolltable">
<table class="table shadow table-bordered">
<tbody id="tbody">
    {% for item in unit %}
<tr>
<td style="width:960px; " class="align-middle">{{item.title}}</td>

<td class="text-center align-middle" ><input data-sid="{{item.pk}}"  value="Update" type="image" src="{% static '/images/update.png' %}" width="25px" > </td>
<td class="text-center align-middle" ><input data-sid="{{item.pk}}" data-del="{{url_delete}}" class="btn-del " value="Delete" type="image" src="{% static '/images/del.png' %}" width="28px"> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
     var PictureDeleteUrl="{% static '/images/del.png' %}"
     var PictureDeleteUrl="{% static '/images/update.png' %}"
</script>
{% endblock DataArea %}

Thanks!

I think the first thing I would do would be to examine closely what is being returned by your ajax calls to ensure that the data you are receiving from the server is what you’re expecting it to be. You can either log that data to your browser’s console or you can examine it in the network tab as the response to that request.

2

I’m trying to delete it immediately after adding it without updating the entire page
PyCharm console:

Internal Server Error: /SprDelete/
Traceback (most recent call last):
  File "C:\WRH\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1823, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: ''

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\WRH\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\WRH\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "c:\WRH\whr\store\views.py", line 196, in SprDelete
    pi=Unit.objects.get(pk=id)
  File "C:\WRH\venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\query.py", line 424, in get
    clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\query.py", line 941, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\query.py", line 961, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\query.py", line 968, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "C:\WRH\venv\lib\site-packages\django\db\models\sql\query.py", line 1416, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\WRH\venv\lib\site-packages\django\db\models\sql\query.py", line 1435, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "C:\WRH\venv\lib\site-packages\django\db\models\sql\query.py", line 1370, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\WRH\venv\lib\site-packages\django\db\models\sql\query.py", line 1216, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\lookups.py", line 25, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\WRH\venv\lib\site-packages\django\db\models\lookups.py", line 77, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "C:\WRH\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1825, in get_prep_value
    raise e.__class__(
ValueError: Field 'id' expected a number but got ''.
[25/Feb/2023 22:34:56] "POST /SprDelete/ HTTP/1.1" 500 121167

So this is the step after where you’re saying the issue is occuring.

You’re calling the url spr_save, and what it’s returning is setting up your page to create the problem when SprDelete is called.

You need to examine the flow of events in the spr_save view. Identify what you’re sending to the server, examine the response, and identify where what you’re getting isn’t properly setting things up.

As I can see in your code (You have a table and if I understand you well) you need to delete a row, Is it true …

You must to define the current row first then delete it as follow

 $('table tbody').on('click', '#id_yourBtn', function(){
        
       let currentRow = $(this).closest('tr');
       // Then do what you want with this (currentRow) like
       // let productName = currentRow.find('.product-name').html();
});

And an important note here

You must fix the Value error first in order to Ajax works
The error is so clear (YOUR ID RETURNS EMPTY) check it well
Hope it helps

Yes, I see, id=" ". But why? If add location.reload() in ajax code, ( for save new record) ,it works ok…

Here is the Error … This indicates that “sid” returns empty

Try to print it to console (in js file via console.log()). To be sure it’s not empty and you will find the missing circle

So, I add new record. id=242, title=‘New Item’.

Refresh page and delete this record


Yes, id=242. Thats OK

Add another record

And try delete it without refresh page. Oops, id=’ '! Why it works with location.reload() only?

Okay, you need to make another view to get the “id” from ajax and you will use (Ajax method “GET” not “POST”). like

$.ajax({
                    type: "GET",
                    url: '{% url "AJAX_GET_VIEW" %}',
                    data: {
                        "bank_id": 'YOUR_ID',
                    
                    },
                    success: function (data) { 
                        console.log("Success ");
                    },
                    error: function () {
                        console.log("ERROR with ajax request  !!!");
                    }
                });

It will work …

Thank you very much. I’ll try to do it tomorrow. It’s night in Siberia now:))

I changed the code, but nothing works as it should :crying_cat_face:
view for delete:

def SprDelete(request):
    if request.method == 'GET':
        id=request.GET.get('sid')
        print(id)
        pi=Unit.objects.get(pk=id)
        pi.delete()
        return JsonResponse({'status':'Del',})
    else:
        return JsonResponse({'status':0,})

AJAX:

<script>
 output='';

$('#post-form').on('submit',function(e){
event.preventDefault();
var self = this;
let _tlt=$("#idtitle").val();

let csr=$("input[name=csrfmiddlewaretoken]").val();
console.log($(this).attr('action'))
mydata={
title:_tlt,
csrfmiddlewaretoken:csr,
}

$.ajax({
url:$(this).attr('action'),
method:"POST",
data:mydata,
dataType:"json",

success:function(data){

    x=data.unit_data;
    if (data.status=='Save'){
    for(i=0;i<x.length;i++){
    output +='<tr><td class="align-middle" style="width:960px;">'+ x[i].title+'</td>'+
    '<td class="text-center align-middle">'+'<input data-sid="{{item.pk}}" value="Update" type="image" src="../static/images/update.png" style="width:25px;">'+'</td>'
    +
    '<td class="text-center align-middle">'+'<input data-sid="{{item.pk}}" data-del="{{url_delete}}" class="btn-del" value="Delete" type="image" src="../static/images/del.png" style="width:28px;">'+'</td></tr>'
    }

    $('#tbody').html(output)
    output='';
    $("form")[0].reset();
    //location.reload();
    }
    if (data.status == 0){
    alert('Запись не добавлена. Возможно, такая уже есть в справочнике...');
    }
}
});
}
);
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////Delete SPR
$('#tbody').on('click','.btn-del',function(e){
event.preventDefault();
let id=$(this).attr('data-sid');
alert(id);
let pth=$(this).attr('data-del');
console.log(pth);
let csr=$("input[name=csrfmiddlewaretoken]").val();

mydata={sid:id, csrfmiddlewaretoken:csr,};
mythis=$(this);
$.ajax({
url:pth,

method:'GET',
data:mydata,
dataType:"json",

success:function(data){
if(data.status =='Del'){
$(mythis).closest("tr").fadeOut();

}

if(data.status ==0){
console.log('NO');
}
},
});




});

</script>

Message in PyCharm:
ValueError: Field ‘id’ expected a number but got ‘’.
[26/Feb/2023 10:25:08] “GET /SprDelete/?sid=&csrfmiddlewaretoken=RGmSNrDuBEo7uM82y5GZvrvRh65IMF9mM8bCdcfWXjFjJoWVuJHhB0Qb8ac
faYhY HTTP/1.1” 500 122454
Again the same error…Why?
Could you look at the whole code?
So, urls.py:

path('unit/', UnitList, name='UnitList'),
path('spr_Save/',SprSave,name='SprSave'),
path('SprDelete/',SprDelete,name='SprDelete'),

views:

def UnitList(request):
   unit = Unit.objects.all()
   form=UnitForm()
   return render(request,'store/spr/SprList.html',{'title':"Единицы измерения",
   'unit':unit,'form':form,'pic_label':'Единицы измерения','url_name': reverse('SprSave'),
   'url_delete': reverse('SprDelete'),})

# '****************************************AJAX************************************'
# сохранение на ajax (Единица измерения):
def SprSave(request):
        if request.method=='POST':
            form=UnitForm(request.POST)

        if form.is_valid():
            title=request.POST['title']
            newrecord=Unit(title=title)
            newrecord.save()
            print(newrecord.id,title)
            un=Unit.objects.values()
            unit_data=list(un)
            return JsonResponse({'status':'Save','unit_data':unit_data})
        else:
            return JsonResponse({'status':0})
#***********************//AJAX//**********************************************
# удаление единицы измерения
def SprDelete(request):
    if request.method == 'GET':
        id=request.GET.get('sid')
        print(id)
        pi=Unit.objects.get(pk=id)
        pi.delete()
        return JsonResponse({'status':'Del',})
    else:
        return JsonResponse({'status':0,})

and template:

{% extends 'store/menu.html' %}
{% load static %}
{% block DataArea %}

<div class="row">
    <div class="col-md-1  ">{{pic_label}}</div>
<div class="col-md-11 mx-auto shadow">
<table class="table  shadow ">
 <thead>

    <tr>
      <th  >
<form action={{url_name}} method="post" id="post-form">
        {% csrf_token %}
        {{ form.as_p}}</th>
<th class="pt-4 "> <button type="submit" class="btn  btn-primary btn-sm mb-3 pt-2 pb-2 " id="savebtn">Добавить</button>


</form>
</th>
    </tr>
  </thead>
</table>
<div class="scrolltable">
<table class="table shadow table-bordered">
<tbody id="tbody">
    {% for item in unit %}
<tr>
<td style="width:960px; " class="align-middle">{{item.title}}</td>

<td class="text-center align-middle" ><input data-sid="{{item.pk}}"  value="Update" type="image" src="{% static '/images/update.png' %}" width="25px" > </td>
<td class="text-center align-middle" ><input data-sid="{{item.pk}}" data-del="{{url_delete}}" class="btn-del " value="Delete" type="image" src="{% static '/images/del.png' %}" width="28px"> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock DataArea %}

All this works only with location.reload() in ajax code :roll_eyes:

I think the error is somewhere in the add function. I have added the following code in my ajax:

(function() {
        $('tr').hover(function() {
            $(this).css('background-color', '#FFFF99');
            $(this).contents('td').css({'border': '1px solid grey', 'border-left': 'none', 'border-right': 'none'});
            $(this).contents('td:first').css('border-left', '1px solid grey');
            $(this).contents('td:last').css('border-right', '1px solid grey');
        },
        function() {
            $(this).css('background-color', '#FFFFFF');
            $(this).contents('td').css('border', 'none');
        });
    });

And it also doesn’t work after adding a record :crying_cat_face: Please, help me…

Thank you all. I found the solution!This issue has been resolved

success:function(data){

    x=data.unit_data;
    if (data.status=='Save'){
    for(i=0;i<x.length;i++){
    output +='<tr><td class="align-middle" style="width:960px;">'+ x[i].title+'</td>'+
    '<td class="text-center align-middle">'+'<input data-sid="{{item.pk}}" value="Update" type="image" src="../static/images/update.png" style="width:25px;">'+'</td>'
    +
    '<td class="text-center align-middle">'+'<input data-sid='+x[i].id+' data-del="{{url_delete}}" class="btn-del" value="Delete" type="image" src="../static/images/del.png" style="width:28px;">'+'</td></tr>'
    }

x[i].id