Jumping/Scrolling in Seaside built web pages

12 views
Skip to first unread message

Louis LaBrunda

unread,
Oct 8, 2025, 11:09:08 AM (5 days ago) Oct 8
to VAST Community Forum
Hi Group,

I recently noticed that the Jumping/Scrolling in my Seaside built web pages stopped working.  For all I know it may have stopped working a long time ago.  I thought some of you may be interested in how it works and what broke.

The two programs I have recently been working on are my Raspberry Pi programs.  They both have two parts.  One part is the code that does the job of the program, in this case, drawing the clock and the calendar and controlling relays that turn things on and off like my lawn sprinkler system.  The other part is a web server that allows me to use a web browser to change the settings.

Other than a login page and a small page that allows me to directly control things like turn the sprinklers on outside their normal time, there is a large settings page.  Sure, I could break it up into many pages but I don't want to.  Instead I use hidden anchors.  I tell the web browser to go to a given anchor when the user adds/deletes something like a timed event in the relay control program or a calendar event in the clock program.  For things like the user saving the settings and wanting to return where he was on the page, the browser "scrollTo()" function is used.

Here is how it is all set up:

First in the #updateRoot: method, add the two lines:

updateRoot: anHtmlRoot
"Add some things to the head portion."

...
anHtmlRoot bodyAttributes at: 'onscroll' put: 'document.getElementById(''ScrollPosition'').value = Math.floor(window.scrollY)'.
anHtmlRoot htmlAttributes at: 'style' put: 'scroll-behavior: smooth;'.

The first line is the work horse.  It is one thing about how web browsers work that I really like.  It tells the browser to put the value of the window Y scroll position in the element with the id 'ScrollPosition' when the onscroll event triggers.  If this doesn't work right, scrolling to a point doesn't work.  Note, if the user scales the page at something other than 100%, the value returned by window.scrollY can be a real number.  Using the Math.floor() function keeps it an integer.

Next, in a subclass of WAComponent, that I subclass all my other components, goes the method below.  The method is only called by components that makeup the bulk of a web page.

renderScriptForScrollPositionOrJumpSpotOn: html
" Load the script for the scrolling to jumpSpot or the position from the top of the page in the browser."
| scrollScript |

scrollScript := self jumpSpot notEmpty
ifTrue: [JSScript new goto: ('#', jumpSpot)]
ifFalse: [JSScript new add: (JSStream new nextPutAll: ('window.scrollTo(0, %1);' bindWith: self scrollPositionAsString))].
html document addLoadScript: scrollScript.
jumpSpot := ''.

html textInput id: 'ScrollPosition'; class: theSession settings scrollElementCSS; on: #scrollPosition of: self.

The first part decides if we want to goto an anchor or to a scroll point and adds the appropriate JSScript to the onload script.  The second part, adds a text input field with the same id used in the root update code above.  What I added recently is the ability to set the CSS classes from the settings (see below).  That helped me to debug the problem.

See below for three methods that are also needed:

The last part of the last line above: 

...on: #scrollPosition of: self.

is a really nice feature of Seaside.  It requires setter/getter methods with matching names.  Most of us do that all the time anyway, so it is no big deal.  It tells Seaside to get the value from the getter method (it is smart enough to convert numbers to strings for the web output).  On return from the browser, it uses the setter method to put the value where it belongs.  You need to convert strings to numbers/dates/times or whatever.  You don't need to parse what comes back from the browser, Seaside does all that.  That is why a guy like me, who knows very little HTML, can make more than adequate web applications.

Back to the problem.  Now that I could set the CSS class for the input field, I could make it visible and see that the onscroll event catching was working.  Therefor telling the browser where to scroll to was failing.  The old code was using window.scrollTo(%1) where the %1 was replaced with the scroll point.  At my age I guess I can't be sure of anything nut I'm sure that use to work.  I guess the function got changed to require two parameters, x and y values.  Changing to window.scrollTo(0, %1) solved the problem.

scrollPosition
"Answer scrollPosition, the position of the top of the page in in the browser."

scrollPosition isNil ifTrue: [scrollPosition := 0].
^scrollPosition.

scrollPosition: anIntOrString
"Set scrollPosition, the position of the top of the page in in the browser."

scrollPosition := anIntOrString asNumber.

scrollPositionAsString
"Answer scrollPosition as a string, the position of the top of the page in in the browser."

^self scrollPosition printString.


CSS:

.Hidden {
 display:none;
}
.Number {
 text-align:right;
}
.ShortInput {
 width:50pt;
 margin-top:5pt;
 margin-left:3pt;
 margin-right:1pt;
 margin-bottom:5pt;
}
.HoverLowerRight4 {
 position: fixed; /* Fixed/sticky position */
 bottom: 140px; /* Place the button at the bottom of the page */
 right: 30px; /* Place the button 30px from the right */
 z-index: 999; /* Make sure it does not overlap */
}

Reply all
Reply to author
Forward
0 new messages