[Seaside][ShoreComponents] DatePicker discussion

Michel Bany m.bany at wanadoo.fr
Sat Sep 24 15:32:45 CEST 2005

I ported the Shore date picker widget to VisualWorks and I wanted
to discuss some of the difficulties I had.

1) The Shore date picker is based upon the Squeak version of the Date
class. The VisualWorks version of the Date is somewhat incompatible
and I had to convert the VisualWork Date objects to Squeak.Date objects
(for those who do not know, the VisualWorks version of Seaside includes
a port of the Squeak chronology subsystem in a different namespace).

For one component in my project, I included a date picker inside a form
and I wanted the form to be submitted as soon as a date was selected in the
calendar. The Shore date picker widget is a composite, it includes a text
input, an image, some links and a table where the cells are clickable. Each
cell has the responsibility to place its value into the text input when 
it is clicked,
using the onclick= attribute. In order to submit the form as well, I need to
add something to the onclick attribute. There I had two difficulties:

2) Addding to the onclick attribute. Currently, coding something like this
    html attributes at: 'onclick' put: 'some javascript'.
    html attributes at: 'onclick' put: 'some more javascript'.
generates the onclick attribute twice in the html tag, making the response
uncompliant to xhtml.
Is that a correct behavior ? Should we modify at:put: so that it accumulates
all the supplied values into only one attribute ? Should we modify at:put:
so that it replaces any value that was supplied before for the attribute ?
Accumulating makes sense only for some attribute like style, onclick, 
etc. Replacing makes sense in most cases. What about case sensitivity 
for the
attribute name ? What about compatibility ? and do on.
Therefore I had the idea to implement this
    html attributes at: 'onclick' append: 'some javascript'.
    html attributes at: 'onclick' append: 'some more javascript'.
The implementation is equivalent to at:put: when the attribute was
never used before. It concatenates the old value with the argument,
inserting a semi-colon otherwise.
In my opinion, a lot of thinking is still needed there.

3) Even with the above issue somewhat solved with at:append: we need
a technique for telling the date picker component that we want to
append something to the onclick attribute of the calendar cells. The problem
is that sometimes we want to submit the form, sometimes we do not want that.
I tried the solution of adding a block parameter to #datePickerOn:of: which
became #datePickerOn:of:onClick: and propagating the additional parameter
down to

drawDay: day editBox: id printFormat: printFormat onClick: clickBlock
    self attributes at: 'onClick' put: 'datePickerSetDate(''', id, ''', 
''',  (day printFormat: printFormat), ''') '.
    clickBlock value: self.
    self tableData: [
        self text: day dayOfMonth .]

allowing me to code

        datePickerOn: #dateScheduled
        of: self
            [:h | h attributes at: 'onclick' append: 'my javascript']

That works, but I find it completely ugly. Therefore I am coming with a 
second suggestion.
My suggestion is to add a notification in #openTag: before opening the 
html tag

openTag: aString
    TagNotification raiseRenderer: self tagName: aString.
    self document openTag: aString attributes: self attributes.
    attributeBuffer := nil.

allowing me to code

        datePickerOn: #dateScheduled
        of: self]

  on: TagNotification do:
        [:n |
        n tagName = 'td' ifTrue:
            [:h | n renderer attributes at: 'onclick' append: 'my 

This would help for all the widgets that are composites like checkboxes, 

Thank you for your patience reading so much,

More information about the Seaside mailing list