0

I am trying to send a post in a Django project to switch a boolean from False to True. The button is working fine but I want to click it without refreshing the page so I am trying to use Ajax but I keep getting {"status": "error"} for a bad request and not sure why.

Here is the views:

def change_status(request, id):
    if request.is_ajax() and request.method == 'POST':
        startsession = Workout.objects.get(id=id)
        startsession.active = True if request.POST.get('active') == 'true' else False
        startsession.save()
        data = {'status': 'success', 'active': startsession.active}
        return JsonResponse(data, status=200)
    else:
        data = {'status': 'error'}
        return JsonResponse(data, status=400)

Here is the template:

        <div>
          {% if object.active %}
            <button disabled  type="button">Start the workout</button>
          {% else %}
              <a href="{% url 'my_gym:bla' object.id %}">
              <button id="customSwitches" onclick="start();" type="button">Start the workout</button>
              </a>
          {% endif %}
        </div>

Here is the ajax script

        <script>
                    $(document).ready(function()
                    $("#customSwitches").on('click', function () {
                      $.ajax({
                        url: "{% url 'my_gym:bla' object.id %}",
                        data: {
                          csrfmiddlewaretoken: "{{ csrf_token }}",
                          active: this.disabled
                        },
                        type: "POST",
                        dataType: 'json',

                      });
                      .done(function(data) {
                          console.log(data);
                      })
                      .always(function() {
                          console.log('[Done]');
                      })
                    })
                    });
        </script>

it is working fine with the following views.py:

def change_status(request, id):
    url = request.META.get('HTTP_REFERER')  # get last url
    startsession = Workout.objects.get(id=id)
    startsession.active = True
    startsession.save()
    return HttpResponseRedirect(url)

--------------------------------------Update------------------------------------------------------

Here is another trial which is returning nothing at all no response:

def change_status(request,id):
    # startsession = get_object_or_404(ActiveSession, id=id)
    startsession = Workout.objects.get(id=id)
    startsession.active = True
    startsession.save()
    context = {
        'startsession': startsession,
    }
    if request.is_ajax:
        html = render_to_string('my_gym/start_workout.html', context, request=request)
        return JsonResponse({'form': html})

here is the template and script:

{{ object.active }}
    <div id="startworkout">
      <form action="{% url 'my_gym:bla' object.id %}" method='post'>
          {% csrf_token %}
              {% if object.active %}
              <button disabled  type="button" class="mt-3 btn btn-dark btn-block mb-4 ripple-surface">Start the workout</button>
              {% else %}
                <button id="customSwitches" onclick="start();" type="button" class="mt-3 btn btn-dark btn-block mb-4 ripple-surface">Start the workout</button>
              {% endif  %}
      </form>
    </div>

    <script type="text/javascript">
        $(document).ready(function(event){     <-------- error here
            $(document).on('click','#customSwitches', function(event){
                event.preventDefault();
                var id= $(this).attr('value');
                $.ajax({
                    type:'POST',
                    url:'{% url 'my_gym:bla' object.id %}',
                    data:{'id': id, 'csrfmiddlewaretoken':'{{csrf_token}}'},
                    dataType:'json',
                    success:function(response){
                        $('#startworkout').html(response['form'])
                        console.log($('#startworkout').html(response['form']));
                    },
                    error:function(rs, e){
                        console.log(rs.responseText);
                    },
                });
            });
        });
    </script>

here is the error in the console: Uncaught ReferenceError: $ is not defined at (index):145:9 which is related to $(document).ready(function(event){ Question: How can I add ajax to the following views to prevent the page from refreshing everytime the button is clicked

Thank you

A_K
  • 731
  • 3
  • 15
  • 40

1 Answers1

0

You code on template is the problem {% if object.active %} this django code will only work on the initialization of the page. you can try my code below:

TEMPLATE:

<script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; </script>

    <div id='divAppend'></div>

    $.ajax({
    url: "{% url 'YOUR URL' %}",
    type: "POST",
    data: {
      'active' : 'True or False' 
    },
    headers: { 'X-CSRFToken': csrftoken },
    success: function (data) {
      $('#divAppend').html()
      html_val=""
      
      if(data.status !== ''){
        html_val+='<button disabled  type="button">Start the workout</button>'
      }
      else{
        html_val+='<a href="{% url 'my_gym:bla' object.id %}">'
        html_val+='<button id="customSwitches" onclick="start();" type="button">Start the workout</button>'
        html_val+='</a>'
      }

      $('#divAppend').append(html_val)

    },
    error: function(){
        console.log('Error. Failed to update the details!...');
    }
  })

YOU VIEWS.PY

def change_status(request, id):
    context = {}

    if request.is_ajax() and request.method == 'POST':
        startsession = Workout.objects.get(id=id)
        startsession.active = True if request.POST.get('active') == 'true' else False
        startsession.save()
        context.update({'status': 'success'})
        context.update({'active': str(startsession.active)})
    else:
        context.update({'status': 'error'})
        context.update({'active': ''})

    return JsonResponse(data=context)
romel rada
  • 21
  • 4
  • @roel rada it is returning the same error but could you provide more context to understand what is happening here – A_K Sep 06 '22 at 23:49
  • I updated my answer, check if it will work. if you want to trouble shoot it, check first if the view is returning data by priinting variables, if yes then check on ajax success if data has value. also, please do not forget the csrf token it is important on ajax and views communication – romel rada Sep 08 '22 at 04:46
  • I tried this code but still not working I believe there is something not correct in the script as I am trying to fix and prevent it from blending in the html text . It is currently showing as text – A_K Sep 09 '22 at 00:33