[Seaside][ShoreComponents] DatePicker discussion (improve reusability of composites)

Michel Bany m.bany at wanadoo.fr
Mon Sep 26 08:29:10 CEST 2005

>> 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.
> <snip>
>> 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.
> I'm concerned about the performance implications of signalling a  
> notification on every single openTag:.  At least in Squeak, I think  
> that will add a ton of overhead.
> If you give your elements ids, couldn't you do something like this?   
> (Not sure if my JS is correct here).
> html datePickerOn: #dateScheduled of: self.
> html script: 'document.getElementById("someElement").onclick =  
> function() {....}'.
Yes, this would be ok if you know the id of the element.

In the case of the Date Picker, there are nearly 50 html elements 
generated and only the first one is given a css id.
Even if the Date Picker was assigning css ids to every html elements, I 
would need a way to get those ids.
Something like this  ?

    ids := html assignedCssIdsDuring:
        [html datePickerOn: #dateScheduled of: self].

For my project, I need to supply an onclick handler only for the 
calendar cells, therefore I would need
something to sort out which ids are for the calendar cells.

And even if I would know very precisely which ids are for the calendar 
cells, coding the script elements
for assigning the onclick handlers would replace the handlers that are 
established by the Date Picker
widget when I want to add to them.

So I come with another suggestion.

This would be to enhance the Date Picker so that it raises 
TagNotification from locations
that are appropriate to ensure better reusability and not leaking too 
much knowledge
from the widget.

drawDay: day editBox: id printFormat: printFormat

    self attributes at: 'onClick' put: 'datePickerSetDate(''', id, ''', 
''',  (day printFormat: printFormat), ''') '.
   TagNotification raiseFor: #CalendarCell withRenderer: self.
    self tableData: [
        self text: day dayOfMonth .]

This would allow me to write :

       datePickerOn: #dateScheduled
       of: self]

 on: TagNotification do:
       [:n |
       n for == #CalendarCell ifTrue:
           [n renderer attributes at: 'onclick' append: 'my javascript'].
        n resume]

In the TagNotification handler, you may want to access the html 
attributes to find what
attributes were already installed, so we would probably need new methods 
    html cssId
    html cssClass
    html attributeAt:

This could also be generalized as an additional responsibility of all 
composite widgets like this one :

dateInputWithValue: aDate callback: aBlock
   TagNotification raiseFor: #Month withRenderer: self.
   TagNotification raiseFor: #Day withRenderer: self.
   TagNotification raiseFor: #Year withRenderer: self.
   TagNotification raiseFor: #HiddenCallback withRenderer: self.

More information about the Seaside mailing list