2

I'm trying to pass a Javascript array to my Django views. This works, but I would like to manipulate that data and display it in a separate url. So I have a products page, where you select items. When the form is submitted, this javascript is called, and I want it to redirect to a cart page:

$("#getArr").submit(function(){
  var data = {'ab[]' : chosen};
  $.post('cart/', data, function(response){
    if(response == 'success'){ 
      window.location.href="cart/" // references my views
    }
    else{ 
      alert('Error! :('); 
    }
  });
});

views.py

def cart(request):
  if request.method == 'POST':
    chosen = request.POST.getlist('ab[]')
    print(chosen, file=sys.stderr)
    template = loader.get_template('o/cart.html')
    context = {'prodChosen': chosen,
                'e': "hy"}
    return HttpResponse('success')
    # return HttpResponse(template.render(context, request))
else:
    template = loader.get_template('o/cart.html')
    context = {}
    return HttpRepsonse('fail')
    # return HttpResponse(template.render(context, request))

Like in the commented out HttpResponse lines, I need to pass data to my cart.html (it will be objects from one of my models). I have no idea how to pass data to my cart page.

The line print(chosen, file=sys.stderr) has been quite useful. Previously, when I had code that used the commented out return HttpResponse lines, it printed to my terminal both the desired array and an empty one. However, with this new code, the desired array prints out but it doesn't redirect to the new page. I'm not sure why this is happening, but I do know the fact the empty array printed out at as well in my earlier attempt meant my cart page wasn't receiving the correct array data.

Edit: I need to pass model objects to the new html page, which (from what I know) I can't do through javascript

index.html

<form id="getArr" method="POST">
      {% csrf_token %}
      <button type='submit' id="checkCart">Check Added Items</button>
</form>
lena
  • 73
  • 3
  • 7
  • You can use render. First import it from django.shortcuts import redirect, render and then you can `return render(request, 'cart.html.html', context)`. – kapilsdv Jul 15 '16 at 16:02
  • Possible duplicate of [How can I make a page redirect using jQuery?](http://stackoverflow.com/questions/503093/how-can-i-make-a-page-redirect-using-jquery) – lorond Jul 15 '16 at 16:07
  • I tried using `window.location.href`, but I need the page to redirect from django, since I want to pass model objects to the page. Also, using `render` gave me the same result. – lena Jul 15 '16 at 16:12
  • 1
    Why `window.location.href` ? You will lose the data if you redirect like this. Also can you make `#getArr` a form and then `post` it to the `cart/`. – kapilsdv Jul 15 '16 at 16:54

1 Answers1

2

If I understand the question correctly, I think you are adding an extra step by using JQuery at all.

Solution #1 - Create a form element on the fly in jQuery and submit that form to your Django endpoint. In Django render template normally.

Javascript

$("#getArr").submit(function(){
  var url = 'cart/';
  var form = '<form action="' + url + '" method="post">';
  for (var i = 0; i < chosen.length; i++) {
      form += '<input type="hidden" name="ab[]" value="' + chosen[i] + '" />'
  };
  form += '</form>'
  var form_element = $(form);
  $('body').append(form_element);
  form_element.submit();
});

And then in your view, simply return the template as usual:

views.py

def cart(request):
  if request.method == 'POST':
    chosen = request.POST.getlist('ab[]')
    print(chosen, file=sys.stderr)
    template = loader.get_template('o/cart.html')
    context = {'prodChosen': chosen,
                'e': "hy"}
    return HttpResponse(template.render(context, request))
else:
    template = loader.get_template('o/cart.html')
    context = {}
    return HttpRepsonse('fail')
    # return HttpResponse(template.render(context, request))

Solution #2 - Use jQuery .load() function function and submit that form to your Django element. In Django render template normally (or as a snippet to avoid repeating other page elements).

Javascript

$("#getArr").submit(function(){
  $('#main-content-div').load('cart/', $("#getArr").serialize());
});

views.py

def cart(request):
  if request.method == 'POST':
    chosen = request.POST.getlist('ab[]')
    print(chosen, file=sys.stderr)
    template = loader.get_template('o/cart.html')
    context = {'prodChosen': chosen,
                'e': "hy"}
    return HttpResponse(template.render(context, request))
else:
    template = loader.get_template('o/cart.html')
    context = {}
    return HttpRepsonse('fail')
    # return HttpResponse(template.render(context, request))

Solution #3 - Create a typical HTML form with elements name ab[] and submit that form to your Django endpoint. In Django render template normally.

The form:

HTML

<form id="getArr" action="cart/" method="POST">
    <input type="text" name="ab[]" value="product_id_1"/>
    <input type="text" name="ab[]" value="product_id_2"/>
    <input type="text" name="ab[]" value="product_id_3"/>
    <input type="submit" value="Submit" />
</form>

Some Javascript to add elements to the form:

Javascript

$('.add_product').click(function(){
    $('#getArr').append('<input type="hidden" name="ab[]" value="' + $(this).attr('product_id') + '"/>')
})

Django view:

views.py

def cart(request):
  if request.method == 'POST':
    chosen = request.POST.getlist('ab[]')
    print(chosen, file=sys.stderr)
    template = loader.get_template('o/cart.html')
    context = {'prodChosen': chosen,
                'e': "hy"}
    return HttpResponse(template.render(context, request))
else:
    template = loader.get_template('o/cart.html')
    context = {}
    return HttpRepsonse('fail')
    # return HttpResponse(template.render(context, request))
Matthew Graves
  • 3,226
  • 1
  • 17
  • 20
  • I do have a POST form in my HTML file (the form's id is getArr), but how would I pass the javascript array to HTML without jquery? – lena Jul 15 '16 at 16:56
  • if you have several input elements in the form, that all have the same name (`ab[]` in your case), then Django will recognize them as an array when that form is posted. I'm not sure how the variable `chosen` is defined in your code. But if you simply added hidden fields to the `getArr` form whenever a product is selected that look like this `` then the `request.POST.getlist('ab[]')` call in your view should work. – Matthew Graves Jul 15 '16 at 17:06
  • I added an example of a form that would work to my answer – Matthew Graves Jul 15 '16 at 17:11
  • It might help if you added the html for the `getArr` element to your post, so I have a better understanding of what the situation is. – Matthew Graves Jul 15 '16 at 17:35
  • I updated the post with the html code. also `chosen` is just an array in js. – lena Jul 15 '16 at 17:47
  • With a bit of tweaking, I was able to get solution3 to work. I actually didn't need any of the input fields in the form for this to work. Why is that? – lena Jul 15 '16 at 18:15
  • What code handles the user selecting a product? I imagine that it adds elements to the `getArr` form. – Matthew Graves Jul 15 '16 at 18:56
  • I probably should have done it that way, but I just stored the selected elements into a javascript array, and through a final submit button, it submits the values. – lena Jul 15 '16 at 19:36