[Seaside] anchors behaving like buttons?
Nevin Pratt
nevin at smalltalkpro.com
Fri Jun 13 18:29:28 CEST 2003
I've just updated our site to the latest SqueakMap version of Seaside.
However, the scheme I wrote about below no longer works for targeting
different entry points into the app.
For example, if the browser URL is:
http://localhost/seaside/foo/red
then the 'path' variable in step #4 should return '/seaside/foo/red', so
that I can invoke the #red method on the 'foo' component as explained in
step #4.
But with this release, 'path := self session path' in step #4 just
returns '/seaside/foo'. Thus, I have no idea what method of the 'foo'
component the URL intends to invoke.
This forces me to have a single entry point into each component of the
app, which forces me to rearchitect somewhat (unless I can find an
alternative way to recreate the old behavior).
For example, when I wanted to give someone a URL that would take them
directly to our 'View Cart' page, I would email them this:
http://www.bountifulbaby.com/seaside/index/viewcart
This would invoke the #viewcart method of the 'index' component, which
would then take them to the shopping cart.
I suppose I could create a separate 'viewcart' entry point into the app
via '/seaside/config', but I quite liked having the ability to invoke
arbitrary methods on a component via the URL.
Any suggestions?
Nevin
************************
************************
Derek Brans wrote:
> In Seaside, is there a way to have an anchor tag that will submit a
> form and perform an action (behaving just like a button)?
>
I've got a scheme that seems to work OK:
Suppose you've got a component 'Foo', with launch URL of
'http://localhost/seaside/foo' (or whatever machine and port you
choose). Now, suppose the 'Foo' component has links 'red' and 'green'
in the GUI, which you want to use to invoke methods #red and #green on
component Foo when the links are clicked on.
1. Define the URL for the 'red' link to be '/seaside/foo/red', and for
the 'green' link to be '/seaside/foo/green'.
2. Give 'Foo' an instance variable called 'targets', and then create an
#initialize method of 'Foo' thus:
initialize
targets _ OrderedCollection new.
targets add: #red;
add: #green
3. Give 'Foo' a 'lastTarget' instance variable, which will be used to
prevent recursive circularities, as shown later.
4. Put the following in Foo's #renderContentOn:
renderContentOn: html
| path sel |
path _ self session path.
sel _ (path copyAfterLast: $/) asLegalSelector asSymbol.
(lastTarget ~= sel
and: [targets includes: sel])
ifTrue: [lastTarget _ sel.
^self perform: sel].
{ ... the rest of the normal rendering code here ... }
With the above, the 'red' and 'green' links will invoke the #red and
#green target methods (respectively) of the component, just like a
button does.
You can, if you wish, easily eliminate the need for the 'targets'
instance variable by, for example, looking for methods within a certain
method category, or for methods that begin (or end) with some common
string, or even be more general by replacing 'targets includes: sel'
with something like 'self respondsTo: sel', but I think I would prefer
to keep strict control over what methods can be invoked via the URL with
this scheme. So, I would use a 'targets' instance variable to
explicitly define allowable methods that can be invoked with this scheme.
Nevin
_______________________________________________
Seaside mailing list
Seaside at lists.squeakfoundation.org
http://lists.squeakfoundation.org/listinfo/seaside
More information about the Seaside
mailing list