I came accross some weird situation when using a component that is a composition of other components. A subcomponent may in turn be a composition of some more components. To make things even more complex, some deeply nested subcomponents may call some other component.
Some of the subcomponents may contain some input html tag and as such will require to be contained in a form html tag. In such a complex construct it may be difficult to decide exactly what component should have the responsibility to generate the form tag. Also, it happened frequently to me that form tags become nested especially when a subcomponent calls another component that happens to be a dialog.
Therefore I am making the following suggestion : Seaside should prevent form tags from being nested. It should discard any form tag that occurs within a previously opened form tag.
With this in place, I can design a component that needs a form with a form construct knowing that if my component happens to be used inside a form, then my form construct will be discarded. Otherwise my form construct will be preserved. If my component calls a dialog component, the form generated by the dialog component will be discarded if my component happens to be used from inside a form.
Michel.
On Jun 28, 2004, at 5:23 AM, Bany, Michel wrote:
I came accross some weird situation when using a component that is a composition of other components. A subcomponent may in turn be a composition of some more components. To make things even more complex, some deeply nested subcomponents may call some other component.
Some of the subcomponents may contain some input html tag and as such will require to be contained in a form html tag. In such a complex construct it may be difficult to decide exactly what component should have the responsibility to generate the form tag. Also, it happened frequently to me that form tags become nested especially when a subcomponent calls another component that happens to be a dialog.
Yes, I've found this too. The behavior can be extremely unpredictable when this happens.
Therefore I am making the following suggestion : Seaside should prevent form tags from being nested. It should discard any form tag that occurs within a previously opened form tag.
<snip>
If my component calls a dialog component, the form generated by the dialog component will be discarded if my component happens to be used from inside a form.
The problem with that is that the dialog component will now be part of the larger form that is around it, and clicking on buttons in the dialog will submit the entire form. Depending on what the callbacks are for that form, this could be undesirable. The browser is also likely to do unexpected things - for example, if you had this:
html form: [html submitButtonWithText: 'Foo'. html form: [html textInputWithValue: '' callback: [..]. html submitButtonWithText: 'Bar']]
On most browsers, typing into the text input and then hitting return will automatically press the "Foo" submit button, even though the user would expect it to select "Bar".
We might be able to deal with the first problem (by only processing callbacks in the same conceptual form as whatever submit button is pressed, even if the submission itself is larger because of a shared form tag), but there's not much we can do about the second one.
So, I don't have a solution. For now it's probably best if there's an immediate and explicit error whenever you end up with nested forms. It doesn't help you fix the problem, but at least it alerts you to exactly what the problem is.
Avi
I believe I found the bug that causes the weird effects that have been observed when nesting forms.
When there are nested <form> in the html and when a submit button is pressed, the resulting http request contains the "_s" and the "_k" hidden fields many times (once for each form). As a result the http fields in the request are holding collection of strings rather than just strings (the field dictionary object is too smart !) In such situations, Seaside is not able to retrieve the session and shows the expiration screen.
I found that the consequences of the bug can be in corrected WAKom>>convertRequest: where the request fields can be computed differently. The implementation in the attachment eliminates the false expiration.
This does not occur in VisualWorks where the computation of the request fields are always and consistently available as collections or strings.
The attached change set includes both the fix and a test component with nested <form>
Enjoy, Michel.
'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 3 November 2005 at 10:28:53 pm'! WAComponent subclass: #WANestedForms instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Seaside-Examples-Test'!
!WAKom methodsFor: 'as yet unclassified' stamp: 'mb 11/3/2005 22:28'! convertRequest: aKomRequest | request fields waFields | self processMultipartFields: aKomRequest. fields := aKomRequest method = 'POST' ifTrue: [aKomRequest postFields] ifFalse: [aKomRequest getFields]. waFields := Dictionary new. fields keysAndValuesDo: [:k :v | v isString ifFalse: [waFields at: k put: v first] ifTrue: [waFields at: k put: v]]. request := WARequest method: aKomRequest method url: aKomRequest url unescapePercents headers: aKomRequest header fields: waFields cookies: aKomRequest cookies nativeRequest: aKomRequest. aKomRequest method = 'PUT' ifTrue: [request fields at: 'PUTData' put: (aKomRequest stream next: aKomRequest contentLength)]. ^ request! !
!WANestedForms methodsFor: 'rendering' stamp: 'mb 11/3/2005 22:17'! renderContentOn: html html heading: 'Buttons in nested forms'. html text: 'Click the buttons and get an expired session !!'. html form: [html submitButtonWithAction: [self inform: 'Button1'] text: 'Button1'. html form: [html submitButtonWithAction: [self inform: 'Button2'] text: 'Button2']]! !
!WANestedForms class methodsFor: 'initialize-release' stamp: 'mb 11/3/2005 22:13'! initialize self registerAsApplication: 'NestedForms'! !
WANestedForms initialize!
!WANestedForms class reorganize! ('initialize-release' initialize) !
!WANestedForms reorganize! ('rendering' renderContentOn:) !
ShoreComponents solve this problem. Demo is included. http://www.squeaksource.com/ShoreComponents/
-- Pavel
I believe I found the bug that causes the weird effects that have been observed when nesting forms.
When there are nested <form> in the html and when a submit button is pressed, the resulting http request contains the "_s" and the "_k" hidden fields many times (once for each form). As a result the http fields in the request are holding collection of strings rather than just strings (the field dictionary object is too smart !) In such situations, Seaside is not able to retrieve the session and shows the expiration screen.
I found that the consequences of the bug can be in corrected WAKom>>convertRequest: where the request fields can be computed differently. The implementation in the attachment eliminates the false expiration.
This does not occur in VisualWorks where the computation of the request fields are always and consistently available as collections or strings.
The attached change set includes both the fix and a test component with nested <form>
Enjoy, Michel.
'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 3 November 2005 at 10:28:53 pm'! WAComponent subclass: #WANestedForms instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Seaside-Examples-Test'!
!WAKom methodsFor: 'as yet unclassified' stamp: 'mb 11/3/2005 22:28'! convertRequest: aKomRequest | request fields waFields | self processMultipartFields: aKomRequest. fields := aKomRequest method = 'POST' ifTrue: [aKomRequest postFields] ifFalse: [aKomRequest getFields]. waFields := Dictionary new. fields keysAndValuesDo: [:k :v | v isString ifFalse: [waFields at: k put: v first] ifTrue: [waFields at: k put: v]]. request := WARequest method: aKomRequest method url: aKomRequest url unescapePercents headers: aKomRequest header fields: waFields cookies: aKomRequest cookies nativeRequest: aKomRequest. aKomRequest method = 'PUT' ifTrue: [request fields at: 'PUTData' put: (aKomRequest stream next: aKomRequest contentLength)]. ^ request! !
!WANestedForms methodsFor: 'rendering' stamp: 'mb 11/3/2005 22:17'! renderContentOn: html html heading: 'Buttons in nested forms'. html text: 'Click the buttons and get an expired session !!'. html form: [html submitButtonWithAction: [self inform: 'Button1'] text: 'Button1'. html form: [html submitButtonWithAction: [self inform: 'Button2'] text: 'Button2']]! !
!WANestedForms class methodsFor: 'initialize-release' stamp: 'mb 11/3/2005 22:13'! initialize self registerAsApplication: 'NestedForms'! !
WANestedForms initialize!
!WANestedForms class reorganize! ('initialize-release' initialize) !
!WANestedForms reorganize! ('rendering' renderContentOn:) !
Seaside mailing list Seaside@lists.squeakfoundation.org http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Pavel Krivanek a écrit :
ShoreComponents solve this problem. Demo is included. http://www.squeaksource.com/ShoreComponents/
I would rather say that ShoreComponents add a layer on top of Seaside that addresses this issue.
I think I remember Avi saying there is a utility in Squeak that allows filing out Squeak code in VW compatible format. Is this true? If so, where would I find it?
Thanks, Brett
Hi. I had the same issue some tine before. Avi said ( http://lists.squeakfoundation.org/pipermail/squeak-dev/2004-June/079421.html )
Assuming your code uses PackageInfo conventions, you can use PackageInfo-Exporters from SqueakMap. Once installed, try
VW5PackageExporter fileOutPackageNamed: 'MyPackage'
Avi
I had some problems with it but afaik seaisde for vw is heavily using this feature so you might be lucky using it.
regards marco
On Tue, 22 Feb 2005 12:01:21 -0800, Brett Taylor brett.taylor@healthauditors.com wrote:
I think I remember Avi saying there is a utility in Squeak that allows filing out Squeak code in VW compatible format. Is this true? If so, where would I find it?
Thanks, Brett
Seaside mailing list Seaside@lists.squeakfoundation.org http://lists.squeakfoundation.org/listinfo/seaside
seaside@lists.squeakfoundation.org