Search code examples
asp.net-coremodel-view-controllerrazorviewscroll

How do you maintain the previous scroll position after post using asp.net core 3.1 MVC and razor views?


How do you maintain the previous scroll position after a post using asp.net core 3.1 MVC (web application) and razor views?

How do you do this across the site?

I saw this: ASP.NET MVC3 Razor - Maintain scroll position on postback - but those did not work for me.


Solution

  • First, Create a base view model that all other models will inherit

    public class BaseViewModel
    {
       public int ScrollPosition { get; set; }
    }
    

    All view models that are bound that will need to remember the previous scroll position will inherit from this BaseViewModel

    Second, Add a hidden input to your form used for posting:

       @using(Html.BeginForm("SomeAction", "SomeController", FormMethod.Post)
       {
          @Html.HiddenFor(x => Model.ScrollPosition)
          ....
       }
    

    Third, inside your post method on the backend set a value to TempData:

       TempData["ScrollPosition"] = Model.ScrollPosition;
    

    Fourth, when redirect after post, set this value to your Model for binding in your view:

       MyModel.ScrollPosition = (int)TempData["ScrollPosition"];
    

    Fifth, use javascript to scroll to previous position after page load:

       <script type="text/javascript">
           window.addEventListener("DOMContentLoaded", function(){
               //add event listener for the scroll event and set hidden input value for posts
               document.addEventListener('scroll', function(){
                  const scrollPosY = window.scrollY;
                  document.querySelector('input[name="ScrollPosition"]').value = scrollPosY;
               });
               const scrollpos = document.querySelector('input[name="ScrollPosition"]').value;
               window.scrollTo(0, scrollpos); //y-axis scroll
           });
       </script>
    

    If you would need to track x axis scroll as well as y axis, you'd need two hidden inputs for each x and y axis scroll position and change model to hold both x and y