[Seaside] AutoCompleter

Edward Stow ed.stow at gmail.com
Fri Apr 18 14:35:51 UTC 2008


On Fri, Apr 18, 2008 at 5:13 PM, Lukas Renggli <renggli at gmail.com> wrote:
> 1. You need to store the autocompleter object in a JavaScript variable.
>
>  2. Then in the onSelected: event you can access the method
>  selectedIndex and serialize it to the client together with the
>  contents of the form element.
>
>  That looks somehow like this (as usual I haven't tested):
>
>
>    html div
>       class: 'autocomplete';
>       script: (html autocompleter
>          element: 'text';
>          assignTo: 'auto';
>          onSelected: (html request
>             callback: [ :value | index := value asInteger ]
>                value: (html autocompleter
>                    alias: 'auto';
>                    selectedIndex);
>             triggerFormElement: 'text')
>
Thanks -- this did not work and because I cannot mentally grasp how
this works ... I have concocted a different solution that includes a
unique identifier from each item displayed. The steps are:

1.  Created a subclass of WAUnOrderedListTag and reimplement:

TrUnOrderedEventListTag>>renderListItem:labelled:
	canvas listItem
		id: anObject eventId;  <-- my object has a unique string id
        ... remainder deleted.

This step would be unnecessary if  rendering of the id value were
pluggable such as with #labels:

2.  MyComponent>renderContentOn: is pretty straight forward now:

MyComponent>renderContentOn: html
	html paragraph: [
		html textInput
			id: 'text';
			value: text;
			callback: [ :value | text := value ].
		html div
			class: 'autocomplete';
			script: (html autocompleter
				element: 'text';
				onSelected: (self selectionHandlerOn: html );
				on: #renderListOn: of: self) ]

3.  Write a fuction such that the AJAX.Autocompleter
afterUpdateElement event handler is defined with two arguments - the
text and lineItem values.  Return in the function body the lineItem id
value.

MyComponent>selectionHandlerOn: html
	^(html request
		callback: [:value | value inspect ]
		value: (SUStream new nextPutAll: 'li.id'))
                    asFunction arguments: #('text' 'li')

I'm sure there is a better way to write the request function body.  I
think its a disadvantage to know javascript ... as it always seems
much easier to write the expected output javascript than it is to
write the javascript generation in Smalltalk.

4.  Include the #labels: block in #renderListOn: .  Render the
      items is a collection of my domain objects.

MyComponent>>renderListOn:
        .... item generation removed ...
	(html brush: TrUnOrderedEventListTag new)
		labels: [:each | each eventName];
		list: (items first: (items size min: 10))

To my mind -- this may have been the long way round to the solution
but now each step does not appear to depend on blackmagic.

-- 

Edward Stow


More information about the seaside mailing list