Just test for the existence of the form variable with the name given to the
'name' attribute of the button:
class Controller:
@expose(self, **kw):
if kw.get('action_kung'):
# do action kung
elif kw.get('action_foo'):
# do action foo
where your form would look like:
<form>
....
<input type="submit" name="action_foo" value="Do Kung!">
<input type="submit" name="action_foo" value="Do Foo!">
</form>
The test for the existence of the submit button should really be
kw.get('action_foo') is not None
but since form variables will be always strings, unless you mangle them with
validators, there is no danger that a 0 (zero) integer value will be
interpreted as False.
Explanation:
You test for the name rather for the value of the submit button, because submit
buttons display their value as the button label, which will probably change in
your application according to i18n, so you can't test for it in your controller.
Normally, one should be able to use <button type="submit"> elements instead,
since these can contain any element, but stupid IE will always submit values
for *all* <button> elements in a form, regardless of which one you click!
You can test this with this simple form:
<form>
<input type="text" name="text" size="50">
<button name="nosubmit">
This does nothing
</button>
<button type="submit" name="kung">
Do Kung!
</button>
<button type="submit" name="foo">
Do Foo!
</button>
</form>
HTH, Chris
Sorry, that should be:
<form>
....
<input type="submit" name="action_kung" value="Do Kung!">
<input type="submit" name="action_foo" value="Do Foo!">
</form>
Chris
Argh, where's my head:
class Controller:
@expose()
def index(self, **kw):
if kw.get('action_kung'):
# do action kung
elif kw.get('action_foo'):
# do action foo
*now goes to make dinner so that brain gets some blood sugar again*
Chris
BTW, for the most common case, where you want a submit and a cancel button, you
can just put a link instead of the cancel button, that references another url
than the form action, and then make it look like a button with CSS:
<style>
a.button {
color: black;
border: .2em outset #e2e2de;
background-color: #e2e2de;
font-family: sans-serif;
font-size: small;
text-decoration: none;
padding: .15em .5em;
display: inline-block;
cursor: default;
}
a.button:active {
border-style: inset;
}
</style>
<input type="submit" value="A real button">
<a class="button" href="#">A fake button</a>
Of course, you should then style normal buttons accordingly too.
Chris
IIRC basecamp (made by the Ruby on Rails team) had this problem when
google's web accelerator went click-happy and deleted a bunch of stuff.
Moral: Even on a restricted site you should beware of this kind of
thing. You can restyle links and buttons so one looks like the other,
that is pretty much always a better solution than using one instead of
the other.
-Adam
class Controller:
@expose()
def index(self, **kw):
if kw.get('action_kung'):
# do action kung, but kung is another function
elif kw.get('action_foo'):
# do action foo, but foo is another function
@expose()
def kung(self, **kw):
...
@expose()
def foo(self, **kw):
...
>
> A slight spinoff of this question... suppose that I wanted to call
> another function within the index def? If I just borrow the code from
> above... is it possible to call a function kung (or foo, doesn't
> matter), from the index function (and pass **kw along with it)?
Sure, why not? :) In fact, this is precisely what errorhandling does
when calling the error handler after validation fails or an exception
occurs.
Alberto
@expose(sometemplate1)
def kung(self, **kw):
...
return dict(kw=kw)
@expose(sometemplate2)
def foo(self, **kw):
...
return dict(kw=kw)
Where I want kung to display sometemplate1 and foo to display
sometemplate2. But if I un the above code, then it calls kung (or foo)
and then returns back to index() and continues... is there any way to
redirect to kung so that sometemplate1 is displayed?
Did that make sense? I was actually getting lost writing my own
question, :)
Frank
You need to return the output of the method you're calling:
@expose()
def index(self, **kw):
if kw.get('action_kung'):
return self.kung(**kw)
----------^^^^^
elif kw.get('action_foo'):
return self.foo(**kw)
Alberto
Keep in mind that you also need to set a tg_template key in your return
dictionary if you want to override the template that is used. So to
have index use kung's template you would use code like:
@expose()
def index(self, **kw):
if kw.get('action_kung'):
return
self.kung(**kw).update(dict(tg_template="sometemplate1"))
-Adam
>
> Alberto
But I found one of Adam's other threads: http://tinyurl.com/t9osu,
which was exactly what I wanted.
Thanks again
Frank
This will not work as expected. The update method of dict does not
return the updated dict. Correct:
@expose()
def index(self, **kw):
if kw.get('action_kung'):
kw.update(dict(tg_template="sometemplate1"))
return self.kung(**kw)
Chris
Hmmm, not really. self.kung will return a string because it's already
decorated by "expose" so you can't really do that. To get the dict
self.kung would have returned un-decorated you have to undecorate it
yourself before calling it (take a look at turbogears.decorator for a
function called func_orig (or something like that, can't check that out
ATM cause I'm in public access point (with IE6 and a 15" CRT... argggg))
which does that. That way you will return a dict and index's "expose" will
process that dict (instead of "kung"'s)
Alberto
I think the best way (imho) is to make sure each method returns its
own tg_template value. Also, unless you're going to be using them via
their own URL's as well, I wouldn't use @expose() on the kung and foo
methods:
class Controller(controllers.Controller):
@expose()
def index(self, **kw):
if kw.get('action_kung'):
return self.kung(**kw)
elif kw.get('action_foo'):
return self.foo(**kw)
def kung(self, **kw):
# Note the complete lack of @expose()
# Do stuff here
return dict(tg_template=".templates.kung", kw=kw)
def foo(self, **kw):
# No @expose() again
return dict(tg_template=".templates.foo", kw=kw)
Lee
--
Lee McFadden
blog: http://www.splee.co.uk
work: http://fireflisystems.com
skype: fireflisystems