Refactoring and bug fixes for grid templates.

This commit is contained in:
Jeremy Goecks
2009-11-09 14:07:16 -05:00
parent 907d90dc43
commit 06c4ab7e05
6 changed files with 409 additions and 663 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ class HistoryDatasetAssociationListGrid( grids.Grid ):
grids.MulticolFilterColumn(
"Search",
cols_to_filter=[ columns[0], columns[2] ],
key="free-text-search", visible=False, filterable="default" )
key="free-text-search", visible=False, filterable="standard" )
)
operations = []
standard_filters = []
+3 -3
View File
@@ -16,7 +16,7 @@ class Grid( object ):
title = ""
exposed = True
model_class = None
template = "grid.mako"
template = "grid_base.mako"
global_actions = []
columns = []
operations = []
@@ -99,9 +99,9 @@ class Grid( object ):
if isinstance( decoded_item, list):
decoded_list = from_json_string_recurse( decoded_item )
else:
decoded_list = [ str( decoded_item ) ]
decoded_list = [ unicode( decoded_item ) ]
except ValueError:
decoded_list = [ str( item ) ]
decoded_list = [ unicode ( item ) ]
elif isinstance( item, list):
return_val = []
for element in item:
+1 -298
View File
@@ -1,298 +1 @@
<%! from galaxy.web.framework.helpers.grids import GridColumnFilter %>
<%inherit file="/base.mako"/>
<%def name="title()">${grid.title}</%def>
%if message:
<p>
<div class="${message_type}message transient-message">${message}</div>
<div style="clear: both"></div>
</p>
%endif
<%def name="javascripts()">
${parent.javascripts()}
${h.js("jquery.autocomplete", "autocomplete_tagging" )}
<script type="text/javascript">
## TODO: generalize and move into galaxy.base.js
$(document).ready(function() {
$(".grid").each( function() {
var grid = this;
var checkboxes = $(this).find("input.grid-row-select-checkbox");
var update = $(this).find( "span.grid-selected-count" );
$(checkboxes).each( function() {
$(this).change( function() {
var n = $(checkboxes).filter("[checked]").size();
update.text( n );
});
})
});
// Set up autocomplete for tag filter input.
var t = $("#input-tag-filter");
t.keyup( function( e )
{
if ( e.keyCode == 27 )
{
// Escape key
$(this).trigger( "blur" );
} else if (
( e.keyCode == 13 ) || // Return Key
( e.keyCode == 188 ) || // Comma
( e.keyCode == 32 ) // Space
)
{
//
// Check input.
//
new_value = this.value;
// Do nothing if return key was used to autocomplete.
if (return_key_pressed_for_autocomplete == true)
{
return_key_pressed_for_autocomplete = false;
return false;
}
// Suppress space after a ":"
if ( new_value.indexOf(": ", new_value.length - 2) != -1)
{
this.value = new_value.substring(0, new_value.length-1);
return false;
}
// Remove trigger keys from input.
if ( (e.keyCode == 188) || (e.keyCode == 32) )
new_value = new_value.substring( 0 , new_value.length - 1 );
// Trim whitespace.
new_value = new_value.replace(/^\s+|\s+$/g,"");
// Too short?
if (new_value.length < 3)
return false;
//
// New tag OK.
//
}
});
// Add autocomplete to input.
var format_item_func = function(key, row_position, num_rows, value, search_term)
{
tag_name_and_value = value.split(":");
return (tag_name_and_value.length == 1 ? tag_name_and_value[0] :tag_name_and_value[1]);
//var array = new Array(key, value, row_position, num_rows,
//search_term ); return "\"" + array.join("*") + "\"";
}
var autocomplete_options =
{ selectFirst: false, formatItem : format_item_func, autoFill: false, highlight: false, mustMatch: true };
t.autocomplete("${h.url_for( controller='tag', action='tag_autocomplete_data', item_class='HistoryDatasetAssociation' )}", autocomplete_options);
return t;
});
## Can this be moved into base.mako?
%if refresh_frames:
%if 'masthead' in refresh_frames:
## Refresh masthead == user changes (backward compatibility)
if ( parent.user_changed ) {
%if trans.user:
parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
%else:
parent.user_changed( null, false );
%endif
}
%endif
%if 'history' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_history ) {
## If available, include HDA ids to seek to in history request.
<%
hda_id = None
if seek_hda_ids:
hda_id = str( seek_hda_ids[0] ) # Use only the first id.
print hda_id
%>
parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history', hda_id=hda_id )}";
if ( parent.force_right_panel ) {
parent.force_right_panel( 'show' );
}
}
%endif
%if 'tools' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_tools ) {
parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
if ( parent.force_left_panel ) {
parent.force_left_panel( 'show' );
}
}
%endif
%endif
//
// Add a tag to the current grid filter; this adds the tag to the filter and then issues a request to refresh the grid.
//
function add_tag_to_grid_filter(tag_name, tag_value)
{
// Use tag as a filter: replace TAGNAME with tag_name and issue query.
<%
url_args = {}
if "tags" in cur_filter_dict and cur_filter_dict["tags"] != "All":
url_args["f-tags"] = cur_filter_dict["tags"].encode("utf-8") + ", TAGNAME"
else:
url_args["f-tags"] = "TAGNAME"
%>
var url_base = "${url( url_args )}";
var url = url_base.replace("TAGNAME", tag_name);
self.location = url;
}
</script>
</%def>
<%def name="stylesheets()">
${h.css( "base", "autocomplete_tagging" )}
<style>
## Not generic to all grids -- move to base?
.count-box {
min-width: 1.1em;
padding: 5px;
border-width: 1px;
border-style: solid;
text-align: center;
display: inline-block;
}
</style>
</%def>
<%namespace file="../grid_common.mako" import="*" />
## Print grid header.
${render_grid_filters()}
## Print grid.
<form name="dataset_actions" action="${url()}" method="post" >
<table class="grid">
<thead>
<tr>
%for column in grid.columns:
%if column.visible:
<%
href = ""
extra = ""
if column.sortable:
if sort_key == column.key:
if sort_order == "asc":
href = url( sort=( "-" + column.key ) )
extra = "&darr;"
else:
href = url( sort=( column.key ) )
extra = "&uarr;"
else:
href = url( sort=column.key )
%>
<th\
%if column.ncells > 1:
colspan="${column.ncells}"
%endif
>
%if href:
<a href="${href}">${column.label}</a>
%else:
${column.label}
%endif
<span>${extra}</span>
</th>
%endif
%endfor
<th></th>
</tr>
</thead>
<tbody>
%for i, item in enumerate( query ):
<tr \
%if current_item == item:
class="current" \
%endif
>
## Data columns
%for column in grid.columns:
%if column.visible:
<%
# Link
link = column.get_link( trans, grid, item )
if link:
href = url( **link )
else:
href = None
# Value (coerced to list so we can loop)
value = column.get_value( trans, grid, item )
if column.ncells == 1:
value = [ value ]
%>
%for cellnum, v in enumerate( value ):
<%
if isinstance(v, str):
v = unicode(v, 'utf-8')
# Attach popup menu?
if column.attach_popup and cellnum == 0:
extra = '<a id="grid-%d-popup" class="arrow" style="display: none;"><span>&#9660;</span></a>' % i
else:
extra = ""
%>
%if href:
<td><div class="menubutton split" style="float: left;"><a class="label" href="${href}">${v}${extra}</a> </td>
%else:
<td >${v}${extra}</td>
%endif
%endfor
%endif
%endfor
## Actions column
<td>
<div popupmenu="grid-${i}-popup">
%for operation in grid.operations:
%if operation.allowed( item ):
<a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
%endif
%endfor
</div>
</td>
</tr>
%endfor
</tbody>
<tfoot>
%if num_pages > 1:
<tr>
<td></td>
<td colspan="100" style="text-align: right">
Page:
%for page_index in range(1, num_pages + 1):
%if page_index == cur_page_num:
<span style="font-style: italic">${page_index}</span>
%else:
<% args = { "page" : page_index } %>
<span><a href="${url( args )}">${page_index}</a></span>
%endif
%endfor
</td>
</tr>
%endif
%if grid.operations:
<tr>
<td></td>
<td colspan="100">
For <span class="grid-selected-count"></span> selected histories:
%for operation in grid.operations:
%if operation.allow_multiple:
<input type="submit" name="operation" value="${operation.label}" class="action-button">
%endif
%endfor
</td>
</tr>
%endif
</tfoot>
</table>
</form>
<%inherit file="/grid_base.mako"/>
+358
View File
@@ -0,0 +1,358 @@
<%!
from galaxy.model import History, HistoryDatasetAssociation
def inherit(context):
if context.get('use_panels'):
return '/base_panels.mako'
else:
return '/base.mako'
%>
<%inherit file="${inherit(context)}"/>
## Render the grid's basic elements. Each of these elements can be subclassed.
%if message:
<p>
<div class="${message_type}message transient-message">${message}</div>
<div style="clear: both"></div>
</p>
%endif
${self.grid_header()}
${self.grid_table()}
## Function definitions.
<%def name="title()">${grid.title}</%def>
<%def name="javascripts()">
${parent.javascripts()}
${h.js("jquery.autocomplete", "autocomplete_tagging" )}
<script type="text/javascript">
## TODO: generalize and move into galaxy.base.js
$(document).ready(function() {
// Initialize grid elements.
$(".grid").each( function() {
var grid = this;
var checkboxes = $(this).find("input.grid-row-select-checkbox");
var update = $(this).find( "span.grid-selected-count" );
$(checkboxes).each( function() {
$(this).change( function() {
var n = $(checkboxes).filter("[checked]").size();
update.text( n );
});
})
});
// Initialize autocomplete for text inputs in search UI.
var t = $("#input-tags-filter");
if (t.length)
{
var autocomplete_options =
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false };
t.autocomplete("${h.url_for( controller='tag', action='tag_autocomplete_data', item_class='History' )}", autocomplete_options);
}
var t2 = $("#input-name-filter");
if (t2.length)
{
var autocomplete_options =
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false };
t2.autocomplete("${h.url_for( controller='history', action='name_autocomplete_data' )}", autocomplete_options);
}
});
## Can this be moved into base.mako?
%if refresh_frames:
%if 'masthead' in refresh_frames:
## Refresh masthead == user changes (backward compatibility)
if ( parent.user_changed ) {
%if trans.user:
parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
%else:
parent.user_changed( null, false );
%endif
}
%endif
%if 'history' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_history ) {
parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
if ( parent.force_right_panel ) {
parent.force_right_panel( 'show' );
}
}
%endif
%if 'tools' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_tools ) {
parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
if ( parent.force_left_panel ) {
parent.force_left_panel( 'show' );
}
}
%endif
%endif
// Filter and sort args for grid.
var filter_args = ${h.to_json_string(cur_filter_dict)};
var sort_key = "${sort_key}";
//
// Add tag to grid filter.
//
function add_tag_to_grid_filter(tag_name, tag_value)
{
// Put tag name and value together.
var tag = tag_name + (tag_value != null && tag_value != "" ? ":" + tag_value : "");
add_condition_to_grid_filter("tags", tag, true);
}
//
// Add a filter to the current grid filter; this adds the filter and then issues a request to refresh the grid.
//
function add_condition_to_grid_filter(name, value, append)
{
// Update filter arg with new condition.
if (append)
{
// Append value.
var cur_val = filter_args[name];
if (cur_val != "All")
cur_val = cur_val + ", " + value;
else
cur_val = value;
filter_args[name] = cur_val;
}
else
{
// Replace value.
filter_args[name] = value;
}
// Build URL with filter args, sort key.
var filter_arg_value_strs = new Array();
var i = 0;
for (arg in filter_args)
{
filter_arg_value_strs[i++] = "f-" + arg + "=" + filter_args[arg];
}
var filter_str = filter_arg_value_strs.join("&");
var url_base = "${h.url_for( action='list')}";
var url = url_base + "?" + filter_str + "&sort=" + sort_key;
self.location = url;
}
//
// Initiate navigation when user selects a page to view.
//
function navigate_to_page(page_select)
{
page_num = $(page_select).val();
<% url_args = {"page" : "PAGE"} %>
var url_base = "${url( url_args )}";
var url = url_base.replace("PAGE", page_num);
self.location = url;
}
</script>
</%def>
<%def name="stylesheets()">
${h.css( "base", "autocomplete_tagging" )}
<style>
## Not generic to all grids -- move to base?
.count-box {
min-width: 1.1em;
padding: 5px;
border-width: 1px;
border-style: solid;
text-align: center;
display: inline-block;
}
</style>
</%def>
<%namespace file="./grid_common.mako" import="*" />
## Print grid header.
<%def name="grid_header()">
<div class="grid-header">
<h2>${grid.title}</h2>
%if grid.global_actions:
<ul class="manage-table-actions">
%for action in grid.global_actions:
<li>
<a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a>
</li>
%endfor
</ul>
%endif
${render_grid_filters()}
</div>
</%def>
## Print grid.
<%def name="grid_table()">
<form action="${url()}" method="post" >
<table class="grid">
<thead>
<tr>
<th></th>
%for column in grid.columns:
%if column.visible:
<%
href = ""
extra = ""
if column.sortable:
if sort_key == column.key:
if sort_order == "asc":
href = url( sort=( "-" + column.key ) )
extra = "&darr;"
else:
href = url( sort=( column.key ) )
extra = "&uarr;"
else:
href = url( sort=column.key )
%>
<th\
%if column.ncells > 1:
colspan="${column.ncells}"
%endif
>
%if href:
<a href="${href}">${column.label}</a>
%else:
${column.label}
%endif
<span>${extra}</span>
</th>
%endif
%endfor
<th></th>
</tr>
</thead>
<tbody>
%for i, item in enumerate( query ):
<tr \
%if current_item == item:
class="current" \
%endif
>
## Item selection column
<td style="width: 1.5em;">
<input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
</td>
## Data columns
%for column in grid.columns:
%if column.visible:
<%
# Link
link = column.get_link( trans, grid, item )
if link:
href = url( **link )
else:
href = None
# Value (coerced to list so we can loop)
value = column.get_value( trans, grid, item )
if column.ncells == 1:
value = [ value ]
%>
%for cellnum, v in enumerate( value ):
<%
# Handle non-ascii chars.
if isinstance(v, str):
v = unicode(v, 'utf-8')
# Attach popup menu?
if column.attach_popup and cellnum == 0:
extra = '<a id="grid-%d-popup" class="arrow" style="display: none;"><span>&#9660;</span></a>' % i
else:
extra = ""
%>
%if href:
<td><div class="menubutton split" style="float: left;"><a class="label" href="${href}">${v}</a>${extra}</td>
%else:
<td >${v}${extra}</td>
%endif
%endfor
%endif
%endfor
## Actions column
<td>
<div popupmenu="grid-${i}-popup">
%for operation in grid.operations:
%if operation.allowed( item ):
<%
target = ""
if operation.target:
target = "target='" + operation.target + "'"
%>
<a class="action-button" ${target} href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
%endif
%endfor
</div>
</td>
</tr>
%endfor
</tbody>
<tfoot>
## Row for navigating among pages.
%if num_pages > 1:
<tr>
<td></td>
<td colspan="100">
Page ${cur_page_num} of ${num_pages}
&nbsp;&nbsp;&nbsp;&nbsp;Go to:
## Next page link.
%if cur_page_num != num_pages:
<% args = { "page" : cur_page_num+1 } %>
<span><a href="${url( args )}">Next</a></span>
%endif
## Previous page link.
%if cur_page_num != 1:
<span>|</span>
<% args = { "page" : cur_page_num-1 } %>
<span><a href="${url( args )}">Previous</a></span>
%endif
## Go to page select box.
<span>| Select:</span>
<select id="page-select" onchange="navigate_to_page(this)">
<option value=""></option>
%for page_index in range(1, num_pages + 1):
%if page_index == cur_page_num:
continue
%else:
<% args = { "page" : page_index } %>
<option value='${page_index}'>Page ${page_index}</option>
%endif
%endfor
</select>
## Show all link.
<% args = { "page" : "all" } %>
<span>| <a href="${url( args )}">Show all histories on one page</a></span>
</td>
</tr>
%endif
<tr>
## Grid operations.
<td></td>
<td colspan="100">
<%
# Mapping between item class and plural term for item.
plural = "items"
if grid.model_class == History:
plural = "histories"
elif grid.model_class == HistoryDatasetAssociation:
plural = "datasets"
%>
For <span class="grid-selected-count"></span> selected ${plural}:
%for operation in grid.operations:
%if operation.allow_multiple:
<input type="submit" name="operation" value="${operation.label}" class="action-button">
%endif
%endfor
</td>
</tr>
</tfoot>
</table>
</form>
</%def>
+45 -50
View File
@@ -73,57 +73,52 @@
## Print grid search/filtering UI.
<%def name="render_grid_filters()">
<div class="grid-header">
<h2>${grid.title}</h2>
## Default search.
<div>
<table><tr>
<td>
<table>
%for column in grid.columns:
%if column.filterable == "default":
${render_grid_column_filter(column)}
%endif
%endfor
</table>
</td>
<td>
##|
##<% filter_all = GridColumnFilter( "", { column.key : "All" } ) %>
##<a href="${url( filter_all.get_url_args() )}">Clear All</a>
| <a href="" onclick="javascript:$('#more-search-options').slideToggle('fast');return false;">Advanced Search</a>
</td>
</tr></table>
</div>
## Advanced search.
<div id="more-search-options" style="display: none; padding-top: 5px">
<table style="border: 1px solid gray;">
<tr><td style="text-align: left" colspan="100">
Advanced Search |
<a href=""# onclick="javascript:$('#more-search-options').slideToggle('fast');return false;">Close</a> |
## Link to clear all filters.
<%
no_filter = GridColumnFilter("Clear All", default_filter_dict)
%>
<a href="${url( no_filter.get_url_args() )}">${no_filter.label}</a>
</td></tr>
%for column in grid.columns:
%if column.filterable == "advanced":
## Show div if current filter has value that is different from the default filter.
%if column.key in cur_filter_dict and column.key in default_filter_dict and \
cur_filter_dict[column.key] != default_filter_dict[column.key]:
<script type="text/javascript">
$('#more-search-options').css("display", "block");
</script>
%endif
${render_grid_column_filter(column)}
## Standard search.
<div>
<table><tr>
<td>
<table>
%for column in grid.columns:
%if column.filterable == "standard":
${render_grid_column_filter(column)}
%endif
%endfor
</table>
</div>
</table>
</td>
<td>
##|
##<% filter_all = GridColumnFilter( "", { column.key : "All" } ) %>
##<a href="${url( filter_all.get_url_args() )}">Clear All</a>
| <a href="" onclick="javascript:$('#more-search-options').slideToggle('fast');return false;">Advanced Search</a>
</td>
</tr></table>
</div>
## Advanced search.
<div id="more-search-options" style="display: none; padding-top: 5px">
<table style="border: 1px solid gray;">
<tr><td style="text-align: left" colspan="100">
Advanced Search |
<a href=""# onclick="javascript:$('#more-search-options').slideToggle('fast');return false;">Close</a> |
## Link to clear all filters.
<%
no_filter = GridColumnFilter("Clear All", default_filter_dict)
%>
<a href="${url( no_filter.get_url_args() )}">${no_filter.label}</a>
</td></tr>
%for column in grid.columns:
%if column.filterable == "advanced":
## Show div if current filter has value that is different from the default filter.
%if column.key in cur_filter_dict and column.key in default_filter_dict and \
cur_filter_dict[column.key] != default_filter_dict[column.key]:
<script type="text/javascript">
$('#more-search-options').css("display", "block");
</script>
%endif
${render_grid_column_filter(column)}
%endif
%endfor
</table>
</div>
</%def>
+1 -311
View File
@@ -1,311 +1 @@
<%! from galaxy.web.framework.helpers.grids import TextColumn, GridColumnFilter %>
<%inherit file="/base.mako"/>
<%def name="title()">${grid.title}</%def>
%if message:
<p>
<div class="${message_type}message transient-message">${message}</div>
<div style="clear: both"></div>
</p>
%endif
<%def name="javascripts()">
${parent.javascripts()}
${h.js("jquery.autocomplete", "autocomplete_tagging" )}
<script type="text/javascript">
## TODO: generalize and move into galaxy.base.js
$(document).ready(function() {
$(".grid").each( function() {
var grid = this;
var checkboxes = $(this).find("input.grid-row-select-checkbox");
var update = $(this).find( "span.grid-selected-count" );
$(checkboxes).each( function() {
$(this).change( function() {
var n = $(checkboxes).filter("[checked]").size();
update.text( n );
});
})
});
// Set up autocomplete for tag filter input.
var t = $("#input-tags-filter");
var autocomplete_options =
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false };
t.autocomplete("${h.url_for( controller='tag', action='tag_autocomplete_data', item_class='History' )}", autocomplete_options);
// Set up autocomplete for name filter input.
var t2 = $("#input-name-filter");
var autocomplete_options =
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false };
t2.autocomplete("${h.url_for( controller='history', action='name_autocomplete_data' )}", autocomplete_options);
});
## Can this be moved into base.mako?
%if refresh_frames:
%if 'masthead' in refresh_frames:
## Refresh masthead == user changes (backward compatibility)
if ( parent.user_changed ) {
%if trans.user:
parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
%else:
parent.user_changed( null, false );
%endif
}
%endif
%if 'history' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_history ) {
parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
if ( parent.force_right_panel ) {
parent.force_right_panel( 'show' );
}
}
%endif
%if 'tools' in refresh_frames:
if ( parent.frames && parent.frames.galaxy_tools ) {
parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
if ( parent.force_left_panel ) {
parent.force_left_panel( 'show' );
}
}
%endif
%endif
// Filter and sort args for grid.
var filter_args = ${h.to_json_string(cur_filter_dict)};
var sort_key = "${sort_key}";
//
// Add tag to grid filter.
//
function add_tag_to_grid_filter(tag_name, tag_value)
{
// Put tag name and value together.
var tag = tag_name + (tag_value != null && tag_value != "" ? ":" + tag_value : "");
add_condition_to_grid_filter("tags", tag, true);
}
//
// Add a filter to the current grid filter; this adds the filter and then issues a request to refresh the grid.
//
function add_condition_to_grid_filter(name, value, append)
{
// Update filter arg with new condition.
if (append)
{
// Append value.
var cur_val = filter_args[name];
if (cur_val != "All")
cur_val = cur_val + ", " + value;
else
cur_val = value;
filter_args[name] = cur_val;
}
else
{
// Replace value.
filter_args[name] = value;
}
// Build URL with filter args, sort key.
var filter_arg_value_strs = new Array();
var i = 0;
for (arg in filter_args)
{
filter_arg_value_strs[i++] = "f-" + arg + "=" + filter_args[arg];
}
var filter_str = filter_arg_value_strs.join("&");
var url_base = "${h.url_for( controller='history', action='list')}";
var url = url_base + "?" + filter_str + "&sort=" + sort_key;
self.location = url;
}
//
// Initiate navigation when user selects a page to view.
//
function navigate_to_page(page_select)
{
page_num = $(page_select).val();
<% url_args = {"page" : "PAGE"} %>
var url_base = "${url( url_args )}";
var url = url_base.replace("PAGE", page_num);
self.location = url;
}
</script>
</%def>
<%def name="stylesheets()">
${h.css( "base", "autocomplete_tagging" )}
<style>
## Not generic to all grids -- move to base?
.count-box {
min-width: 1.1em;
padding: 5px;
border-width: 1px;
border-style: solid;
text-align: center;
display: inline-block;
}
</style>
</%def>
<%namespace file="../grid_common.mako" import="*" />
## Print grid header.
${render_grid_filters()}
## Print grid.
<form name="history_actions" action="${url()}" method="post" >
<input type="hidden" name="page" value="${cur_page_num}">
<table class="grid">
<thead>
<tr>
<th></th>
%for column in grid.columns:
%if column.visible:
<%
href = ""
extra = ""
if column.sortable:
if sort_key == column.key:
if sort_order == "asc":
href = url( sort=( "-" + column.key ) )
extra = "&darr;"
else:
href = url( sort=( column.key ) )
extra = "&uarr;"
else:
href = url( sort=column.key )
%>
<th\
%if column.ncells > 1:
colspan="${column.ncells}"
%endif
>
%if href:
<a href="${href}">${column.label}</a>
%else:
${column.label}
%endif
<span>${extra}</span>
</th>
%endif
%endfor
<th></th>
</tr>
</thead>
<tbody>
%for i, item in enumerate( query ):
<tr \
%if current_item == item:
class="current" \
%endif
>
## Item selection column
<td style="width: 1.5em;">
<input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
</td>
## Data columns
%for column in grid.columns:
%if column.visible:
<%
# Link
link = column.get_link( trans, grid, item )
if link:
href = url( **link )
else:
href = None
# Value (coerced to list so we can loop)
value = column.get_value( trans, grid, item )
if column.ncells == 1:
value = [ value ]
%>
%for cellnum, v in enumerate( value ):
<%
# Attach popup menu?
if column.attach_popup and cellnum == 0:
extra = '<a id="grid-%d-popup" class="arrow" style="display: none;"><span>&#9660;</span></a>' % i
else:
extra = ""
%>
%if href:
<td><div class="menubutton split" style="float: left;"><a class="label" href="${href}">${v}</a>${extra}</td>
%else:
<td >${v}${extra}</td>
%endif
%endfor
%endif
%endfor
## Actions column
<td>
<div popupmenu="grid-${i}-popup">
%for operation in grid.operations:
%if operation.allowed( item ):
<a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
%endif
%endfor
</div>
</td>
</tr>
%endfor
</tbody>
<tfoot>
## Row for navigating among pages.
%if num_pages > 1:
<tr>
<td></td>
<td colspan="100">
Page ${cur_page_num} of ${num_pages}
&nbsp;&nbsp;&nbsp;&nbsp;Go to:
## Next page link.
%if cur_page_num != num_pages:
<% args = { "page" : cur_page_num+1 } %>
<span><a href="${url( args )}">Next</a></span>
%endif
## Previous page link.
%if cur_page_num != 1:
<span>|</span>
<% args = { "page" : cur_page_num-1 } %>
<span><a href="${url( args )}">Previous</a></span>
%endif
## Go to page select box.
<span>| Select:</span>
<select id="page-select" onchange="navigate_to_page(this)">
<option value=""></option>
%for page_index in range(1, num_pages + 1):
%if page_index == cur_page_num:
continue
%else:
<% args = { "page" : page_index } %>
<option value='${page_index}'>Page ${page_index}</option>
%endif
%endfor
</select>
## Show all link.
<% args = { "page" : "all" } %>
<span>| <a href="${url( args )}">Show all histories on one page</a></span>
</td>
</tr>
%endif
%if grid.operations:
<tr>
<td></td>
<td colspan="100">
For <span class="grid-selected-count"></span> selected histories:
%for operation in grid.operations:
%if operation.allow_multiple:
<input type="submit" name="operation" value="${operation.label}" class="action-button">
%endif
%endfor
</td>
</tr>
%endif
</tfoot>
</table>
</form>
<%inherit file="/grid_base.mako"/>