Reload a component form another component without submit form

124 views
Skip to first unread message

Michel Krav

unread,
Sep 11, 2014, 10:21:26 AM9/11/14
to web...@googlegroups.com
Hi,

I'd like to reload a component when an event (dble click) occurs on client side (browser) from another component :

I am not able to solve on my own those issues using the code below :
- when setting ajax = True to second component LOAD, the script do not provide the sid anymore.
- make the ajax call reload the first form

I have a main page made of 2 components : one form and one grid :

Main page view is :

{{extend 'layout.html'}}
<div id="target" hidden="true"></div>
{{ =LOAD('default','army_header.load', ajax=True , ajax_trap=False , target='army_header') }}
{{ =LOAD('default','cards_list.load', ajax=False  ,ajax_trap=False, target='cards_list', vars={'mode':'edit'}) }}
<script>
// catch Id of selected and double clicked row card
jQuery(document).ready(function() {
        jQuery('tr.w2p_even.even.with_id,tr.w2p_odd.odd.with_id').dblclick(function() {
        var sid =  jQuery(this).prop('id');
        ajax('on_card_selected?card_id='+sid, [] ,'army_header') ;                        }
                                                                            ) ;
                                    }
                        );
</script>

army_header.load view is :
<hr>
{{=formarmy}}

cards_list.load view is :
<hr>
{{=formcards}}

The controller :

@auth.requires_login()   
def army_detail():
    """Page composed of 2 components """
   
    some_stuff()
   
    army_header()
   
    cards_list()
   
    return dict()

@auth.requires_login()
def army_header():
   
    some_stuff()
         
    form = SQLFORM(db.myarmy )
   
    # Mode vars unknown : create army
    if form.process(keepvalues=True).accepted:
         
        update_db()
     
    return dict(formarmy=form)
 
@auth.requires_login()
def cards_list():
       
    form = SQLFORM.grid(db.cards)

    return dict( formcards=form)
  
   
@auth.requires_login()
def on_card_selected():
           
    # Load session variables :
    card_id = session.card_id = int(request.vars.card_id)
   
    some_stuff()
   
    # want to refresh component :
    army_header()  #

Thanks.

Niphlod

unread,
Sep 13, 2014, 10:29:09 AM9/13/14
to web...@googlegroups.com
you need to bind to document events instead of currently available ones.
The problem is that when the js run there are some elements the event is binded, but those gets entirely replaced when you load the component.
So, please, use .on() instead of the direct dbclick event (and ready about jquery event delegation system)

Michel Krav

unread,
Sep 15, 2014, 7:44:49 AM9/15/14
to web...@googlegroups.com

Thanks Niphlod using the on() function:
<script>
jQuery
(document).ready(function()
       
{
         jQuery
('tr.w2p_even.even.with_id,tr.w2p_odd.odd.with_id ').on("dblclick",function() {

                                                                                       
var sid =  jQuery(this).prop('id');

                                                                                        ajax
( "{{=URL('default', 'on_card_selected.html' ) }}",[],'target');
                                                                                               
}
                                                                           
);
       
}
                       
);
</script>

solve my first pb.

For the other point, I still get None to my ajax call in this script, maybe ajax is not the solution to reload my first component, any way to follow ?

Michel Krav

unread,
Sep 15, 2014, 11:28:41 AM9/15/14
to web...@googlegroups.com

For now I'm using the walkaround below to solve the second problem, consisting of two separate ajax call :
<script>
jQuery
(document).ready(function()
       
{
         jQuery
('tr.w2p_even.even.with_id,tr.w2p_odd.odd.with_id ').on("dblclick",function() {                                                                                        
                                                                                       
var sid =  jQuery(this).prop('id');

                                                                                        ajax
('on_card_selected?card_id='+sid,[] ,'target') ;
                                                                                        ajax
( "{{=URL('default', 'update_army.load' ) }}",[],'army_header');                                                                                         ;
                                                                                               
}
                                                                       
);
       
}
                       
);
</script>

It works well 99% of time until the double click are not too fast from the end user : in this particular case,
second call can be lower than the first one.
As the first update db and the second read the db it results on no refresh on the screen until user press F5 to force it manually which is not suitable.

Niphlod

unread,
Sep 15, 2014, 2:45:40 PM9/15/14
to web...@googlegroups.com
that's not going to save you from any troubles.

did you read the jquery docs about on() ?

especially

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.

and what it follows ?

esp. the difference from

$( "#dataTable tbody tr" ).on( "click", function() {
    alert( $( this ).text() );
});

and

$( "#dataTable tbody" ).on( "click", "tr", function() {
    alert( $( this ).text() );
});

Michel Krav

unread,
Sep 16, 2014, 2:40:47 PM9/16/14
to web...@googlegroups.com

ooops, sorry niphlod, I've only read on w3schools.com site about the on() function.
And furthermore I test the code above without changing the ajax parameter of the 2nd LOAD to True...
aargh, not serious.

But now, it finally works this way :
{{extend 'layout.html'}}

{{ =LOAD('default','army_header.load', ajax=True , ajax_trap=False , user_signature=True, target='army_header') }}

{{ =LOAD('default','cards_list.load', ajax=True  ,ajax_trap=False, user_signature=True, target='cards_list', vars={'mode':'edit'}) }}

<script>
jQuery
('#cards_list').on("dblclick","tr", function() {

   
var sid =  jQuery(this).prop('id');

    ajax
('on_card_selected?card_id='+sid,[] ,'target') ;
    ajax
( "{{=URL('default', 'update_army.load' ) }}",[],'army_header');

                                                   
});
</script>..

I really need to improve myself with jquery, I'm not in line with it.

Reply all
Reply to author
Forward
0 new messages