[Seaside] ajax onBlur callback with load html: [...]

Johan Brichau johan at inceptive.be
Thu Sep 16 08:30:32 UTC 2021


Hi Bob,

The JQAjax#callback being nil is normal if there is no “primary” callback. This is what you see: the Ajax callback registered on the onblur event (using JQAjax>>callback:value:, which is a secondary callback) has no primary callback block. The Ajax callback registered on the onClick event only has a primary callback block. This is fine and works as intended.

The problem you are seeing is on the client side and all about browser events: the click on the button triggers the browser’s onBlur event first, which triggers the Seaside callback for the blur, which triggers another callback to replace the html snippet including the button you pressed and the input field that triggered the blur. The html load replaces the button you are clicking….  Now, depending on the speed of events and callbacks, the html (including your button) will be replaced before or after the browser can send the onClick event to the button, which would trigger the Seaside callback for the button. 

In addition, there is the ordering of events in the browser that makes this very complicated to think about: an onClick is only fired after a mouseDown and a mouseUp and an onBlur is sent because of the mouseDown on the button.

If you include a 100ms delay in the response of the Seaside callback, you are effectively making it possible for the browser to trigger the onClick event on the original button as well.
Without this delay, the browser will have sent the mouseDown event to the button but the button will be replaced before the browser is able to trigger a mouseUp and an onClick. 
Because the new button is not the one you clicked, it will not have it’s onclick handler fired.

If you do not replace the button while rendering the Ajax update, it works as well.

Doing some console logging can be helpful to debug such issues. See code below and try with or without the delay commented out.

	html textInput 
		value: self stringValue; 
		onBlur: ((JSStream on: 'console.log(''onblur'')'),
				(html jQuery ajax callback: [:value | 
						self stringValue: value. (Delay forMilliseconds: 100) wait.
						Transcript cr; show: Time now displayString  , ' value: ' , value asString]
				value: (html jQuery this value); 
			onSuccess: ((JSStream on: 'console.log(''contentload-onblur'')'),(self renderContentLoadDivOn: html) ))).
	html break; break. 
	html button 
		onClick: ( (JSStream on: 'console.log(''onclick'')'),
				(html jQuery ajax callback: [
					self stringValue: self stringValue , '+'.
					Transcript cr; show: Time now displayString , ' button: ' , self stringValue asString];
			onSuccess: ((JSStream on: 'console.log(''contentload-onclick'')'),(self renderContentLoadDivOn: html) )));
		with: 'Press’.


Hope this helps,
Johan

> On 15 Sep 2021, at 23:40, Bob Nemec <bobn at rogers.com> wrote:
> 
> 
> Wow, this is proving to be challenge. The problem is that in JQAjax>>processCallback #callback is sometimes nil. When it is, the button press callback is not processed and the button has to be pressed again. But, if the onBlur of the text input field has a 100ms delay, the #callback value is not nil and the button callback works all the time. Which is especially frustrating because adding diagnostic traces slows down the first callback enough for things to work. 
> 
> This is pushing me to the edge of my Seaside knowledge. I will try this same example with the latest Seaside code on Pharo. If it works, I'll work on getting us updated (we develop in VW but deploy on GS). If not, I'll have a nice packaged problem to raise on the Seaside part of the Pharo Discord channel. 
> 
> Bob
> 
> On Tuesday, September 14, 2021, 08:58:31 a.m. EDT, Karsten Kusche <karsten at heeg.de> wrote:
> 
> 
> Hi Bob,
> 
>> We use onBlur to get the data from input fields and to refresh the state of the view. The problem comes up if a button is included in the refresh: the ajax callback from that button is not handled (which makes sense due to the jQuery load), so the user has to press the button again.
> 
> I’d say it actually doesn’t make any sense. Your callbacks are registered, they should work regardless. You could use the Web-Browser’s network tool/profiler to see which event-handler is fired and what network requests are made. Maybe one of the requests doesn’t come through correctly and you can investigate that further. 
> 
> Some things you should also consider: when you use render HTML-Snippets that contain Javascript (like new click-handlers), Seaside will automatically add these inside a <script>-tag at the end of this snippet and inject that into your DOM at the place where you inject the HTML. In your case you should have a <script>-tag at the end of your #testDiv. 
> 
> I’m not entirely sure about this, but iirc replacing that script-tag will also remove all event-handlers that were registered as part of this tag. On the other hand replacing the <script> also means replacing the <button> so you should still have a working button in any case… like i said, it doesn’t really make much sense.
> 
> Karsten
> 
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/seaside/attachments/20210916/136a44da/attachment-0001.html>


More information about the seaside mailing list