DasDave
DasDave

Reputation: 811

MVC Persist Model when paging

I have a dropdown list with check boxes. The selected value is bound to my view model. The data is paged using PagedList.Mvc. All works fine when I select some checkboxes and then hit the search button, but when I click onto another page the check box list becomes null so the list loses what is checked. How can I get the model to persist whilst paging.

So my html looks like this

    <ul class="dropdown-menu">
        @for (int i = 0; i < Model.Units.Count; i++)
        {
            @Html.CheckBoxFor(m => m.Units[i].Selected) 
            @Html.HiddenFor(m => m.Units[i].UnitId) 
            @Html.LabelFor(m => m.Units[i].Selected,
                       Model.Units[i].UnitName)
            <br />
            }
    </ul>

 <button class="btn btn-primary" type="submit" id="btnSave" name="Command" value="Save">Search</button>

and further down the paging

 @Html.PagedListPager(Model.SearchData, page => Url.Action("Index", new HistoricDataViewModel { Page = page }))

and my model looks like this

public class HistoricDataViewModel
{
    public HistoricDataViewModel()
    {
        Page = 1;
    }

    public StaticPagedList<Data_Search_Result> SearchData { get; set; }
    public List<Units_Getall_Result> Units { get; set; }
    public int Page
    {
        get; set;
    }
}

When I hit my search button it is submitting the form. Is the problem because the paging plugin isn't doing a submit?

Upvotes: 0

Views: 744

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239440

I always like to drop down to the low-level details in situations like this because I think it helps to understand why things are or aren't possible. Then, once you understand that, you can figure out how to work around limitations.

Namely, here you're dealing with the concepts of request-response and statelessness. Let's start with statelessness. The Internet (specifically the TCP/IP protocol) was designed to be stateless. The Internet is a mesh network, composed of many, many connected devices that join and drop from the network constantly. Having its origins in ARPA, the research arm of the U.S. military, its original purpose was to provide a communication system that could survive a nuclear attack on "hubs", or centralized communication choke points. By decentralizing the network, multiple hubs could be cut off and communication could still continue unabated. However, to implement this kind of network design, you can't have any sort of state, as when the client is forced to connect to a different server because the previous server is now offline that new server would have no knowledge of prior communication the client had. As a result, all the information required for the server to respond to the request must be in the request itself. Which brings us to request-response.

A client issues a request to a server and that server sends a response. This is the fundamental basis for all network communication. When you click one of your pager links, you're issuing a GET request to the server for the next page, and the server responds with the HTML document that represents that page. Since the web is stateless, the only information the server has to build that response with is what was sent in the request by the client (for instance, a query string with the name-value pair "page=2". If you want to persist the checked items, as well, you must find some way to include that in the query string or send a POST request with that data included in the POST body. However, while you can make a link click issue a POST, it requires JavaScript to change the default behavior of a link (sending GET), but it would also require JavaScript to dynamically change the href of the link to include extra data in the query string.

The best solution, really, would be to treat each (checking items and changing pages) as separate things. Upon checking an item, you could either use JavaScript to dynamically post that information to the server or provide a submit button to allow the user to manually post it. Server-side, you can store that value in the session. Then, you can simply let the paging work as it does out of the box and simply read the checked values from the session for each page.

Continuing the discussion above, the session is state, so you might wonder how that's possible when the web is stateless. The answer is that sessions are "fake" state. What's actually going on under the hood is that the server is saving the information and issuing a token that represents the "session". That token is sent to the client as a cookie. Web browsers (the most typical clients) are programmed to send all cookies received from a server back to the server with each request. The result is that the request still technically has all the information the server needs, as the session token is enough to allow the server to find the previous session data and "restore" it.

Upvotes: 1

Related Questions