Problem with Checkboxes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with Checkboxes

Felix Dorner
Hey,

first, I am a Squeak/Smalltalk newcomer, so please forgive me if I make
an obvious error. I also give as much detail as I can and would greatly
appreciate general comments.

I am trying to write a small survey application, for that I created a
class WASurvey:

WAComponent subclass: #WASurvey
    instanceVariableNames: 'survey questionsPerPage currentPage'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'questionaire'

survey is a list of questions, questionsPerPage/currentPage should be
obvious.

The component is rendered like that:

renderContentOn: html
    | first last |
    first := currentPage - 1 * questionsPerPage + 1.
    last := first + questionsPerPage - 1.
    html heading: survey title.
    html text: currentPage; text: '/'; text: self pageCount.
    html form: [
        survey questions from:first to:last do: [ :question | question
renderContentOn: html ].
        html submitButton text: 'Previous Page';
                              callback: [ currentPage := currentPage - 1 ];
                              disabled: currentPage = 1.
        html submitButton text: 'Next Page';
                              callback: [ currentPage := currentPage + 1 ];
                              disabled: currentPage = self pageCount.
    ]

Now I created several Question classes that implement renderContentOn:
aCanvas

MultiChoiceQuestion>>renderContentOn: html
super renderContentOn: html.
    answers doWithIndex: [ :answer :index |
                                   | current |
                                   current := html checkbox value:
(values includes: index).
                                   html text: answer.
                             ]

SingleChoice>>renderContentOn: html
super renderContentOn: html.
    html radioGroup: [ :group |
        answers doWithIndex: [ :e :index |
                                     | current |
                                     current := group radioButton.
                                     value = index ifTrue: [ current
beChecked ].
                                     html text: e ]
    ]


I currently get a MessageNotUnderstood error that seems to be related to
the Checkbox components in MultiChoice questions. My problem is, that
the StackTrace is very deep, and only shows Seaside internals. What
would now be the general approach to trace down that issue?

Thanks for your help,

Felix

Here is the top of the Stack Trace:

   1.

      thisContext
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&4>
          UndefinedObject(Object)>>doesNotUnderstand: #value:
      self
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&5>
          nil
      aMessage
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&6>
          value: nil

   2.

      thisContext
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&7>
          [] in WACheckboxTag>>after {[callback value: value. value :=
          false]}
      self
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&8>
          a WACheckboxTag

   3.

      thisContext
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&9>
          BlockContext>>valueWithPossibleArgument:
      self
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&10>
          [] in WACheckboxTag>>after {[callback value: value. value :=
          false]}
      anArg
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&11>
          ''

   4.

      thisContext
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&12>
          WAValueCallback>>evaluateWithArgument:
      self
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&13>
          a WAValueCallback
      anObject
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&14>
          ''

   5.

      thisContext
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&15>
          WAValueCallback(WACallback)>>evaluateWithField:
      self
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&16>
          a WAValueCallback
      anObject
      <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&17>
          ''


_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Problem with Checkboxes

