Re: [galaxy-dev] Conditionally showing certain form elements on tool page
Hi John, On Thu, Aug 16, 2012 at 9:51 AM, John Patterson <jmpatt4@g.uky.edu> wrote:
On 08/15/2012 08:59 PM, Dan Tenenbaum wrote:
Hi all,
I'm trying to wrap my head around what the <conditional> tag does...it looks like it doesn't do what I would like.
I want to create a tool that allows the user to upload a data file and then have it run through one or more filters. Each filter takes one or more parameters.
I was thinking I could do something like this:
<inputs> <conditional name="mycond"> <param name="checktest" type="boolean" label="foo" value="yessir"> </param> <when value="yessir"> <param name="param1" type="text" label="bar" value="twunk"> </param> </when> </conditional> </inputs>
The idea being, if the user checks the box labeled "foo", a text box labeled "bar" will appear. And I would have several such checkboxes and their accompanying parameters. But what I get is just the checkbox, and nothing happens when I click it.
Is it possible to do what I have in mind, and if so, how?
Also note that these conditions are not mutually exclusive. A user can select one *or more* filters. So I'm not sure how the body of my <command> tag should look. Is there a way I can just pass every possible parameter to my script like this: myscript.py param1=foo param2=bar If a parameter is not defined (because the user didn't click its associated checkbox), then the script will receive e.g. param1= param2=bar but it can deal with that.
I realize I can make several tools and chain them together in a workflow, but that seems like overkill for this use case, and it would be nice if the user could set up their desired filters on one screen.
Is this possible? Thanks! Dan ___________________________________________________________ Please keep all replies on the list by using "reply all" in your mail client. To manage your subscriptions to this and other Galaxy lists, please use the interface at:
Hello Dan,
The easiest way to go about this, since you said that none of your filters are mutually exclusive, is to use the "select" datatype. I don't think you even need the conditional tags. Galaxy says that you need <when> tag sets when you use conditionals, but this is not true, as I have similar code as I have written below. Use type="select" in your parameter. This gives you a button that can have a multitude of options, but most of mine are simply used like booleans. Something like this:
<inputs> <param name="param1" type="select" label="filterName" help="helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> <param name="param2" type="select" label="filter2Name" help="more helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> </inputs>
I had certain options that WERE mutually exclusive, and required nested conditional statements, where I had an outer conditional for the extra options, and an inner conditional around each parameter.
As for the command tag, the select type parameters make it easy because you can just check the string values with an if statement, like so: (assuming python) <command interpreter="python"> tool.py #if $param1 == "yes": --YourGetOptFlag #else: ##dont even need an else, just ignore #end if
</command>
If I am not mistaken, this should be sufficient if all you need to pass is a flag indicating your program to use the filter. If you need to pass a flag AND integer values, you are going to have to wrap your parameters in conditional tags and use a set of <when>:
<inputs> <conditional name="firstConditional"> <param name="param1" type="select" label="filterName" help="helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> <when value="yes"> <param name="IntegerBox" type="integer" value="[default value]" min="(optional)" max="(optional)" label="UseParamName" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> </inputs>
Rinse and repeat, adding conditionals around each select. I think this is actually what you want to do, as you say you want a box to appear after a user selects whether or not to use the filter. Also, quick note, the text between the option tags are what appear on the select buttons, so they can be whatever you want. The value="" is the important thing, as this is what you will evaluate the "if/else" to in the <command> tag. One last thing, The cheetah command is really no different.
<command interpreter="python"> tool.py #if $firstConditional.param1 == "yes": --testGetOpt $firstConditional.IntegerBox #end if
</command>
The second command tag is how I pass a few parameters into my command line tool.
Anyway, I hope this helped a little bit. If you need anything else, let me know and I will see If I can help. A lot of this was trial and error and I am sure there are trickier ways to doing it, but this worked for the scope of my program.
This is extremely helpful! Thanks. I find the select box yes/no idiom a bit awkward. I'd prefer a checkbox (just a single one, not one each for "yes" and "no") but doing a select box is ok too, I can live with that. I'm running into problems constructing my command, though. I'm new to cheetah so that might be it. First off, here's my inputs and outputs: <inputs> <conditional name="firstConditional"> <param name="param1" type="select" label="Filter 1" help="helpful tips"> <option value="no">no</option> <option value="yes">yes</option> </param> <when value="yes"> <param name="IntegerBox" type="integer" value="1" min="0" max="5" label="A parameter to filter 1" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> <conditional name="secondConditional"> <param name="param2" type="select" label="Filter 2" help="helpful tips"> <option value="no">no</option> <option value="yes">yes</option> </param> <when value="yes"> <param name="IntegerBox2" type="integer" value="1" min="0" max="5" label="A parameter to filter 2" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> </inputs> <outputs> <data format="csv" name="outputFileName"/> </outputs> So the page displays two select boxes. If you select either one of them, a text box appears. This feeds to a python script that for now just echoes the parameters passed in and writes them to a file, which I can examine in galaxy. So here is what I have in the command section: <command interpreter="python"> tool.py #if $firstConditional.param1 == "yes": --filter1 $firstConditional.IntegerBox #end if # if $secondConditional.param2 == "yes": --filter2 $secondConditional.IntegerBox2 #end if $outputFileName </command> This results in an error: galaxy.jobs.runners.local ERROR 2012-08-16 10:43:42,677 failure running job 87 Traceback (most recent call last): File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/jobs/runners/local.py", line 59, in run_job job_wrapper.prepare() File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/jobs/__init__.py", line 429, in prepare self.command_line = self.tool.build_command_line( param_dict ) File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/tools/__init__.py", line 1971, in build_command_line command_line = fill_template( self.command, context=param_dict ) File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/util/template.py", line 9, in fill_template return str( Template( source=template_text, searchList=[context] ) ) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 1244, in __init__ self._compile(source, file, compilerSettings=compilerSettings) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 1538, in _compile keepRefToGeneratedCode=True) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 745, in compile compiler.compile() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Compiler.py", line 1670, in compile self._parser.parse() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1488, in parse self.eatDirective() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1610, in eatDirective directiveParser() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1761, in eatEndDirective self.popFromOpenDirectivesStack(directiveName) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 2645, in popFromOpenDirectivesStack raise ParseError(self, msg="#end found, but nothing to end") ParseError: #end found, but nothing to end Line 8, column 1 Line|Cheetah Code ----|------------------------------------------------------------- 5 | # if $secondConditional.param2 == "yes": 6 | --filter2 $secondConditional.IntegerBox2 7 | #end if 8 | $outputFileName ^ 9 | What I am trying to do is build up a command line bit by bit. Pseudocode would be like this: commandline = "tool.py " if condition_a: commandline += "--filter1 25.6 " if condition_b: commandline += "--filter2 86.2 " commandline += "outputfilename" What am I doing wrong? Thanks again! Dan
-John
___________________________________________________________ Please keep all replies on the list by using "reply all" in your mail client. To manage your subscriptions to this and other Galaxy lists, please use the interface at:
On Thu, Aug 16, 2012 at 10:53 AM, Dan Tenenbaum <dtenenba@fhcrc.org> wrote:
Hi John,
On Thu, Aug 16, 2012 at 9:51 AM, John Patterson <jmpatt4@g.uky.edu> wrote:
On 08/15/2012 08:59 PM, Dan Tenenbaum wrote:
Hi all,
I'm trying to wrap my head around what the <conditional> tag does...it looks like it doesn't do what I would like.
I want to create a tool that allows the user to upload a data file and then have it run through one or more filters. Each filter takes one or more parameters.
I was thinking I could do something like this:
<inputs> <conditional name="mycond"> <param name="checktest" type="boolean" label="foo" value="yessir"> </param> <when value="yessir"> <param name="param1" type="text" label="bar" value="twunk"> </param> </when> </conditional> </inputs>
The idea being, if the user checks the box labeled "foo", a text box labeled "bar" will appear. And I would have several such checkboxes and their accompanying parameters. But what I get is just the checkbox, and nothing happens when I click it.
Is it possible to do what I have in mind, and if so, how?
Also note that these conditions are not mutually exclusive. A user can select one *or more* filters. So I'm not sure how the body of my <command> tag should look. Is there a way I can just pass every possible parameter to my script like this: myscript.py param1=foo param2=bar If a parameter is not defined (because the user didn't click its associated checkbox), then the script will receive e.g. param1= param2=bar but it can deal with that.
I realize I can make several tools and chain them together in a workflow, but that seems like overkill for this use case, and it would be nice if the user could set up their desired filters on one screen.
Is this possible? Thanks! Dan ___________________________________________________________ Please keep all replies on the list by using "reply all" in your mail client. To manage your subscriptions to this and other Galaxy lists, please use the interface at:
Hello Dan,
The easiest way to go about this, since you said that none of your filters are mutually exclusive, is to use the "select" datatype. I don't think you even need the conditional tags. Galaxy says that you need <when> tag sets when you use conditionals, but this is not true, as I have similar code as I have written below. Use type="select" in your parameter. This gives you a button that can have a multitude of options, but most of mine are simply used like booleans. Something like this:
<inputs> <param name="param1" type="select" label="filterName" help="helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> <param name="param2" type="select" label="filter2Name" help="more helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> </inputs>
I had certain options that WERE mutually exclusive, and required nested conditional statements, where I had an outer conditional for the extra options, and an inner conditional around each parameter.
As for the command tag, the select type parameters make it easy because you can just check the string values with an if statement, like so: (assuming python) <command interpreter="python"> tool.py #if $param1 == "yes": --YourGetOptFlag #else: ##dont even need an else, just ignore #end if
</command>
If I am not mistaken, this should be sufficient if all you need to pass is a flag indicating your program to use the filter. If you need to pass a flag AND integer values, you are going to have to wrap your parameters in conditional tags and use a set of <when>:
<inputs> <conditional name="firstConditional"> <param name="param1" type="select" label="filterName" help="helpful tips"> <option value="yes">yes</option> <option value="no">no</option> </param> <when value="yes"> <param name="IntegerBox" type="integer" value="[default value]" min="(optional)" max="(optional)" label="UseParamName" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> </inputs>
Rinse and repeat, adding conditionals around each select. I think this is actually what you want to do, as you say you want a box to appear after a user selects whether or not to use the filter. Also, quick note, the text between the option tags are what appear on the select buttons, so they can be whatever you want. The value="" is the important thing, as this is what you will evaluate the "if/else" to in the <command> tag. One last thing, The cheetah command is really no different.
<command interpreter="python"> tool.py #if $firstConditional.param1 == "yes": --testGetOpt $firstConditional.IntegerBox #end if
</command>
The second command tag is how I pass a few parameters into my command line tool.
Anyway, I hope this helped a little bit. If you need anything else, let me know and I will see If I can help. A lot of this was trial and error and I am sure there are trickier ways to doing it, but this worked for the scope of my program.
This is extremely helpful! Thanks. I find the select box yes/no idiom a bit awkward. I'd prefer a checkbox (just a single one, not one each for "yes" and "no") but doing a select box is ok too, I can live with that.
I'm running into problems constructing my command, though. I'm new to cheetah so that might be it.
First off, here's my inputs and outputs:
<inputs> <conditional name="firstConditional"> <param name="param1" type="select" label="Filter 1" help="helpful tips"> <option value="no">no</option> <option value="yes">yes</option> </param> <when value="yes"> <param name="IntegerBox" type="integer" value="1" min="0" max="5" label="A parameter to filter 1" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> <conditional name="secondConditional"> <param name="param2" type="select" label="Filter 2" help="helpful tips"> <option value="no">no</option> <option value="yes">yes</option> </param> <when value="yes"> <param name="IntegerBox2" type="integer" value="1" min="0" max="5" label="A parameter to filter 2" help="helpful text" /> </when> <when value="no" /> <!--Doesnt show integer text box when no is chosen in the select--> </conditional> </inputs> <outputs> <data format="csv" name="outputFileName"/> </outputs>
So the page displays two select boxes. If you select either one of them, a text box appears.
This feeds to a python script that for now just echoes the parameters passed in and writes them to a file, which I can examine in galaxy.
So here is what I have in the command section:
<command interpreter="python"> tool.py #if $firstConditional.param1 == "yes": --filter1 $firstConditional.IntegerBox #end if # if $secondConditional.param2 == "yes":
Got rid of the space between # and if and that seems to have fixed this. Thanks Dan
--filter2 $secondConditional.IntegerBox2 #end if $outputFileName </command>
This results in an error:
galaxy.jobs.runners.local ERROR 2012-08-16 10:43:42,677 failure running job 87 Traceback (most recent call last): File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/jobs/runners/local.py", line 59, in run_job job_wrapper.prepare() File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/jobs/__init__.py", line 429, in prepare self.command_line = self.tool.build_command_line( param_dict ) File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/tools/__init__.py", line 1971, in build_command_line command_line = fill_template( self.command, context=param_dict ) File "/Users/dtenenba/dev/galaxy-dist/lib/galaxy/util/template.py", line 9, in fill_template return str( Template( source=template_text, searchList=[context] ) ) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 1244, in __init__ self._compile(source, file, compilerSettings=compilerSettings) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 1538, in _compile keepRefToGeneratedCode=True) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Template.py", line 745, in compile compiler.compile() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Compiler.py", line 1670, in compile self._parser.parse() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1488, in parse self.eatDirective() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1610, in eatDirective directiveParser() File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 1761, in eatEndDirective self.popFromOpenDirectivesStack(directiveName) File "/Users/dtenenba/dev/galaxy-dist/eggs/Cheetah-2.2.2-py2.7-macosx-10.6-intel-ucs2.egg/Cheetah/Parser.py", line 2645, in popFromOpenDirectivesStack raise ParseError(self, msg="#end found, but nothing to end") ParseError:
#end found, but nothing to end Line 8, column 1
Line|Cheetah Code ----|------------------------------------------------------------- 5 | # if $secondConditional.param2 == "yes": 6 | --filter2 $secondConditional.IntegerBox2 7 | #end if 8 | $outputFileName ^ 9 |
What I am trying to do is build up a command line bit by bit. Pseudocode would be like this:
commandline = "tool.py " if condition_a: commandline += "--filter1 25.6 " if condition_b: commandline += "--filter2 86.2 " commandline += "outputfilename"
What am I doing wrong?
Thanks again! Dan
-John
___________________________________________________________ Please keep all replies on the list by using "reply all" in your mail client. To manage your subscriptions to this and other Galaxy lists, please use the interface at:
On Thu, Aug 16, 2012 at 6:53 PM, Dan Tenenbaum <dtenenba@fhcrc.org> wrote:
Hi John,
On Thu, Aug 16, 2012 at 9:51 AM, John Patterson <jmpatt4@g.uky.edu> wrote:
Hello Dan,
The easiest way to go about this, since you said that none of your filters are mutually exclusive, is to use the "select" datatype. I don't think you even need the conditional tags. Galaxy says that you need <when> tag sets when you use conditionals, but this is not true, as I have similar code as I have written below. Use type="select" in your parameter. This gives you a button that can have a multitude of options, but most of mine are simply used like booleans. Something like this: ...
This is extremely helpful! Thanks. I find the select box yes/no idiom a bit awkward. I'd prefer a checkbox (just a single one, not one each for "yes" and "no") but doing a select box is ok too, I can live with that.
Using a boolean checkbox should work - although early on it wasn't possible thus many older tools use a select instead: https://bitbucket.org/galaxy/galaxy-central/issue/393/cant-use-checkbox-bool... Peter
Hi John and Peter, On Thu, Aug 16, 2012 at 11:37 AM, Peter Cock <p.j.a.cock@googlemail.com> wrote:
On Thu, Aug 16, 2012 at 6:53 PM, Dan Tenenbaum <dtenenba@fhcrc.org> wrote:
Hi John,
On Thu, Aug 16, 2012 at 9:51 AM, John Patterson <jmpatt4@g.uky.edu> wrote:
Hello Dan,
The easiest way to go about this, since you said that none of your filters are mutually exclusive, is to use the "select" datatype. I don't think you even need the conditional tags. Galaxy says that you need <when> tag sets when you use conditionals, but this is not true, as I have similar code as I have written below. Use type="select" in your parameter. This gives you a button that can have a multitude of options, but most of mine are simply used like booleans. Something like this: ...
This is extremely helpful! Thanks. I find the select box yes/no idiom a bit awkward. I'd prefer a checkbox (just a single one, not one each for "yes" and "no") but doing a select box is ok too, I can live with that.
Using a boolean checkbox should work - although early on it wasn't possible thus many older tools use a select instead: https://bitbucket.org/galaxy/galaxy-central/issue/393/cant-use-checkbox-bool...
I can do a checkbox like this: <param name="cbtest" type="boolean" label="checkbox" help="some help"/> But I want to have a checkbox that triggers some other params to appear when it is checked (the way I have successfully done it with a select). I haven't been able to figure that out. If I do this: <conditional name="thirdConditional"> <param name="param2" type="boolean" value="yes" label="Filter 3" help="helpful tips" /> <when value="yes"> <param name="IntegerBox3" type="integer" value="1" min="0" max="5" label="A parameter to filter 3" help="helpful text" /> </when> <when value="no" /> </conditional> ...nothing happens when I click the checkbox. I also tried using a select with multiple="true" and display="checkbox", but Galaxy doesn't like that because I provide only one option ("yes"). If you could tell me how to cause params to appear/disappear by checking a checkbox that would be great! Thanks, Dan
Peter
participants (2)
-
Dan Tenenbaum
-
Peter Cock