4

Looking for a similar solution effect as the updatepanel in web forms, but for MVC, below is a bit about my problem in particular. I'm sure there are many ways to do this, but ideally I want the best and most proper way.

I have looked at this question but couldn't get it to work.

Update: It can postback; MVC equivalent. I just need the position of the page maintained for the user's perspective.

I have tried the below at the bottom of my Index page but no dice.

@section Scripts
{
<script type="text/javascript">
    window.scrollTo = function( x,y ) {
     return true;
    }
</script>
}

As well as: Controller

ViewBag.JumpTo = "equipmentAnchor";
            return RedirectToAction("Index");

Index

<div id="equipmentAnchor"></div>
@section Scripts
{
<script type="text/javascript">
    $(document).ready(function () {
        var JumpTo = '@ViewBag.JumpTo';
        if (JumpTo != "") {
            $(this).scrollTop($('#' + JumpTo).position().top);
        }
    });
</script>
}

What is the best/easiest way to achieve this?

I've seen reports that AJAX is heavy on the server, but not overly fussed about that, preferably no CSS tricks (if there are any). JQuery is not something I am overly familiar with, but could lead to be the best solution, however not particularly well versed in it so don't know where to begin.

In the below example is a list view with a delete button that goes back to a controller to iterate through the list and delete the last entry into the list. However be it add, or in this case delete, the page jumps to the top of the index page after the postback.

How should/can I stop this posting back and reloading the page, or at the very least stop the user experiencing it?

Example Code:

Index:

<div class="List">
                    @{Html.RenderPartial("View", Model.List);}
                </div>

Partial

@using (Html.BeginForm("RemoveExisting", "PA_4"))
{
    if (Model != null)
    {
        foreach (var ri in Model)
        {
            <div class="ui-grid-c ui-responsive">
                <div class="ui-block-a">
                    <p>One</p>
                    <span>
                        @ri.One
                    </span>
                </div>
                <div class="ui-block-b">
                    <p>Two</p>
                    <span>
                        @ri.Two
                    </span>
                </div>
            </div>
        }
    }
    if (Model.Count() > 0)
    {
        <div>
            <input type="submit" value="Remove"/>
        </div>
    }
}
Community
  • 1
  • 1
JammAndTea
  • 195
  • 1
  • 8

2 Answers2

2

Had this problem this answer here helped me.

Download from GitHub and dump it in your scripts folder and reference it in @section Scripts

Like so at the bottom of your view:

@section Scripts
{
<script type="text/javascript" src="~/Scripts/maintainscroll.jquery.min.js">

</script>
}
Community
  • 1
  • 1
PurpleSmurph
  • 2,055
  • 3
  • 32
  • 52
1

Use ajax form ... you will need jquery.unobtrusive-ajax.js for it to woork & jquery ofcourse. ( use nuget).

To use it you need to define it like Html.BeginForm but you define an id ( preferably a div ) where the response html will be written. So the page never reloads but ajax inserts the response HTML in the element with the targetId ( in the dom). A prerequesite for this to work is that the return of the action is a partial view. Otherwise the entier page will render inside this div.

Example:

View:

    @using (Ajax.BeginForm("RemoveExisting", new AjaxOptions() {
        HttpMethod = "POST",
        OnBegin = "OptionalJSFunction",
        OnFailure = "OptionalJSFunction",
        OnSuccess = "OptionalJSFunction",
        UpdateTargetId = "targetId"
    }))
    { 
         //Your form goes in here..
    } 

<div id="targetId">
</div>

Controller:

    [HttpPost]
    public ActionResult RemoveExisting(YourModel model)
    {
       //your code in here
       return PartialView("YourView",model);
    }
SomeRandomName
  • 593
  • 1
  • 8
  • 23
  • This would go in the partial, yes? Would that still work as it's being displayed through a partial on the Index. – JammAndTea May 11 '15 at 14:28
  • Depends how you want to set it up if you only want to return an updated list or the entire form with the list. If its case 1 you need to separate them into 2 views. Example you can have an "index" action tah laods the entire view. and popualtes
    on pagelao d with some @renderpartial and then have the ActionResult return this partial aswell..
    – SomeRandomName May 11 '15 at 14:31
  • I couldn't get that to work when I tried, it behaved the same as with html.beginform. From the removing actionmethod, I am returning RedirectToAction("Index"), not passing in a model, that's done through a session. – JammAndTea May 11 '15 at 15:23
  • Well i told you to return a partialview result in the action that the Ajax form calls.So ofcourse it won't woork. And didn't you want a partial load ? why would you accept some scroll handler ? i dont get it – SomeRandomName May 12 '15 at 06:41
  • Can this solution work when returning RedirectToAction (this populates lists from my session objects) rather than return PartialView? If so, how? – JammAndTea May 12 '15 at 12:58
  • If the action you are redirecting to is returning a partial view sure. – SomeRandomName May 12 '15 at 14:06
  • Okay, will try again later, the action I'm redirecting to is "Index" which has several partial views - this didn't work for me previously, will give it another shot and mark as accepted answer if works. Cheers for the suggestion. – JammAndTea May 14 '15 at 08:39