[Seaside] build drop-down select list when clicked

Paul DeBruicker pdebruic at gmail.com
Fri Mar 1 00:52:55 UTC 2013


Hi Bob,

zI looked a little bit online and didn't see anything where you can use
'click' or 'mousedown' and have the options displayed in one click.
Changing the event to 'mouseover' seems to give the best response on
both Chrome and IE, but the data is loaded when people may not have any
intention of changing the value.  If you use 'focus' on Chrome it loads
the data and displays it with on click.  With 'focus' on IE you still
need two clicks.  Also this doesn't work at all on iOS, where you need
two clicks no matter what.

Firefox works with all of ('click' 'mousedown' 'mouseover' 'focus) .

So now the JS that loads the list of options is this:

MyClass>>loadTimeZoneListOnceFor: anId on: html
	^ (html jQuery id: anId)
		one: 'focus'
		do:
			((html jQuery ajax
				html: [ :h | self renderTimeZoneList: h ];
				async: false;
				onSuccess: (self loadOptionsInto: anId on: html)) asFunction:
#('event'))


Hope this helps

Paul



On 02/28/2013 01:03 PM, Paul DeBruicker wrote:
> Hi Bob,
> 
> Ooooh I had not noticed that.  I tested on Firefox on Linux with Seaside
> 3.0.7 on pharo 1.4 and it worked with one click only.  With Chrome it
> works with two unreliably so I'll have to look into that.  On Firefox
> the list populates while still open after the first click but there is a
> slight delay between when the list opens with just one value and the
> list is populated with all of the items.
> 
> Thanks for the idea of loading the select only when necessary.  It had
> been annoying to know that sometimes 381 timezones, 253 currencies, and
> 249 countries were being loaded into a page and never looked at.
> 
> On Windows 8 it seems to work as is in Firefox but not Chrome or IE9.
> I'll take a look soon at fixing it for other browsers
> 
> Paul
> 
> 
> 
> 
> On 02/28/2013 12:25 PM, bobn at rogers.com wrote:
>> Paul,
>> Thanks for all the work. This is not something I would have figured out
>> on my own.
>>
>> In my example the list is now rendered after the first click and
>> displayed on the second click, so from the user's point of view two
>> clicks are needed to get the rendered list.  That kind of makes sense,
>> since the first click triggers the 'click' event to build the selection
>> list. Would there be a way to have the list displayed after build,
>> rather than waiting for the second click?
>>
>> Are you seeing the same click sequence? If not I'll go through my code
>> more carefully.
>>
>> I've tried the code first in VW 7.7.1 with Seaside 3.0 and again in the
>> current Pharo one-click image with Seaside 3.0.7
>>
>> Thanks again,
>> Bob
>>
>>
>> ------------------------------------------------------------------------
>> *From:* Paul DeBruicker <pdebruic at gmail.com>
>> *To:* bobn at rogers.com; Seaside - general discussion
>> <seaside at lists.squeakfoundation.org>
>> *Sent:* Thursday, February 28, 2013 12:46:52 PM
>> *Subject:* Re: [Seaside] build drop-down select list when clicked
>>
>> I figured out the rest of it. The original callback from the select
>> doesn't do anything with the value from the expanded list.  If you add a
>> hiddenInput after the select and serialize that with the selected value
>> of the select when the select changes, then things work nicely.
>>
>> So change the renderSelect: method to
>>
>> MyClass>>renderSelect:html
>>     html select
>>         id: html lastId;
>>         list: (Array with: self timeZone key);
>>         script: (self loadSelectListOnceFor: html lastId on: html);
>>         onChange: (self serializeHiddenInput: 'tzId' withValueFrom: html
>> lastId on: html);
>>         selected: self timeZone key
>>        
>>     html hiddenInput
>>         id: 'tzId';
>>         callback: [ :val | self timeZone: (Timezone at: val) ].
>>
>>
>> and add
>>
>> MyClass>>serializeHiddenInput: anId withValueFrom: selectId on: html
>>     ^ ((html jQuery id: anId) value: ((html jQuery id: selectId) find:
>> 'option:selected') contents text)
>>         , (html jQuery ajax serialize: (html jQuery id: anId))
>>
>>
>>
>>
>> On 02/27/2013 09:24 PM, Paul DeBruicker wrote:
>>> I haven't figured out how to get the browser to recognize the changed
>>> value for the select, so the callback get the updated value if the user
>>> changes their choice.  Probably need to clone the select after adding
>>> the options then replace the original with the new version.  I'm not
>>> sure yet.  But it would be handy to know.  So it needs some work but
>>> what I outline below loads a bunch of <option> tags into the <select>
>>> and serializes the select onChange: to the callback.  Just not the value
>>> the user chooses yet.
>>>
>>>
>>> To load new select items into the select menu you need to create the
>>> <option> tags that comprise the select list and then stick them in there.
>>>
>>> Assuming your list is the Chronos list of Timezone keys you could do it
>>> like this:
>>>
>>> MyClass>>renderSelect: html
>>>     html select
>>>         id: html lastId;
>>>         list: (Array with: self timeZone key);
>>>         script: (self loadSelectListOnce: html);
>>>         onChange: html jQuery post serializeThis;
>>>         selected: self timeZone key;
>>>         callback: [ :val | self timeZone: (Timezone at: val) ].
>>>
>>> MyClass>>loadSelectListOnceFor: anId on: html
>>>     ^ (html jQuery id: anId)
>>>         one: 'click'
>>>         do:
>>>             (html jQuery ajax
>>>                 html: [ :h | self renderTimeZoneList: h ];   
>>>                 onSuccess: (self loadOptionsInto: anId on: html))
>>>
>>>
>>> MyClass>>renderTimeZoneList:html
>>>     Timezone allRegisteredKeys asSortedCollection
>>>         doWithIndex: [ :eachTimeZone :index |
>>>             html option
>>>                 value: index + 1;
>>>                 with: eachTimeZone ]
>>>
>>> MyClass>>loadOptionsInto: anId on: html
>>>     ^ (JSStream
>>>         on:'$("#' , anId ,' option:first").after(data)') asFunction:
>> #('data'
>>> 'status' 'jqXhr')
>>>
>>>
>>>
>>> Good luck
>>>
>>>
>>> Paul
>>>
>>>
>>>
>>> On 02/27/2013 08:52 AM, bobn at rogers.com <mailto:bobn at rogers.com> wrote:
>>>> Hello,
>>>> Is there a way to build the 'select' list when the drop-down button is
>>>> pressed?
>>>>
>>>> Our application uses drop-down lists for options that have a short list
>>>> to pick from (longer lists use a lightbox list prompt).
>>>> In most cases, the list of values is not needed, since the user is not
>>>> going to change the selection.
>>>> So, I'd prefer to defer getting the list to when the user asks for it
>>>> (round trip time to get the list is less than 50ms).
>>>> Getting the data is not expensive, but including it in the initial data
>>>> retrieval for the full view is a coding hassle.
>>>>
>>>> I've tried various #onClick: code, like loading a new rendering of the
>>>> select component with the list populated, but no luck.
>>>>
>>>> i.e.
>>>> html select
>>>> onClick: ("get the list and display it");
>>>> list: (Array with: initialSelection); "for initial display"
>>>> selected: initialSelection;
>>>> callback: [:value | ... ]
>>>> Thanks for any help,
>>>> Bob Nemec
>>>>
>>>>
>>>> _______________________________________________
>>>> seaside mailing list
>>>> seaside at lists.squeakfoundation.org
>> <mailto:seaside at lists.squeakfoundation.org>
>>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>>>>
>>>
>>
>>
>>
> 



More information about the seaside mailing list