Skip to content

adding server side paging without javascript #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/React.Sample.Mvc4/Content/Sample.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@

var CommentsBox = React.createClass({
propTypes: {
initialComments: React.PropTypes.array.isRequired
initialComments: React.PropTypes.array.isRequired,
page: React.PropTypes.number
},
getInitialState() {
return {
comments: this.props.initialComments,
page: 1,
page: this.props.page,
hasMore: true,
loadingMore: false
};
Expand All @@ -29,6 +30,7 @@ var CommentsBox = React.createClass({
var url = evt.target.href;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = () => {
var data = JSON.parse(xhr.responseText);
this.setState({
Expand Down Expand Up @@ -60,7 +62,7 @@ var CommentsBox = React.createClass({
return <em>Loading...</em>;
} else if (this.state.hasMore) {
return (
<a href={'comments/page-' + (this.state.page + 1)} onClick={this.loadMoreClicked}>
<a href={'/comments/page-' + (this.state.page + 1)} onClick={this.loadMoreClicked}>
Load More
</a>
);
Expand Down
72 changes: 45 additions & 27 deletions src/React.Sample.Mvc4/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI;
using React.Sample.Mvc4.Models;
using React.Sample.Mvc4.ViewModels;

Expand All @@ -36,20 +37,21 @@ public class IndexViewModel
{
public IEnumerable<CommentModel> Comments { get; set; }
public int CommentsPerPage { get; set; }
public int Page { get; set; }
}
}

namespace React.Sample.Mvc4.Controllers
{
public class HomeController : Controller
{
private const int COMMENTS_PER_PAGE = 3;
public class HomeController : Controller
{
private const int COMMENTS_PER_PAGE = 3;

private readonly IDictionary<string, AuthorModel> _authors;
private readonly IDictionary<string, AuthorModel> _authors;
private readonly IList<CommentModel> _comments;

public HomeController()
{
public HomeController()
{
// In reality, you would use a repository or something for fetching data
// For clarity, we'll just use a hard-coded list.
_authors = new Dictionary<string, AuthorModel>
Expand All @@ -60,36 +62,52 @@ public HomeController()
{"jordwalke", new AuthorModel { Name = "Jordan Walke", GithubUsername = "jordwalke" }},
{"zpao", new AuthorModel { Name = "Paul O'Shannessy", GithubUsername = "zpao" }},
};
_comments = new List<CommentModel>
{
_comments = new List<CommentModel>
{
new CommentModel { Author = _authors["daniel"], Text = "First!!!!111!" },
new CommentModel { Author = _authors["zpao"], Text = "React is awesome!" },
new CommentModel { Author = _authors["cpojer"], Text = "Awesome!" },
new CommentModel { Author = _authors["vjeux"], Text = "Hello World" },
new CommentModel { Author = _authors["daniel"], Text = "Foo" },
new CommentModel { Author = _authors["daniel"], Text = "Bar" },
new CommentModel { Author = _authors["daniel"], Text = "FooBarBaz" },
};
}
};
}

public ActionResult Index()
{
return View(new IndexViewModel
{
Comments = _comments.Take(COMMENTS_PER_PAGE),
CommentsPerPage = COMMENTS_PER_PAGE
});
}
public ActionResult Index()
{
return View(new IndexViewModel
{
Comments = _comments.Take(COMMENTS_PER_PAGE),
CommentsPerPage = COMMENTS_PER_PAGE,
Page = 1
});
}

public ActionResult Comments(int page)
{
var comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE);
[OutputCache(Duration = 0, Location = OutputCacheLocation.Any, VaryByHeader = "Content-Type")]
public ActionResult Comments(int page)
{
Response.Cache.SetOmitVaryStar(true);
var comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE);
var hasMore = page * COMMENTS_PER_PAGE < _comments.Count;

return Json(new {
comments = comments,
hasMore = hasMore
}, JsonRequestBehavior.AllowGet);
}
}
if (ControllerContext.HttpContext.Request.ContentType == "application/json")
{
return Json(new
{
comments = comments,
hasMore = hasMore
}, JsonRequestBehavior.AllowGet);
}
else
{
return View("Index", new IndexViewModel
{
Comments = _comments.Take(COMMENTS_PER_PAGE * page),
CommentsPerPage = COMMENTS_PER_PAGE,
Page = page
});
}
}
}
}
2 changes: 1 addition & 1 deletion src/React.Sample.Mvc4/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</p>

<!-- Render the component server-side, passing initial props -->
@Html.React("CommentsBox", new { initialComments = Model.Comments })
@Html.React("CommentsBox", new { initialComments = Model.Comments, page = Model.Page })

<!-- Load all required scripts (React + the site's scripts) -->
<script src="http://fb.me/react-0.13.1.js"></script>
Expand Down