Julian Fitzell-3
So in the top frame of the stack you can see that the error is #value:
being called on nil. If you look at the second frame, you can see that
#value is being called on the instance variable 'callback', so clearly
that must be nil. And sure enough, if you look at your rendering code,
you have not set a callback for your checkboxes (if you don't set a
callback, you won't get the value submitted by the user).

If you add a call to #callback: when rendering your checkbox the
problem should go away. That said, obviously the framework should
handle the case of no callback more gracefully. I created the
following issue: http://code.google.com/p/seaside/issues/detail?id=106

Welcome to Seaside,

Julian

On Sun, Jul 20, 2008 at 7:46 AM, Felix Dorner <[hidden email]> wrote:

> Hey,
>
> first, I am a Squeak/Smalltalk newcomer, so please forgive me if I make an
> obvious error. I also give as much detail as I can and would greatly
> appreciate general comments.
>
> I am trying to write a small survey application, for that I created a class
> WASurvey:
>
> WAComponent subclass: #WASurvey
>   instanceVariableNames: 'survey questionsPerPage currentPage'
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'questionaire'
>
> survey is a list of questions, questionsPerPage/currentPage should be
> obvious.
>
> The component is rendered like that:
>
> renderContentOn: html
>   | first last |
>   first := currentPage - 1 * questionsPerPage + 1.
>   last := first + questionsPerPage - 1.
>   html heading: survey title.
>   html text: currentPage; text: '/'; text: self pageCount.
>   html form: [
>       survey questions from:first to:last do: [ :question | question
> renderContentOn: html ].
>       html submitButton text: 'Previous Page';
>                             callback: [ currentPage := currentPage - 1 ];
>                             disabled: currentPage = 1.
>       html submitButton text: 'Next Page';
>                             callback: [ currentPage := currentPage + 1 ];
>                             disabled: currentPage = self pageCount.
>   ]
>
> Now I created several Question classes that implement renderContentOn:
> aCanvas
>
> MultiChoiceQuestion>>renderContentOn: html
> super renderContentOn: html.
>   answers doWithIndex: [ :answer :index |
>                                  | current |
>                                  current := html checkbox value: (values
> includes: index).
>                                  html text: answer.
>                            ]
>
> SingleChoice>>renderContentOn: html
> super renderContentOn: html.
>   html radioGroup: [ :group |
>       answers doWithIndex: [ :e :index |
>                                    | current |
>                                    current := group radioButton.
>                                    value = index ifTrue: [ current beChecked
> ].
>                                    html text: e ]
>   ]
>
>
> I currently get a MessageNotUnderstood error that seems to be related to the
> Checkbox components in MultiChoice questions. My problem is, that the
> StackTrace is very deep, and only shows Seaside internals. What would now be
> the general approach to trace down that issue?
>
> Thanks for your help,
>
> Felix
>
> Here is the top of the Stack Trace:
>
>  1.
>
>     thisContext
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&4>
>         UndefinedObject(Object)>>doesNotUnderstand: #value:
>     self
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&5>
>         nil
>     aMessage
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&6>
>         value: nil
>
>  2.
>
>     thisContext
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&7>
>         [] in WACheckboxTag>>after {[callback value: value. value :=
>         false]}
>     self
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&8>
>         a WACheckboxTag
>
>  3.
>
>     thisContext
>     <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&9>
>         BlockContext>>valueWithPossibleArgument:
>     self
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&10>
>         [] in WACheckboxTag>>after {[callback value: value. value :=
>         false]}
>     anArg
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&11>
>         ''
>
>  4.
>
>     thisContext
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&12>
>         WAValueCallback>>evaluateWithArgument:
>     self
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&13>
>         a WAValueCallback
>     anObject
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&14>
>         ''
>
>  5.
>
>     thisContext
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&15>
>         WAValueCallback(WACallback)>>evaluateWithField:
>     self
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&16>
>         a WAValueCallback
>     anObject
>
> <http://127.0.0.1:8080/seaside/survey?_s=TGzVOKjnplpRtUnu&_k=VXYqwquh&17>
>         ''
>
>
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Problem with Checkboxes

cedreek
In reply to this post by Felix Dorner
> WAComponent subclass: #WASurvey

>   instanceVariableNames: 'survey questionsPerPage currentPage'
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'questionaire'
>
> survey is a list of questions, questionsPerPage/currentPage should be
> obvious.
>
> The component is rendered like that:
>
> renderContentOn: html
>   | first last |
>   first := currentPage - 1 * questionsPerPage + 1.
>   last := first + questionsPerPage - 1.
>   html heading: survey title.
>   html text: currentPage; text: '/'; text: self pageCount.
>   html form: [
>       survey questions from:first to:last do: [ :question | question
> renderContentOn: html ].
another remark:

[:question | html render: question]

"It's important that you use #render:, rather than directly calling
the #renderContentOn: method of the subcomponent. " if question is a
component (then don't forget to use children).

If Question is not a subclass of WAComponent, then implement renderOn:
instead of renderContentOn:

hth

Cédrick

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Problem with Checkboxes

Felix Dorner
In reply to this post by Julian Fitzell-3
Hi Julien,

> If you add a call to #callback: when rendering your checkbox the
> problem should go away. That said, obviously the framework should
> handle the case of no callback more gracefully. I created the
> following issue: http://code.google.com/p/seaside/issues/detail?id=106
>  

Great. I simply assumed that not setting a callback would not break
anything. (I didn't set a callback for the radio button (group) either,
and didn't have problems there). I simply wanted to add the callbacks in
a second step, and definitely agree that a nil callback shouldn't cause
a problem.

Thanks for helping,
Felix
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Problem with Checkboxes

Felix Dorner
In reply to this post by cedreek
Hi Cdric,

>>   html form: [
>>       survey questions from:first to:last do: [ :question | question
>> renderContentOn: html ].
>>    
>
> another remark:
>
> [:question | html render: question]
>
> "It's important that you use #render:, rather than directly calling
> the #renderContentOn: method of the subcomponent. " if question is a
> component (then don't forget to use children).
>  
Question is actually not a WAComponent subclass. Anyway, thanks for the
advice, I'll keep that in mind.

> If Question is not a subclass of WAComponent, then implement renderOn:
> instead of renderContentOn:
>  
Why? Simply to avoid confusion?

Thanks,
Felix
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Problem with Checkboxes

Julian Fitzell-3
On Mon, Jul 21, 2008 at 11:04 PM, Felix Dorner <[hidden email]> wrote:
>> If Question is not a subclass of WAComponent, then implement renderOn:
>> instead of renderContentOn:
>>
>
> Why? Simply to avoid confusion?

Because then you can pass it to "html render:" :)

Any object that is renderable should implement #renderOn:. WAComponent
implement that to do a bunch of other stuff and then calls
#renderContentOn: for its subclasses.

Obviously if you're the only one using your class, you can call it
#fooBarBaz: if you feel like, but if you implement #renderOn: you can
do:

html render: aCollectionOfQuestions

or:

html div id: 'foo'; with: aQuestion

And yes, it's just sort of standard I guess.

Julian
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside