ajax() infinite loop

656 views
Skip to first unread message

Marco Prosperi

unread,
Aug 1, 2013, 1:25:10 PM8/1/13
to web...@googlegroups.com

hello, I would like to update the total in the view below (bottom of the message) when the user changes quantity. The following script works fine (fixed value)

<script>
jQuery(document).ready(function(){
   $(document).ajaxStop(function(){
   jQuery('#910').slideToggle();     
   jQuery('#910').html('25.0');
   jQuery('#910').slideToggle();
   return false;
   });  
});
</script>

but if I replace the jQuery('#910').html('25.0');
with:

ajax("{{=URL(r=request,c='downld',f='order_reload')}}",[],'910');

where:

def order_reload():
    total=sum((qty*db.product(idx).price for idx,qty in session.cart.items()),0.0)
    return HTML(str(total))

then after the first increment of qty the total gets refreshed continuously. How can I avoid this?

thank you in advance, Marco

p.s.: here is the view

{{extend 'layout.html'}}
<h1>Checkout</h1>
<h2>Cart</h2>
<table width="100%">
  {{for id, qty in cart.items():}}{{p=db.product(id)}}
  <tr>
    <td>{{=p.name}}</td>
    <td>&euro; {{=p.price}}</td>
    <td><span class="e" id="{{='item%s'%p.id}}">{{=qty}}</span>
    {{=A('add',callback=URL('cart_callback',vars=dict(id=p.id,action='add')),target='item%s'%p.id,_class='button pill')}}{{=A('sub',callback=URL('cart_callback',vars=dict(id=p.id,action='sub')),target='item%s'%p.id,_class='button pill')}}   
    </td>
  </tr> 
    {{pass}}
  <tr>
    <td>Total</td>
    <!-- <td>&euro;{{=sum((qty*db.product(id).price for id, qty in cart.items()),0.0)}}</td> -->
    <td><div class="one" id="910">&euro;  {{=sum((qty*db.product(id).price for id, qty in cart.items()),0.0)}}</div></td>
  </tr>
</table>


Niphlod

unread,
Aug 1, 2013, 2:46:37 PM8/1/13
to web...@googlegroups.com
well, you are hooking up to the event that gets fired every time an ajax request completes.
you "trial" code just replace the fragment with a fixed value, but if you use ajax instead the ajaxstop will fire in a loop, and it's correct that it does it.
Why are you hooking up to the ajaxstop event instead of the change event on the "quantity" field (as per your description on what is supposed to happen) ?

Marco Prosperi

unread,
Aug 1, 2013, 6:45:17 PM8/1/13
to web...@googlegroups.com

It was the first thing I tried, using the same view and the following script, but nothing happens in this case when the quantity changes. Maybe it interferes with the 'add' and 'sub' callbacks?

<script>
jQuery(document).ready(function(){
    jQuery('.e').change(function(){
    jQuery('#910').slideToggle();

    ajax("{{=URL(r=request,c='downld',f='order_reload')}}",[],'910');
    jQuery('#910').slideToggle();
});
</script>

Niphlod

unread,
Aug 2, 2013, 3:51:31 AM8/2/13
to web...@googlegroups.com
uhm. the change event must be hooked to an input that changes, not to a piece of the page ... let me understand: you have a page with a total that needs to be refreshed via ajax after having submitted with ajax the "add" or the "sub" function ?

Marco Prosperi

unread,
Aug 2, 2013, 4:07:13 AM8/2/13
to web...@googlegroups.com

I've started from the PosOnLine demo appliance. There with the 'add' and 'sub' buttons you can change the quantity of the products you want to buy, but there is no total. I've tried to add a total in the view so that when the the customer 'adds' a product both the quantity and the total changes. I can't figure out how to correctly fire the total change. There is a similar thread in this mailing on this subject list but without a useful conclusion

Marco

Niphlod

unread,
Aug 2, 2013, 4:22:23 AM8/2/13
to web...@googlegroups.com
well, given that you're not an expert on javascript events (:-P) I'd use response.js in both the add and the sub functions to trigger the changes in your total field.
This is one of the reasons that pushed me to create a new web2py.js (will be available from 2.6.0) , but you need to be comfortable with js events anyway. I think that your best shot is to put

response.js ='jQuery('#910').slideToggle();ajax("{{=URL(r=request,c='downld',f='order_reload')}}",[],'910');jQuery('#910').slideToggle();'

in the add and sub functions.

Marco Prosperi

unread,
Aug 2, 2013, 8:49:00 AM8/2/13
to web...@googlegroups.com


the solution (simple as a solution must be) is changing the 'cart_callback' to update the entire (always little) <table>. Sorry, you haven't passed the test :-P

thank you for your time!

Marco

Niphlod

unread,
Aug 2, 2013, 12:29:10 PM8/2/13
to web...@googlegroups.com
yep, but that's not playing fair ^_^ happy that you resolved the problem though.
Reply all
Reply to author
Forward
0 new messages