details: http://www.bx.psu.edu/hg/galaxy/rev/052f6096e3cd changeset: 3039:052f6096e3cd user: jeremy goecks <jeremy.goecks@emory.edu> date: Mon Nov 16 14:52:33 2009 -0500 description: Ajax support for grid operations. Preparations for ajaxing history grid. diffstat: lib/galaxy/web/controllers/history.py | 18 ++-- lib/galaxy/web/framework/helpers/grids.py | 3 +- templates/grid_base_async.mako | 135 +++++++++++++++++++++------------ 3 files changed, 95 insertions(+), 61 deletions(-) diffs (253 lines): diff -r 3d0e1bdd6ce1 -r 052f6096e3cd lib/galaxy/web/controllers/history.py --- a/lib/galaxy/web/controllers/history.py Mon Nov 16 11:27:30 2009 -0500 +++ b/lib/galaxy/web/controllers/history.py Mon Nov 16 14:52:33 2009 -0500 @@ -87,7 +87,7 @@ # Grid definition title = "Saved Histories" model_class = model.History - template='/history/grid.mako' + template='/grid_base.mako' default_sort_key = "-create_time" columns = [ NameColumn( "Name", key="name", model_class=model.History, @@ -110,14 +110,14 @@ ) operations = [ - grids.GridOperation( "Switch", allow_multiple=False, condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Share", condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Unshare", condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Rename", condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), - grids.GridOperation( "Enable import via link", condition=( lambda item: item.deleted ) ), - grids.GridOperation( "Disable import via link", condition=( lambda item: item.deleted ) ) + grids.GridOperation( "Switch", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=True ), + grids.GridOperation( "Share", condition=( lambda item: not item.deleted ), async_compatible=False ), + grids.GridOperation( "Unshare", condition=( lambda item: not item.deleted ), async_compatible=False ), + grids.GridOperation( "Rename", condition=( lambda item: not item.deleted ), async_compatible=False ), + grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), async_compatible=True ), + grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ), async_compatible=True ), + grids.GridOperation( "Enable import via link", condition=( lambda item: item.deleted ), async_compatible=True ), + grids.GridOperation( "Disable import via link", condition=( lambda item: item.deleted ), async_compatible=True ) ] standard_filters = [ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ), diff -r 3d0e1bdd6ce1 -r 052f6096e3cd lib/galaxy/web/framework/helpers/grids.py --- a/lib/galaxy/web/framework/helpers/grids.py Mon Nov 16 11:27:30 2009 -0500 +++ b/lib/galaxy/web/framework/helpers/grids.py Mon Nov 16 14:52:33 2009 -0500 @@ -393,7 +393,7 @@ return query.filter( complete_filter ) class GridOperation( object ): - def __init__( self, label, key=None, condition=None, allow_multiple=True, allow_popup=True, target=None, url_args=None ): + def __init__( self, label, key=None, condition=None, allow_multiple=True, allow_popup=True, target=None, url_args=None, async_compatible=False ): self.label = label self.key = key self.allow_multiple = allow_multiple @@ -401,6 +401,7 @@ self.condition = condition self.target = target self.url_args = url_args + self.async_compatible = async_compatible def get_url_args( self, item ): if self.url_args: temp = dict( self.url_args ) diff -r 3d0e1bdd6ce1 -r 052f6096e3cd templates/grid_base_async.mako --- a/templates/grid_base_async.mako Mon Nov 16 11:27:30 2009 -0500 +++ b/templates/grid_base_async.mako Mon Nov 16 14:52:33 2009 -0500 @@ -33,6 +33,23 @@ $(document).ready(function() { // Initialize grid elements. init_grid_elements(); + + // Operations that are not async (AJAX) compatible. + var no_async_ops = new Object(); + %for operation in grid.operations: + %if not operation.async_compatible: + no_async_ops['${operation.label}'] = "True"; + %endif + %endfor + + // Initialize each operation button to do operation when clicked. + $('input[name=operation]:submit').each(function() { + $(this).click( function() { + var this_value = $(this).attr("value"); + var no_async = ( no_async_ops[this_value] != undefined && no_async_ops[this_value] != null); + do_operation(this_value, no_async); + }); + }); // Initialize autocomplete for text inputs in search UI. var t = $("#input-tags-filter"); @@ -227,13 +244,13 @@ } } - update_grid(true); + update_grid(); }); var container = $('#' + name + "-filtering-criteria"); container.append(t); - update_grid(true); + update_grid(); } // Set sort condition for grid. @@ -307,7 +324,7 @@ // Update grid. url_args["f-" + name] = new_value; - update_grid(true); + update_grid(); } var num_pages = ${num_pages}; @@ -354,11 +371,41 @@ { url_args['page'] = parseInt(new_page); } - update_grid(); + update_grid(true); + } + + // Perform a grid operation. TODO: this is not complete. + function do_operation(operation, no_async) + { + // For some reason, $('input[name=id]:checked').val() does not return all ids for checked boxes. + // The code below performs this function. + var item_ids = new Array() + $('input[name=id]:checked').each(function() { + item_ids[item_ids.length] = $(this).val(); + }); + + // Update URL args. + url_args['operation'] = operation; + url_args['id'] = item_ids; + + // If operation cannot be performed asynchronously, redirect to location. Otherwise do operation. + if (no_async) + { + var arg_str = ""; + var arg; + + for (arg in url_args) + arg_str = arg_str + arg + "=" + url_args[arg] + "&"; + + self.location = encodeURI( "${h.url_for()}?" + arg_str ); + } + else + update_grid(); + } // Update grid. - function update_grid() + function update_grid(maintain_page_links) { $.ajax({ url: "${h.url_for()}", @@ -381,61 +428,47 @@ var num_pages = parseInt( parsed_response_text[1] ); // Rebuild page links. - var page_link_container = $('#page-link-container'); - page_link_container.children().remove(); - if (num_pages > 1) + if (!maintain_page_links) { - // Show page link row. - $('#page-links-row').show(); + var page_link_container = $('#page-link-container'); + page_link_container.children().remove(); + if (num_pages > 1) + { + // Show page link row. + $('#page-links-row').show(); - // First page is the current page. - var t = $("<span>1</span>"); - t.addClass('page-link'); - t.addClass('inactive-link'); - t.attr('id', 'page-link-1'); - page_link_container.append(t); + // First page is the current page. + var t = $("<span>1</span>"); + t.addClass('page-link'); + t.addClass('inactive-link'); + t.attr('id', 'page-link-1'); + page_link_container.append(t); - // Subsequent pages are navigable. - for (var i = 2; i <= num_pages; i++) + // Subsequent pages are navigable. + for (var i = 2; i <= num_pages; i++) + { + var span = $("<span></span>"); + span.addClass('page-link'); + span.attr('id', 'page-link-' + i); + var t = $("<a href='#'>" + i + "</a>"); + var page_num = i + t.click(function() { + set_page(page_num); + }); + span.append(t) + page_link_container.append(span); + } + } + else { - var span = $("<span></span>"); - span.addClass('page-link'); - span.attr('id', 'page-link-' + i); - var t = $("<a href='#'>" + i + "</a>"); - var page_num = i - t.click(function() { - set_page(page_num); - }); - span.append(t) - page_link_container.append(span); + // Hide page link row. + $('#page-links-row').hide('slow'); } - } - else - { - // Hide page link row. - $('#page-links-row').hide('slow'); } } }); } - // Perform a grid operation. TODO: this is not complete. - function do_operation() - { - // Get grid form. - var form = $('#grid-form'); - var operation = $('input[name=operation]:submit').val(); - var item_ids = $('input[name=id]:checked').val(); - - // Update URL args. - url_args['operation'] = operation; - url_args['id'] = item_ids; - - //update_grid(); - - //document.location = ${h.url_for()} + "?" - } - </script> </%def> @@ -491,7 +524,7 @@ ## Print grid. <%def name="render_grid_table()"> - <form action="${url()}" method="post" onsubmit="do_operation();return false;"> + <form action="${url()}" method="post" onsubmit="return false;"> <table class="grid"> <thead id="grid-table-header"> <tr>