1 new changeset in galaxy-central: http://bitbucket.org/galaxy/galaxy-central/changeset/8553b02ce9ee/ changeset: 8553b02ce9ee user: kanwei date: 2011-07-19 03:56:23 summary: Tools: Add new LibraryDataset tool parameter to expose LDDAs to tools. Use trackster's modal popup interface for item selection. Add new InputWrapper that exposes LDDA templates as well. Refactor tool_form.mako to use base_panels.mako instead of its own custom HTML. affected #: 9 files (4.1 KB) --- a/lib/galaxy/tools/__init__.py Mon Jul 18 15:02:37 2011 -0400 +++ b/lib/galaxy/tools/__init__.py Mon Jul 18 21:56:23 2011 -0400 @@ -1463,6 +1463,11 @@ elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], self.app, other_values = param_dict ) + + elif isinstance( input, LibraryDatasetToolParameter ): + input_values[ input.name ] = LibraryDatasetValueWrapper( + input, input_values[ input.name ], param_dict ) + else: input_values[ input.name ] = InputValueWrapper( input, input_values[ input.name ], param_dict ) @@ -2013,6 +2018,31 @@ def __getattr__( self, key ): return getattr( self.obj, key ) +class LibraryDatasetValueWrapper( object ): + """ + Wraps an input so that __str__ gives the "param_dict" representation. + """ + def __init__( self, input, value, other_values={} ): + self.input = input + self.value = value + self._other_values = other_values + def __str__( self ): + return self.value.name + def templates( self ): + if not self.value: + return None + template_data = {} + for temp_info in self.value.info_association: + template = temp_info.template + content = temp_info.info.content + tmp_dict = {} + for field in template.fields: + tmp_dict[field['label']] = content[field['name']] + template_data[template.name] = tmp_dict + return template_data + def __getattr__( self, key ): + return getattr( self.value, key ) + class InputValueWrapper( object ): """ Wraps an input so that __str__ gives the "param_dict" representation. --- a/lib/galaxy/tools/parameters/basic.py Mon Jul 18 15:02:37 2011 -0400 +++ b/lib/galaxy/tools/parameters/basic.py Mon Jul 18 21:56:23 2011 -0400 @@ -1272,7 +1272,7 @@ displayed as radio buttons and multiple selects as a set of checkboxes TODO: The following must be fixed to test correctly for the new security_check tag in the DataToolParameter ( the last test below is broken ) - Nate's next passs at the dataset security stuff will dramatically alter this anyway. + Nate's next pass at the dataset security stuff will dramatically alter this anyway. """ def __init__( self, tool, elem ): @@ -1522,6 +1522,38 @@ ref = ref() return ref +class LibraryDatasetToolParameter( ToolParameter ): + """ + Parameter that lets users select a LDDA from a modal window, then use it within the wrapper. + """ + + def __init__( self, tool, elem ): + ToolParameter.__init__( self, tool, elem ) + + def get_html_field( self, trans=None, value=None, other_values={} ): + return form_builder.LibraryField( self.name, value=value, trans=trans ) + + def get_initial_value( self, trans, context ): + return None + + def from_html( self, value, trans, other_values={} ): + if not value: + return None + elif isinstance( value, trans.app.model.LibraryDatasetDatasetAssociation ): + return value + else: + return trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( value ) ) + + def to_string( self, value, app ): + if not value: + return None + return value.id + + def to_python( self, value, app ): + if not value: + return value + return app.model.context.query( app.model.LibraryDatasetDatasetAssociation ).get( value ) + # class RawToolParameter( ToolParameter ): # """ # Completely nondescript parameter, HTML representation is provided as text @@ -1570,19 +1602,20 @@ # self.html = form_builder.HiddenField( self.name, trans.history.id ).get_html() # return self.html -parameter_types = dict( text = TextToolParameter, - integer = IntegerToolParameter, - float = FloatToolParameter, - boolean = BooleanToolParameter, - genomebuild = GenomeBuildParameter, - select = SelectToolParameter, - data_column = ColumnListParameter, - hidden = HiddenToolParameter, - baseurl = BaseURLToolParameter, - file = FileToolParameter, - ftpfile = FTPFileToolParameter, - data = DataToolParameter, - drill_down = DrillDownSelectToolParameter ) +parameter_types = dict( text = TextToolParameter, + integer = IntegerToolParameter, + float = FloatToolParameter, + boolean = BooleanToolParameter, + genomebuild = GenomeBuildParameter, + select = SelectToolParameter, + data_column = ColumnListParameter, + hidden = HiddenToolParameter, + baseurl = BaseURLToolParameter, + file = FileToolParameter, + ftpfile = FTPFileToolParameter, + data = DataToolParameter, + library_data = LibraryDatasetToolParameter, + drill_down = DrillDownSelectToolParameter ) class UnvalidatedValue( object ): """ --- a/lib/galaxy/web/form_builder.py Mon Jul 18 15:02:37 2011 -0400 +++ b/lib/galaxy/web/form_builder.py Mon Jul 18 21:56:23 2011 -0400 @@ -652,6 +652,27 @@ return self.value else: return '-' + +class LibraryField( BaseField ): + def __init__( self, name, value=None, trans=None ): + self.name = name + self.ldda = value + self.trans = trans + def get_html( self, disabled=False ): + if not self.ldda: + ldda = "" + text = "Choose a library dataset" + else: + ldda = self.trans.security.encode_id(self.ldda.id) + text = self.ldda.name + return '<a href="javascript:void(0);" class="add-librarydataset">%s</a> \ + <input type="hidden" name="%s" value="%s">' % ( text, self.name, escape( str(ldda), quote=True ) ) + + def get_display_text(self): + if self.ldda: + return self.ldda.name + else: + return 'None' def get_suite(): """Get unittest suite for this module""" --- a/static/scripts/galaxy.base.js Mon Jul 18 15:02:37 2011 -0400 +++ b/static/scripts/galaxy.base.js Mon Jul 18 21:56:23 2011 -0400 @@ -725,4 +725,5 @@ } return anchor; }); + }); --- a/static/scripts/galaxy.panels.js Mon Jul 18 15:02:37 2011 -0400 +++ b/static/scripts/galaxy.panels.js Mon Jul 18 21:56:23 2011 -0400 @@ -214,7 +214,7 @@ init_fn(); } }; - + function show_in_overlay( options ) { var width = options.width || '600'; var height = options.height || '400'; @@ -226,9 +226,9 @@ show_modal( null, $( "<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='" + image_path + "/closebox.png'><iframe style='margin: 0; padding: 0;' src='" + options.url + "' width='" + width + "' height='" + height + "' scrolling='" + scroll + "' frameborder='0'></iframe></div>" ) ); $("#close_button").bind( "click", function() { hide_modal(); } ); } - + // Tab management - + $(function() { $(".tab").each( function() { var submenu = $(this).children( ".submenu" ); --- a/templates/base.mako Mon Jul 18 15:02:37 2011 -0400 +++ b/templates/base.mako Mon Jul 18 21:56:23 2011 -0400 @@ -1,15 +1,13 @@ <% _=n_ %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html> - -<head> -<title>${self.title()}</title> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -${self.metas()} -${self.stylesheets()} -${self.javascripts()} -</head> - + <head> + <title>${self.title()}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + ${self.metas()} + ${self.stylesheets()} + ${self.javascripts()} + </head><body> ${next.body()} </body> --- a/templates/base_panels.mako Mon Jul 18 15:02:37 2011 -0400 +++ b/templates/base_panels.mako Mon Jul 18 21:56:23 2011 -0400 @@ -155,13 +155,13 @@ ## Override </%def> -<%def name="overlay( title='', content='' )"> +<%def name="overlay( title='', content='', visible=False )"><%def name="title()"></%def><%def name="content()"></%def><div id="overlay" - %if not self.overlay_visible: - style="display: none;" + %if not visible: + style="display: none;" %endif > ## @@ -169,21 +169,21 @@ ## Need a table here for centering in IE6 <table class="dialog-box-container" border="0" cellpadding="0" cellspacing="0" - %if not self.overlay_visible: + %if not visible: style="display: none;" %endif ><tr><td><div class="dialog-box-wrapper"><div class="dialog-box"> - <div class="unified-panel-header"> - <div class="unified-panel-header-inner"><span class='title'>${title}</span></div> - </div> - <div class="body">${content}</div> - <div> - <div class="buttons" style="display: none; float: right;"></div> - <div class="extra_buttons" style="display: none; padding: 5px;"></div> - <div style="clear: both;"></div> - </div> + <div class="unified-panel-header"> + <div class="unified-panel-header-inner"><span class='title'>${title}</span></div> + </div> + <div class="body">${content}</div> + <div> + <div class="buttons" style="display: none; float: right;"></div> + <div class="extra_buttons" style="display: none; padding: 5px;"></div> + <div style="clear: both;"></div> + </div></div></div></td></tr></table> @@ -198,45 +198,45 @@ <html> ${self.init()} <head> - <title>${self.title()}</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name = "viewport" content = "maximum-scale=1.0"> - ${self.stylesheets()} - ${self.javascripts()} + <title>${self.title()}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name = "viewport" content = "maximum-scale=1.0"> + ${self.stylesheets()} + ${self.javascripts()} </head><body scroll="no" class="${self.body_class}"> - <div id="everything" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; min-width: 600px;"> - ## Background displays first - <div id="background"></div> - ## Layer iframes over backgrounds - <div id="masthead"> - ${self.masthead()} - </div> - <div id="messagebox" class="panel-${self.message_box_class}-message"> - %if self.message_box_visible: - ${self.message_box_content()} + <div id="everything" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; min-width: 600px;"> + ## Background displays first + <div id="background"></div> + ## Layer iframes over backgrounds + <div id="masthead"> + ${self.masthead()} + </div> + <div id="messagebox" class="panel-${self.message_box_class}-message"> + %if self.message_box_visible: + ${self.message_box_content()} + %endif + </div> + ${self.overlay(visible=self.overlay_visible)} + %if self.has_left_panel: + <div id="left"> + ${self.left_panel()} + </div> + <div id="left-border"> + <div id="left-border-inner" style="display: none;"></div> + </div> + %endif + <div id="center"> + ${self.center_panel()} + </div> + %if self.has_right_panel: + <div id="right-border"><div id="right-border-inner" style="display: none;"></div></div> + <div id="right"> + ${self.right_panel()} + </div> %endif </div> - ${self.overlay()} - %if self.has_left_panel: - <div id="left"> - ${self.left_panel()} - </div> - <div id="left-border"> - <div id="left-border-inner" style="display: none;"></div> - </div> - %endif - <div id="center"> - ${self.center_panel()} - </div> - %if self.has_right_panel: - <div id="right-border"><div id="right-border-inner" style="display: none;"></div></div> - <div id="right"> - ${self.right_panel()} - </div> - %endif - </div> ## Allow other body level elements </body> ## Scripts can be loaded later since they progressively add features to --- a/templates/root/index.mako Mon Jul 18 15:02:37 2011 -0400 +++ b/templates/root/index.mako Mon Jul 18 21:56:23 2011 -0400 @@ -174,14 +174,14 @@ <%def name="init()"><% - if trans.app.config.cloud_controller_instance: - self.has_left_panel=False - self.has_right_panel=False - self.active_view="cloud" - else: - self.has_left_panel=True - self.has_right_panel=True - self.active_view="analysis" + if trans.app.config.cloud_controller_instance: + self.has_left_panel=False + self.has_right_panel=False + self.active_view="cloud" + else: + self.has_left_panel=True + self.has_right_panel=True + self.active_view="analysis" %> %if trans.app.config.require_login and not trans.user: <script type="text/javascript"> @@ -219,7 +219,7 @@ elif m_c is not None: center_url = h.url_for( controller=m_c, action=m_a ) elif trans.app.config.cloud_controller_instance: - center_url = h.url_for( controller='cloud', action='list' ) + center_url = h.url_for( controller='cloud', action='list' ) else: center_url = h.url_for( '/static/welcome.html' ) %> --- a/templates/tool_form.mako Mon Jul 18 15:02:37 2011 -0400 +++ b/templates/tool_form.mako Mon Jul 18 21:56:23 2011 -0400 @@ -1,203 +1,230 @@ -<!-- --> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<%inherit file="/base.mako"/> +<%namespace file="/base_panels.mako" import="overlay" /> -<% -from galaxy.util.expressions import ExpressionContext -%> +<%def name="stylesheets()"> + ${h.css( "autocomplete_tagging", "panel_layout", "base", "library" )} +</%def> -<html> +<%def name="javascripts()"> + ${h.js( "jquery", "galaxy.panels", "galaxy.base", "jquery.autocomplete", "jstorage" )} + <script type="text/javascript"> + $(function() { + $(window).bind("refresh_on_change", function() { + $(':file').each( function() { + var file = $(this); + var file_value = file.val(); + if (file_value) { + // disable file input, since we don't want to upload the file on refresh + var file_name = $(this).attr("name"); + file.attr( { name: 'replaced_file_input_' + file_name, disabled: true } ); + // create a new hidden field which stores the filename and has the original name of the file input + var new_file_input = $(document.createElement('input')); + new_file_input.attr( { "type": "hidden", "value": file_value, "name": file_name } ); + file.after(new_file_input); + } + }); + }); -<head> -<title>Galaxy</title> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -${h.css( "base", "autocomplete_tagging" )} -${h.js( "jquery", "galaxy.base", "jquery.autocomplete" )} -<script type="text/javascript"> -$(function() { - $(window).bind("refresh_on_change", function() { - $(':file').each( function() { - var file = $(this); - var file_value = file.val(); - if (file_value) { - // disable file input, since we don't want to upload the file on refresh - var file_name = $(this).attr("name"); - file.attr( { name: 'replaced_file_input_' + file_name, disabled: true } ); - // create a new hidden field which stores the filename and has the original name of the file input - var new_file_input = $(document.createElement('input')); - new_file_input.attr( { "type": "hidden", "value": file_value, "name": file_name } ); - file.after(new_file_input); + // For drilldown parameters: add expand/collapse buttons and collapse initially-collapsed elements + $( 'li ul.toolParameterExpandableCollapsable' ).each( function() { + var el = $(this), + parent_li = el.parent('li'), + sub_ul = el.remove(); + + parent_li.find( 'span' ).wrapInner( '<a/>' ).find( 'a' ).click( function() { + sub_ul.toggle(); + (this).html( sub_ul.is(":hidden") ? '[+]' : '[-]' ); + }); + parent_li.append( sub_ul ); + }); + + $( 'ul ul.toolParameterExpandableCollapsable' ).each( function(i) { + var el = $(this); + if (el.attr("default_state") === "collapsed") { + el.hide(); } }); + + function checkUncheckAll( name, check ) { + $("input[name='" + name + "'][type='checkbox']").attr('checked', !!check); + } + + // Inserts the Select All / Unselect All buttons for checkboxes + $("div.checkUncheckAllPlaceholder").each( function() { + var check_name = $(this).attr("checkbox_name"); + select_link = $("<a class='action-button'></a>").text("Select All").click(function() { + checkUncheckAll(check_name, true); + }); + unselect_link = $("<a class='action-button'></a>").text("Unselect All").click(function() { + checkUncheckAll(check_name, false); + }); + $(this).append(select_link).append(" ").append(unselect_link); + }); + + $(".add-librarydataset").live("click", function() { + var link = $(this); + $.ajax({ + url: "/tracks/list_libraries", + error: function(xhr, ajaxOptions, thrownError) { alert( "Grid failed" ); console.log(xhr, ajaxOptions, thrownError); }, + success: function(table_html) { + show_modal( + "Select Library Dataset", + table_html, { + "Cancel": function() { + hide_modal(); + }, + "Select": function() { + $('input[name=ldda_ids]:checked').each(function() { + var name = $.trim( $(this).siblings("div").find("a").text() ); + var id = $(this).val(); + link.text(name); + link.siblings("input[type=hidden]").val(id); + }); + hide_modal(); + } + } + ); + } + }); + }); }); - - // For drilldown parameters: add expand/collapse buttons and collapse initially-collapsed elements - $( 'li ul.toolParameterExpandableCollapsable' ).each( function() { - var el = $(this), - parent_li = el.parent('li'), - sub_ul = el.remove(); - - parent_li.find( 'span' ).wrapInner( '<a/>' ).find( 'a' ).click( function() { - sub_ul.toggle(); - (this).html( sub_ul.is(":hidden") ? '[+]' : '[-]' ); - }); - parent_li.append( sub_ul ); - }); - - $( 'ul ul.toolParameterExpandableCollapsable' ).each( function(i) { - var el = $(this); - if (el.attr("default_state") === "collapsed") { - el.hide(); + + %if not add_frame.debug: + if( window.name != "galaxy_main" ) { + location.replace( '${h.url_for( controller='root', action='index', tool_id=tool.id )}' ); } - }); - - function checkUncheckAll( name, check ) { - $("input[name='" + name + "'][type='checkbox']").attr('checked', !!check); - } - - // Inserts the Select All / Unselect All buttons for checkboxes - $("div.checkUncheckAllPlaceholder").each( function() { - var check_name = $(this).attr("checkbox_name"); - select_link = $("<a class='action-button'></a>").text("Select All").click(function() { - checkUncheckAll(check_name, true); - }); - unselect_link = $("<a class='action-button'></a>").text("Unselect All").click(function() { - checkUncheckAll(check_name, false); - }); - $(this).append(select_link).append(" ").append(unselect_link); - }); -}); + %endif -%if not add_frame.debug: - if( window.name != "galaxy_main" ) { - location.replace( '${h.url_for( controller='root', action='index', tool_id=tool.id )}' ); - } -%endif + </script> -</script> -</head> +</%def> -<body> - <%def name="do_inputs( inputs, tool_state, errors, prefix, other_values=None )"> - <% other_values = ExpressionContext( tool_state, other_values ) %> - %for input_index, input in enumerate( inputs.itervalues() ): - %if not input.visible: - <% pass %> - %elif input.type == "repeat": - <div class="repeat-group"> - <div class="form-title-row"><b>${input.title_plural}</b></div> - <% repeat_state = tool_state[input.name] %> - %for i in range( len( repeat_state ) ): - <div class="repeat-group-item"> - <% - if input.name in errors: - rep_errors = errors[input.name][i] - else: - rep_errors = dict() - index = repeat_state[i]['__index__'] - %> - <div class="form-title-row"><b>${input.title} ${i + 1}</b></div> - ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )} - <div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div> - </div> - %if rep_errors.has_key( '__index__' ): - <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${rep_errors['__index__']}</span></div> - %endif - %endfor - <div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div> - </div> - %elif input.type == "conditional": - <% - group_state = tool_state[input.name] - group_errors = errors.get( input.name, {} ) - current_case = group_state['__current_case__'] - group_prefix = prefix + input.name + "|" - %> - %if input.value_ref_in_group: - ${row_for_param( group_prefix, input.test_param, group_state, group_errors, other_values )} - %endif - ${do_inputs( input.cases[current_case].inputs, group_state, group_errors, group_prefix, other_values )} - %elif input.type == "upload_dataset": - %if input.get_datatype( trans, other_values ).composite_type is None: #have non-composite upload appear as before +<%def name="do_inputs( inputs, tool_state, errors, prefix, other_values=None )"> + <% + from galaxy.util.expressions import ExpressionContext + other_values = ExpressionContext( tool_state, other_values ) + %> + %for input_index, input in enumerate( inputs.itervalues() ): + %if not input.visible: + <% pass %> + %elif input.type == "repeat": + <div class="repeat-group"> + <div class="form-title-row"><strong>${input.title_plural}</strong></div> + <% repeat_state = tool_state[input.name] %> + %for i in range( len( repeat_state ) ): + <div class="repeat-group-item"><% if input.name in errors: - rep_errors = errors[input.name][0] + rep_errors = errors[input.name][i] else: rep_errors = dict() + index = repeat_state[i]['__index__'] %> - ${do_inputs( input.inputs, tool_state[input.name][0], rep_errors, prefix + input.name + "_" + str( 0 ) + "|", other_values )} - %else: - <div class="repeat-group"> - <div class="form-title-row"><b>${input.group_title( other_values )}</b></div> - <% - repeat_state = tool_state[input.name] - %> - %for i in range( len( repeat_state ) ): - <div class="repeat-group-item"> - <% - if input.name in errors: - rep_errors = errors[input.name][i] - else: - rep_errors = dict() - index = repeat_state[i]['__index__'] - %> - <div class="form-title-row"><b>File Contents for ${input.title_by_index( trans, i, other_values )}</b></div> - ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )} - ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div> - </div> - %endfor - ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div> - </div> + <div class="form-title-row"><strong>${input.title} ${i + 1}</strong></div> + ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )} + <div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div> + </div> + %if rep_errors.has_key( '__index__' ): + <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${rep_errors['__index__']}</span></div> %endif + %endfor + <div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div> + </div> + %elif input.type == "conditional": + <% + group_state = tool_state[input.name] + group_errors = errors.get( input.name, {} ) + current_case = group_state['__current_case__'] + group_prefix = prefix + input.name + "|" + %> + %if input.value_ref_in_group: + ${row_for_param( group_prefix, input.test_param, group_state, group_errors, other_values )} + %endif + ${do_inputs( input.cases[current_case].inputs, group_state, group_errors, group_prefix, other_values )} + %elif input.type == "upload_dataset": + %if input.get_datatype( trans, other_values ).composite_type is None: #have non-composite upload appear as before + <% + if input.name in errors: + rep_errors = errors[input.name][0] + else: + rep_errors = dict() + %> + ${do_inputs( input.inputs, tool_state[input.name][0], rep_errors, prefix + input.name + "_" + str( 0 ) + "|", other_values )} %else: - ${row_for_param( prefix, input, tool_state, errors, other_values )} - %endif - %endfor - </%def> - - <%def name="row_for_param( prefix, param, parent_state, parent_errors, other_values )"> - <% - if parent_errors.has_key( param.name ): - cls = "form-row form-row-error" - else: - cls = "form-row" - - label = param.get_label() - - field = param.get_html_field( trans, parent_state[ param.name ], other_values ) - field.refresh_on_change = param.refresh_on_change - - # Field may contain characters submitted by user and these characters may be unicode; handle non-ascii characters gracefully. - field_html = field.get_html( prefix ) - if type( field_html ) is not unicode: - field_html = unicode( field_html, 'utf-8' ) - - if param.type == "hidden": - return field_html - %> - <div class="${cls}"> - %if label: - <label for="${param.name}">${label}:</label> - %endif - <div class="form-row-input">${field_html}</div> - %if parent_errors.has_key( param.name ): - <div class="form-row-error-message"> - <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${parent_errors[param.name]}</span></div> + <div class="repeat-group"> + <div class="form-title-row"><strong>${input.group_title( other_values )}</strong></div> + <% + repeat_state = tool_state[input.name] + %> + %for i in range( len( repeat_state ) ): + <div class="repeat-group-item"> + <% + if input.name in errors: + rep_errors = errors[input.name][i] + else: + rep_errors = dict() + index = repeat_state[i]['__index__'] + %> + <div class="form-title-row"><strong>File Contents for ${input.title_by_index( trans, i, other_values )}</strong></div> + ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )} + ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div> + </div> + %endfor + ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div></div> %endif - - %if param.help: - <div class="toolParamHelp" style="clear: both;"> - ${param.help} - </div> - %endif - - <div style="clear: both"></div> - - </div> - </%def> - - %if add_frame.from_noframe: - <div class="warningmessage"> + %else: + ${row_for_param( prefix, input, tool_state, errors, other_values )} + %endif + %endfor +</%def> + +<%def name="row_for_param( prefix, param, parent_state, parent_errors, other_values )"> + <% + if parent_errors.has_key( param.name ): + cls = "form-row form-row-error" + else: + cls = "form-row" + + label = param.get_label() + + field = param.get_html_field( trans, parent_state[ param.name ], other_values ) + field.refresh_on_change = param.refresh_on_change + + # Field may contain characters submitted by user and these characters may be unicode; handle non-ascii characters gracefully. + field_html = field.get_html( prefix ) + if type( field_html ) is not unicode: + field_html = unicode( field_html, 'utf-8' ) + + if param.type == "hidden": + return field_html + %> + <div class="${cls}"> + %if label: + <label for="${param.name}">${label}:</label> + %endif + <div class="form-row-input">${field_html}</div> + %if parent_errors.has_key( param.name ): + <div class="form-row-error-message"> + <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${parent_errors[param.name]}</span></div> + </div> + %endif + + %if param.help: + <div class="toolParamHelp" style="clear: both;"> + ${param.help} + </div> + %endif + + <div style="clear: both;"></div> + + </div> +</%def> + +<% overlay(visible=False) %> + +%if add_frame.from_noframe: + <div class="warningmessage"><strong>Welcome to Galaxy</strong><hr/> It appears that you found this tool from a link outside of Galaxy. @@ -205,60 +232,59 @@ <a href="${h.url_for( controller='root' )}" target="_top">welcome page</a>. To learn more about what Galaxy is and what it can do for you, please visit the <a href="$add_frame.wiki_url" target="_top">Galaxy wiki</a>. - </div> - <br/> + </div> + <br/> +%endif + +## handle calculating the redict url for the special case where we have nginx proxy +## upload and need to do url_for on the redirect portion of the tool action +<% + try: + tool_url = h.url_for(tool.action) + except AttributeError: + assert len(tool.action) == 2 + tool_url = tool.action[0] + h.url_for(tool.action[1]) +%> +<div class="toolForm" id="${tool.id}"> + %if tool.has_multiple_pages: + <div class="toolFormTitle">${tool.name} (step ${tool_state.page+1} of ${tool.npages})</div> + %else: + <div class="toolFormTitle">${tool.name}</div> %endif - - ## handle calculating the redict url for the special case where we have nginx proxy - ## upload and need to do url_for on the redirect portion of the tool action - <% - try: - tool_url = h.url_for(tool.action) - except AttributeError: - assert len(tool.action) == 2 - tool_url = tool.action[0] + h.url_for(tool.action[1]) - %><div class="toolForm" id="${tool.id}"> - %if tool.has_multiple_pages: - <div class="toolFormTitle">${tool.name} (step ${tool_state.page+1} of ${tool.npages})</div> - %else: - <div class="toolFormTitle">${tool.name}</div> - %endif - <div class="toolFormBody"> - <form id="tool_form" name="tool_form" action="${tool_url}" enctype="${tool.enctype}" target="${tool.target}" method="${tool.method}"> - <input type="hidden" name="tool_id" value="${tool.id}"> - <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}"> - %if tool.display_by_page[tool_state.page]: - ${trans.fill_template_string( tool.display_by_page[tool_state.page], context=tool.get_param_html_map( trans, tool_state.page, tool_state.inputs ) )} - <input type="submit" class="primary-button" name="runtool_btn" value="Execute"> - %else: - ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, errors, "" )} - <div class="form-row"> - %if tool_state.page == tool.last_page: - <input type="submit" class="primary-button" name="runtool_btn" value="Execute"> - %else: - <input type="submit" class="primary-button" name="runtool_btn" value="Next step"> - %endif - </div> - %endif - </form> + <div class="toolFormBody"> + <form id="tool_form" name="tool_form" action="${tool_url}" enctype="${tool.enctype}" target="${tool.target}" method="${tool.method}"> + <input type="hidden" name="tool_id" value="${tool.id}"> + <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}"> + %if tool.display_by_page[tool_state.page]: + ${trans.fill_template_string( tool.display_by_page[tool_state.page], context=tool.get_param_html_map( trans, tool_state.page, tool_state.inputs ) )} + <input type="submit" class="primary-button" name="runtool_btn" value="Execute"> + %else: + ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, errors, "" )} + <div class="form-row"> + %if tool_state.page == tool.last_page: + <input type="submit" class="primary-button" name="runtool_btn" value="Execute"> + %else: + <input type="submit" class="primary-button" name="runtool_btn" value="Next step"> + %endif + </div> + %endif + </form> + </div> +</div> +%if tool.help: + <div class="toolHelp"> + <div class="toolHelpBody"> + <% + if tool.has_multiple_pages: + tool_help = tool.help_by_page[tool_state.page] + else: + tool_help = tool.help + + # Convert to unicode to display non-ascii characters. + if type( tool_help ) is not unicode: + tool_help = unicode( tool_help, 'utf-8') + %> + ${tool_help} </div></div> - %if tool.help: - <div class="toolHelp"> - <div class="toolHelpBody"> - <% - if tool.has_multiple_pages: - tool_help = tool.help_by_page[tool_state.page] - else: - tool_help = tool.help - - # Convert to unicode to display non-ascii characters. - if type( tool_help ) is not unicode: - tool_help = unicode( tool_help, 'utf-8') - %> - ${tool_help} - </div> - </div> - %endif -</body> -</html> +%endif Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.