If you find yourself at the bottom of a long page, this widget will add functionality to scroll to the top with a click of a button.
Place the widget anywhere on the desired page.
What the button looks like off to the side of text:
On top of text:
The configuration of the widget:
Version 11:
<scriptedContentFragments> <scriptedContentFragment name="${resource:Scroll_to_Top_Name}" version="11.1.1.9982" description="${resource:Scroll_to_Top_Description}" instanceIdentifier="0a7c2ba6ba6f44ac8704a19e88d09d74" theme="" isCacheable="false" varyCacheByUser="false" showHeaderByDefault="false" cssClass="top-button" lastModified="2021-05-09 20:05:25Z"> <contentScript language="Velocity"><![CDATA[$core_v2_page.AddLink('stylesheet', $core_v2_widget.GetExecutedFileUrl('style.less'), "%{ Position = 'AfterTheme' }") <div class="top-button"> <ul> <li> ##"Button" for scroll to top (anchor not button because actual button causes POST resend on reload) <a onclick="topFunction()" id="topBtn" class="prepend-icon up-open-big">$core_v2_language.GetResource('Top')</a> </li> </ul> </div> #registerEndOfPageHtml() <script type="text/javascript"> var topButton = document.getElementById("topBtn"); //Find the link on page to control disply var bodyHeight = document.body.scrollHeight; //Get height of page (Safari) var elemHeight = document.documentElement.scrollHeight; //Get height of page (all other browsers) var hPercent = $core_v2_widget.GetIntValue('sttPercent', 25); //Get the percent of page to be above the to from widget configuration //Initialize dynamicScrollFunction variables var shown = false; var storedBodyHeight = 0; var storedElemHeight = 0; //Check if we're locking the button on at height even if page changes size dynamically var dynamicScrolling = "$core_v2_widget.GetBoolValue('dynScroll', false)"; //stored as string because GetBoolValue returns in Title Case dynamicScrolling = dynamicScrolling.toLowerCase(); //normalize to javascript bool lowercase (still a string though) //Register which function to use when scrolling //String comparison because GetBoolValue returns in Title Case if (dynamicScrolling == "false"){ window.onscroll = function() {scrollFunction()}; } if (dynamicScrolling == "true"){ window.onscroll = function() {dynamicScrollFunction()}; } //Standard scrolling function (always recalculates when to show/hide button on every scroll action) function scrollFunction() { if (document.body.scrollTop > (bodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (elemHeight * (hPercent/100))) { topButton.style.display = "block"; //Show the button } else { topButton.style.display = "none"; //Hide the button } } //Stop recalculating page size function once the button is shown (remove comments on lines to reset when the user scrolls manually above it again) function dynamicScrollFunction(){ if (!shown) { //Check to see if button has not been shown bodyHeight = document.body.scrollHeight; //Update variables elemHeight = document.documentElement.scrollHeight; //Update variables if (document.body.scrollTop > (bodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (elemHeight * (hPercent/100))) { topButton.style.display = "block"; //Show the button storedBodyHeight = bodyHeight; //Lock in bodyHeight storedElemHeight = elemHeight; //Lock in elemHeight shown = true; //Flag that button has been shown } } else if (shown){ //Button has been shown once, always show again at same scroll point if (document.body.scrollTop > (storedBodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (storedElemHeight * (hPercent/100) )) { topButton.style.display = "block"; //Keep showing the button as long as current position is over locked in show height } else{ topButton.style.display = "none"; //Hide the button //shown = false; //Remove flag for has been shown to start calculations over } } } //What the link does when clicked (scrolls back to the top of the page) function topFunction() { document.body.scrollTop = 0; //Safari document.documentElement.scrollTop = 0; //All of the rest topButton.style.display = "none"; //Hide the button //For resetting dynamicScrollFunction: //shown = false; //storedBodyHeight = 0; //storedElemHeight = 0; } </script> #end]]></contentScript> <headerScript language="Velocity"><![CDATA[$core_v2_widget.ApplyTokens($core_v2_widget.GetStringValue('fragmentHeader', '${resource:Scroll_to_Top_Name}'))]]></headerScript> <configuration><![CDATA[<propertyGroup id="options" labelResourceName="Options"> <property id="fragmentHeader" labelResourceName="Title" defaultValue="${resource:Scroll_to_Top_Name}" dataType="String" template="core_v2_tokenizedString" /> <property id="sttPercent" labelResourceName="Scroll_to_Top_Percent_Name" descriptionResourceName="Scroll_to_Top_Percent_Description" defaultValue="25" dataType="int" template="int" presentationDivisor="1"> <propertyRule name="minmax" min="1" max="80" /> </property> <property id="dynScroll" labelResourceName="Scroll_to_Top_Dynamic_Name" descriptionResourceName="Scroll_to_Top_Dynamic_Description" defaultValue="false" dataType="bool" template="bool" /> </propertyGroup>]]></configuration> <languageResources><![CDATA[<language key="en-us"> <resource name="Scroll_to_Top_Description">Creates a button that scrolls to the top of the page</resource> <resource name="Scroll_to_Top_Dynamic_Description">Hold page size calculation after button is shown (keeps button visible at same point on manual scroll up until hidden when page size grows dynamically)</resource> <resource name="Scroll_to_Top_Dynamic_Name">Dynamic Page Size Hold Calculation</resource> <resource name="Scroll_to_Top_Name">Scroll to Top</resource> <resource name="Scroll_to_Top_Percent_Description">Percentage of page scrolled past top of screen before button appears (default = 25)</resource> <resource name="Scroll_to_Top_Percent_Name">Page Percent</resource> <resource name="Title">Widget Title</resource> <resource name="Top">Top</resource> </language>]]></languageResources> <additionalCssScript language="Velocity" /> <files> <file name="style.less">LnRvcC1idXR0b24geyAvL0Jhc2VkIG9uIEdyb3VwIEJhbm5lciBOZXcgYnV0dG9uIGJlaGF2aW91ciBmcm9tIGZvcm1hdC1iYW5uZXIubGVzcwogICAgcG9zaXRpb246IGZpeGVkOyAgICAvL1RoaXMgaXMgcmVxdWlyZWQgdG8gaG9sZCBhdCBib3R0b20gY29ybmVyIG9mIHBhZ2UKICAgICAgICBib3R0b206IDIwcHg7ICAgLy9Ib3cgZmFyIHVwIGZyb20gdGhlIGJvdHRvbSBvZiB0aGUgcGFnZQogICAgICAgIHJpZ2h0OiA3NXB4OyAgICAvL0hvdyBmYXIgZnJvbSB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgcGFnZQogICAgICAgIHotaW5kZXg6IDk5OTk7ICAvL1B1dCB0aGlzIG9uIHRvcCBvZiBhbnkgb3RoZXIgY29udGVudCBldmVyIHNob3duIG9uIHRoZSBwYWdlCiAgICBtYXJnaW4tbGVmdDogMTBweDsKICAgIGRpc3BsYXk6IGZsZXg7CglmbGV4LWRpcmVjdGlvbjogcm93OwoJYWxpZ24taXRlbXM6IGNlbnRlcjsKCWhlaWdodDogODhweDsKICAgIGZsZXg6IDAgMCAxMTVweDsKICAgIGN1cnNvcjogcG9pbnRlcjsKICAgIAogICAgdWwgewogICAgICAgIHdpZHRoOiAxMTVweDsKCQlmbG9hdDogcmlnaHQ7CgkJb3ZlcmZsb3c6IGhpZGRlbjsKCQlsaSB7CgkJCQlmbG9hdDogcmlnaHQ7CgkJCQloZWlnaHQ6IDEwMCU7CgkJCQlvdmVyZmxvdzogaGlkZGVuOwoJCQkJd2lkdGg6IDEwMCU7CgkJCX0KICAgIAlhIHsKICAgIAkgICAgZGlzcGxheTogbm9uZTsgIC8vYnkgZGVmYXVsdCwgZG9uJ3Qgc2hvdyB0aGUgYnV0dG9uCiAgICAJICAgIGZsb2F0OiBsZWZ0OwogICAgICAgICAgICB3aWR0aDogMTAwJTsKICAgIAkgICAgd2hpdGUtc3BhY2U6bm93cmFwOwogICAgICAgICAgICBvdmVyZmxvdzogaGlkZGVuOwogICAgCQl0ZXh0LWFsaWduOiBjZW50ZXI7CiAgICAJCWZvbnQtc2l6ZTogMC45ICogLWV2by10aGVtZWNvbmZpZy11bml0KCdiYXNlRm9udFNpemVWYWx1ZScsIDE0cHgpOwogICAgCQlsaW5lLWhlaWdodDogMzRweDsKICAgIAkJYmFja2dyb3VuZC1jb2xvcjogLWV2by10aGVtZWNvbmZpZy1jb2xvcignYWNjZW50Q29sb3InKTsKICAgIAkJY29sb3I6IC1ldm8tdGhlbWVjb25maWctY29sb3IoJ2JhY2tncm91bmRDb2xvcicpOwogICAgCQlib3JkZXItcmFkaXVzOiAzcHg7IC8vY29kZWQgcmF0aGVyIHRoYW4gcmVjcmVhdGUgLnJvdW5kIGNvZGUKICAgIAkJJjpob3ZlciB7CiAgICAJCQliYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGVuKC1ldm8tdGhlbWVjb25maWctY29sb3IoJ2FjY2VudENvbG9yJyksIDUlKTsKICAgIAkJfQoJCQkKCSAgICB9CiAgICB9Cn0=</file> </files> </scriptedContentFragment> </scriptedContentFragments>
Version 12:
<scriptedContentFragments> <scriptedContentFragment name="${resource:Scroll_to_Top_Name}" version="12.0.1.15778" description="${resource:Scroll_to_Top_Description}" instanceIdentifier="1f873697a9f54f82ab7e526b483b6c2a" theme="" isCacheable="false" varyCacheByUser="false" showHeaderByDefault="false" cssClass="top-button" lastModified="2021-05-09 19:14:24Z"> <contentScript language="Velocity"><![CDATA[$core_v2_page.AddLink('stylesheet', $core_v2_widget.GetExecutedFileUrl('style.less'), "%{ Position = 'AfterTheme' }") <div class="top-button"> <ul> <li> ##"Button" for scroll to top (anchor not button because actual button causes POST resend on reload) <a onclick="topFunction()" id="topBtn" class="prepend-icon up-open-big">$core_v2_language.GetResource('Top')</a> </li> </ul> </div> #registerEndOfPageHtml() <script type="text/javascript"> var topButton = document.getElementById("topBtn"); //Find the link on page to control disply var bodyHeight = document.body.scrollHeight; //Get height of page (Safari) var elemHeight = document.documentElement.scrollHeight; //Get height of page (all other browsers) var hPercent = $core_v2_widget.GetIntValue('sttPercent', 25); //Get the percent of page to be above the to from widget configuration //Initialize dynamicScrollFunction variables var shown = false; var storedBodyHeight = 0; var storedElemHeight = 0; //Check if we're locking the button on at height even if page changes size dynamically var dynamicScrolling = "$core_v2_widget.GetBoolValue('dynScroll', false)"; //stored as string because GetBoolValue returns in Title Case dynamicScrolling = dynamicScrolling.toLowerCase(); //normalize to javascript bool lowercase (still a string though) //Register which function to use when scrolling //String comparison because GetBoolValue returns in Title Case if (dynamicScrolling == "false"){ window.onscroll = function() {scrollFunction()}; } if (dynamicScrolling == "true"){ window.onscroll = function() {dynamicScrollFunction()}; } //Standard scrolling function (always recalculates when to show/hide button on every scroll action) function scrollFunction() { if (document.body.scrollTop > (bodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (elemHeight * (hPercent/100))) { topButton.style.display = "block"; //Show the button } else { topButton.style.display = "none"; //Hide the button } } //Stop recalculating page size function once the button is shown (remove comments on lines to reset when the user scrolls manually above it again) function dynamicScrollFunction(){ if (!shown) { //Check to see if button has not been shown bodyHeight = document.body.scrollHeight; //Update variables elemHeight = document.documentElement.scrollHeight; //Update variables if (document.body.scrollTop > (bodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (elemHeight * (hPercent/100))) { topButton.style.display = "block"; //Show the button storedBodyHeight = bodyHeight; //Lock in bodyHeight storedElemHeight = elemHeight; //Lock in elemHeight shown = true; //Flag that button has been shown } } else if (shown){ //Button has been shown once, always show again at same scroll point if (document.body.scrollTop > (storedBodyHeight * (hPercent/100) ) || document.documentElement.scrollTop > (storedElemHeight * (hPercent/100) )) { topButton.style.display = "block"; //Keep showing the button as long as current position is over locked in show height } else{ topButton.style.display = "none"; //Hide the button //shown = false; //Remove flag for has been shown to start calculations over } } } //What the link does when clicked (scrolls back to the top of the page) function topFunction() { document.body.scrollTop = 0; //Safari document.documentElement.scrollTop = 0; //All of the rest topButton.style.display = "none"; //Hide the button //For resetting dynamicScrollFunction: //shown = false; //storedBodyHeight = 0; //storedElemHeight = 0; } </script> #end]]></contentScript> <headerScript language="Velocity"><![CDATA[$core_v2_widget.ApplyTokens($core_v2_widget.GetStringValue('fragmentHeader', '${resource:Scroll_to_Top_Name}'))]]></headerScript> <configuration><![CDATA[<propertyGroup id="options" labelResourceName="Options"> <property id="fragmentHeader" labelResourceName="Title" defaultValue="${resource:Scroll_to_Top_Name}" dataType="String" template="core_v2_tokenizedString" /> <property id="sttPercent" labelResourceName="Scroll_to_Top_Percent_Name" descriptionResourceName="Scroll_to_Top_Percent_Description" defaultValue="25" dataType="int" template="int" presentationDivisor="1" inputType="number" min="1" max="80" step="1" rangeTicks="0" rangeLabel="True" /> <property id="dynScroll" labelResourceName="Scroll_to_Top_Dynamic_Name" descriptionResourceName="Scroll_to_Top_Dynamic_Description" defaultValue="false" dataType="bool" template="bool" /> </propertyGroup>]]></configuration> <languageResources><![CDATA[<language key="en-us"> <resource name="Scroll_to_Top_Description">Creates a button that scrolls to the top of the page</resource> <resource name="Scroll_to_Top_Dynamic_Description">Hold page size calculation after button is shown (keeps button visible at same point on manual scroll up until hidden when page size grows dynamically)</resource> <resource name="Scroll_to_Top_Dynamic_Name">Dynamic Page Size Hold Calculation</resource> <resource name="Scroll_to_Top_Name">Scroll to Top</resource> <resource name="Scroll_to_Top_Percent_Description">Percentage of page scrolled past top of screen before button appears (default = 25)</resource> <resource name="Scroll_to_Top_Percent_Name">Page Percent</resource> <resource name="Title">Widget Title</resource> <resource name="Top">Top</resource> </language>]]></languageResources> <additionalCssScript language="Velocity" /> <files> <file name="style.less">LnRvcC1idXR0b24geyAvL0Jhc2VkIG9uIEdyb3VwIEJhbm5lciBOZXcgYnV0dG9uIGJlaGF2aW91ciBmcm9tIGZvcm1hdC1iYW5uZXIubGVzcwogICAgcG9zaXRpb246IGZpeGVkOyAgICAvL1RoaXMgaXMgcmVxdWlyZWQgdG8gaG9sZCBhdCBib3R0b20gY29ybmVyIG9mIHBhZ2UKICAgICAgICBib3R0b206IDIwcHg7ICAgLy9Ib3cgZmFyIHVwIGZyb20gdGhlIGJvdHRvbSBvZiB0aGUgcGFnZQogICAgICAgIHJpZ2h0OiA3NXB4OyAgICAvL0hvdyBmYXIgZnJvbSB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgcGFnZQogICAgICAgIHotaW5kZXg6IDk5OTk7ICAvL1B1dCB0aGlzIG9uIHRvcCBvZiBhbnkgb3RoZXIgY29udGVudCBldmVyIHNob3duIG9uIHRoZSBwYWdlCiAgICBtYXJnaW4tbGVmdDogMTBweDsKICAgIGRpc3BsYXk6IGZsZXg7CglmbGV4LWRpcmVjdGlvbjogcm93OwoJYWxpZ24taXRlbXM6IGNlbnRlcjsKCWhlaWdodDogODhweDsKICAgIGZsZXg6IDAgMCAxMTVweDsKICAgIGN1cnNvcjogcG9pbnRlcjsKICAgIAogICAgdWwgewogICAgICAgIHdpZHRoOiAxMTVweDsKCQlmbG9hdDogcmlnaHQ7CgkJb3ZlcmZsb3c6IGhpZGRlbjsKCQlsaSB7CgkJCQlmbG9hdDogcmlnaHQ7CgkJCQloZWlnaHQ6IDEwMCU7CgkJCQlvdmVyZmxvdzogaGlkZGVuOwoJCQkJd2lkdGg6IDEwMCU7CgkJCX0KICAgIAlhIHsKICAgIAkgICAgZGlzcGxheTogbm9uZTsgIC8vYnkgZGVmYXVsdCwgZG9uJ3Qgc2hvdyB0aGUgYnV0dG9uCiAgICAJICAgIGZsb2F0OiBsZWZ0OwogICAgICAgICAgICB3aWR0aDogMTAwJTsKICAgIAkgICAgd2hpdGUtc3BhY2U6bm93cmFwOwogICAgICAgICAgICBvdmVyZmxvdzogaGlkZGVuOwogICAgCQl0ZXh0LWFsaWduOiBjZW50ZXI7CiAgICAJCWZvbnQtc2l6ZTogMC45ICogLWV2by10aGVtZWNvbmZpZy11bml0KCdiYXNlRm9udFNpemVWYWx1ZScpOwogICAgCQlsaW5lLWhlaWdodDogMzRweDsKICAgIAkJYmFja2dyb3VuZC1jb2xvcjogLWV2by10aGVtZWNvbmZpZy1jb2xvcignYWNjZW50Q29sb3InKTsKICAgIAkJY29sb3I6IC1ldm8tdGhlbWVjb25maWctY29sb3IoJ2JhY2tncm91bmRDb2xvcicpOwogICAgCQlib3JkZXItcmFkaXVzOiAzcHg7IC8vY29kZWQgcmF0aGVyIHRoYW4gcmVjcmVhdGUgLnJvdW5kIGNvZGUKICAgIAkJJjpob3ZlciB7CiAgICAJCQliYWNrZ3JvdW5kLWNvbG9yOiAtZXZvLWRlY3JlYXNlLWNvbnRyYXN0KC1ldm8tdGhlbWVjb25maWctY29sb3IoJ2FjY2VudENvbG9yJyksIDEwJSwgLWV2by10aGVtZWNvbmZpZy1jb2xvcignYmFja2dyb3VuZENvbG9yJyksIC1ldm8tdGhlbWVjb25maWctZG91YmxlKCdjb250cmFzdCcpKTsKICAgIAkJfQoJCQkKCSAgICB9CiAgICB9Cn0=</file> </files> </scriptedContentFragment> </scriptedContentFragments>
Instructions on how to import a widget: https://community.telligent.com/community/12/a/developer-training/c/working-with-widget-studio#importing-widgets
This widget is free to use as-is and at your own discretion. No support or guarantee is being offered as part of this listing.