Can PagedList be used to automatically switch pages? - c#

I am using asp.net-mvc and I have a PageList from https://github.com/TroyGoode/PagedList in my project, it works fine but I would like to be able to switch the pages automatically on a set time interval. The pages I am using have a set number of accordion items and wanted to know how I could switch the page number without human interaction. Like use a slideshow with pagedList. Is there something better to use or is this possible?
My Index.cshtml
#model PagedList.IPagedList<ComputerDownTimeTracker.Models.DashboardTicketListVM>
#using PagedList.Mvc;
<body>
<div class="list1">
<div id="accordion">
#foreach (var item in Model)
{
<div class="header">
<b> Equipment: </b>#item.ComputerName <br />
<b> Location: </b>#item.Location
#switch (item.RunningStatus)
{
case 1: imagePath = down;
break;
case 2: imagePath = running;
break;
case 3: imagePath = waiting;
break;
case 4: imagePath = waiting;
break;
default: imagePath = running;
break;
}
<img class="status" src="#imagePath" alt="" />
<ul class="timeStat">
<li><b class="time">Computer Down At :</b> #item.OnClickTimeStamp</li>
#if (#item.RunningStatus == 4)
{
<li> <b class="time"> Maintenance On issue :</b> #item.EditTimeStamp</li>
}
#if (#item.RunningStatus == 3)
{
<li> <b class="time">Waiting For Parts :</b> #item.EditTimeStamp</li>
}
#if (#item.RunningStatus == 2)
{
<li> <b class="time">Computer Restarted :</b> #item.EditTimeStamp</li>
}
</ul>
</div>#*//computer name and status div*#
<div><p>#Html.Raw(#item.ComputerStatus)</p></div>
}
#(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",new { page }))
</div>
</div>
My Home controller index method
public ActionResult Index(int? page)
{
var time = DateTime.Now;
time = time.AddSeconds(-100);
var ViewModel = _ComputerDB.Database.SqlQuery<DashboardTicketListVM>(listQuery).ToList();
var remove_running = ViewModel.Where(x => x.OnRestartTimeStamp >= time || x.OnRestartTimeStamp == null);
int pageSize = 8;
int pageNumber = (page ?? 1);
return View("Index", "~/Views/Shared/_ListLayout.cshtml", remove_running.ToPagedList(pageNumber, pageSize));
}
I omitted a lot of stuff that wasn't really relevant

You need use use Javascript setTimeout to reload the next page after some specified time.
Using the PagedList examples:
Controller
public class ProductController : Controller
{
public object Index(int? page)
{
var products = MyProductDataSource.FindAllProducts(); //returns IQueryable<Product> representing an unknown number of products. a thousand maybe?
var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
var onePageOfProducts = products.ToPagedList(pageNumber, 25); // will only contain 25 products max because of the pageSize
ViewBag.OnePageOfProducts = onePageOfProducts;
return View();
}
}
View
#{
ViewBag.Title = "Product Listing"
}
#using PagedList.Mvc; //import this so we get our HTML Helper
#using PagedList; //import this so we can cast our list to IPagedList (only necessary because ViewBag is dynamic)
<!-- import the included stylesheet for some (very basic) default styling -->
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
<!-- loop through each of your products and display it however you want. we're just printing the name here -->
<h2>List of Products</h2>
<ul>
#foreach(var product in ViewBag.OnePageOfProducts){
<li>#product.Name</li>
}
</ul>
<!-- output a paging control that lets the user navigation to the previous page, next page, etc -->
#Html.PagedListPager( (IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page }) )
View Javascript
<script type="text/javascript">
var nextPage = #(((IPagedList)ViewBag.OnePageOfProducts.PageNumber) + 1); // next page number is current page number + 1
setTimeout(function() {
window.location = "index?page=" + nextPage; // load new page after timeout
}, (5 * 1000) /* set timeout here, example: 5 seconds */);
</script>
Note: You may need to add some additional logic to make sure to stop the next page loading whenever you get to the end of your pages. You can do this by checked the HasNextPage property provided by PagedList.
Example:
<script type="text/javascript">
var hasNextPage = #(((IPagedList)ViewBag.OnePageOfProducts.HasNextPage) ? "true" : "false");
if(hasNextPage) {
var nextPage = #(((IPagedList)ViewBag.OnePageOfProducts.PageNumber) + 1); // next page number is current page number + 1
setTimeout(function() {
window.location = "index?page=" + nextPage; // load new page after timeout
}, (5 * 1000) /* set timeout here, example: 5 seconds */);
}
</script>

Related

PagedList.MVC - Page buttons(links) don't work as expected

I wanted to implement a simple pagination, and PagedList.MVC NuGet package sounded like the best solution for me. HOWEVER, when I click on generated buttons to go to 2nd, 3rd, etc. page, 1st one remains active, and all that happens is refresh of the first page, but I obviously want it to navigate to the expected page...
I followed these two tutorials to see if I've done everything right:
Github
Microsoft
My controller:
public ActionResult Index(int? pageNumber)
{
var modelList = _employeeService.GetEmployeeViewToPagedList(pageNumber);
return View(modelList);
}
The service method that gets called (I know that "ToPagedList()" is usually called from the controller, but the current state is a result of trying everything, and the fact that I get "DbContext disposed" error if I modify to return something like "View(modelList.ToPagedList(pageNumber, pageSize))" from the controller):
public IPagedList<EmployeeView> GetEmployeeViewToPagedList(int? pageNumber)
{
using (var _unitOfWork = UnitOfWork.GetUnitOfWork())
{
var list = (IQueryable<EmployeeView>)_unitOfWork.context.EmployeeViews.OrderByDescending(x => x.Id);
return list.ToPagedList((pageNumber ?? 1), 10);
}
}
My view:
#model PagedList.IPagedList<Company.DAL.Views.EmployeeView>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
}
<h2>List of all employees</h2>
<p>
#Html.ActionLink("Add new employee", "AddNewEmployee")
</p>
#if (Model != null && Model.Count() > 0)
{
<table class="table">
... all needed <tr>'s, <th>'s, <td>'s ...
</table>
<br/>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, pageSize =
Model.PageSize }))
}
I am trying to figure this out for days now, and the closest I got was this question, but I am not sure where to find that JS function, so I could try that as well.
EDIT:
Generated HTML:
<div class="pagination-container">
<ul class="pagination">
<li class="active"><a>1</a></li>
<li>2</li>
<li>3</li>
<li class="PagedList-skipToNext">ยป</li>
</ul>
</div>
I decided to post an answer here, since I solved the problem, and somebody else might find this useful.
So, in the controller, my Index method looks like this:
public ActionResult Index(int? pageNumber)
{
//some logic
}
As you can see, it accepts an int variable named pageNumber as a parameter.
But then there's this on my view:
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, pageSize = Model.PageSize }))
SO, here I am passing a variable named page to my Index method.
That's the mistake! Variable in the method parameter list has to be named page as well.

Redirect to Page but specific Tab

I have used this as an example of what I am trying to do.
I have a tabbed page.
In my Controller I want to redirect to a page but a specific tab on that page.
Now when I am on that page, and hover over the tab the link is http://localhost:xxxxx/OInfoes/Details/2#phases
So in my controller I did this to try and recreate the same link:
return new RedirectResult(Url.Action("Details", "OInfoes", new { id = phase.OID }) + "#phases");
This gives me the correct link but it doesn't put me on the correct tab.
How do I get this to work?
My HTML for the tabs is below:
<ul class="nav nav-tabs">
<li class="active">Information</li>
<li>Previous Reports</li>
<li>Previous/Current Phases</li>
</ul>
You should update your action method to take a parameter to represent the tab to be selected.
public ActionResult Details(int id,string tab="")
{
if (id != null)
ViewBag.ActiveTab = id.ToString();
// to do : Return a view
}
When you return the redirect result, send a querystring with name tab
return new RedirectResult(Url.Action("Details", "OInfoes", new { id = phase.OID ,
tab="phases"}));
Now in your document ready, use the value of ViewBag.ActiveTab value, generate the jQuery selector from that and use that to call .tab('show').
$(function () {
var selector = '#ViewBag.ActiveTab';
if(selector)
{
$("#link-tab"+selector).tab('show');
}
});
Make sure your tab's has id's matching with our above code.
<ul class="nav nav-tabs">
<li class="active">Info</li>
<li>Prev Reports</li>
<li>Prev/Cur Phases</li>
</ul>

Razor function takes more load time than usercontrol function

I just trying to change my usercontrol function to razor function.but the page load time by using razor function is more than usercontrol function can any one know why this time taken.here is my razor code
#inherits RazorFunction
#using System.Linq;
#using Composite.Data;
#using Atc.Data;
#using System.Web.UI.WebControls;
#using System.Collections.Generic;
#functions {
public override string FunctionDescription
{
get { return "Function for footer"; }
}
}
<ul>
<li>##Copyright 2012 </li>
#{
using(DataConnection dCon =new DataConnection())
{
SitemapNavigator sn = new SitemapNavigator(dCon);
PageNode p = sn.CurrentHomePageNode;
List<PageNode> hiddenPages = dCon.Get<Page_Settings>()
.Where(x => x.FooterNavVisibility == true).OrderBy(x => x.Position)
.Select(x => sn.GetPageNodeById(x.PageId))
.ToList<PageNode>();
foreach (var item in hiddenPages)
{
<li>#item.Title</li>
}
}
}
<li>
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_compact"></a>
<a class="addthis_counter addthis_bubble_style"></a>
</div>
</li>
</ul>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=ra-5008fecf0e8dcc29"></script>
It could be that actual UserControl's execution time was accounted in the line "ASP.NET controls: PageLoad, EventHandling, PreRender", which currently takes 91 ms.
On a side note: now need to create new DataConnection/SitemapNavigator objects -> there are Data, and SitemapNavigator properties on the base class for the razor functions.
If you want to optimize it, you can f.e. cache the "hiddenPages" variable, and clear cache on Page or PageSettings data type changes.

Avoid the View being loaded from the cache

How can I avoid a View being loaded using the cache ?
I tried putting the [OutputCache(Duration = 1)] before my method that returns the View through a ActionResult but without success.
[OutputCache(Duration = 1)]
public ActionResult Receita(string id, string periodo)
{
// Do my stuff
var receita = new ReceitaAssunto()
{
// More stuff
};
return View(receita);
}
When I pass a new value through the method's parameter, should exhibit this values in my View, but it haven't had refresh, always exhibit the old ones.
View
#model Dashboard.Domain.ClasseTipada.ReceitaAssunto
<ul class="list-group clear-list m-t">
#{
var i = 1;
foreach(var elemento in Model.ReceitaPorTipoReceita)
{
<li class="list-group-item fist-item">
<span class="pull-right">
<span id="txtTextoValorLocacao">#elemento.Valor.ToString("C", new System.Globalization.CultureInfo("pt-BR"))</span>
</span>
<span class="label label-success">#i</span>#elemento.DescricaoOrigem
</li>
i++;
}
i = 0;
}
</ul>
UPDATE
I saw the request using Firebug and the result it's exactly what I want, but it doesn't render in my View.
How I saw (take a look at the values), these values it's true only in the first page load
JS
$("#btnTrimestral").on("click", function () {
GeradorGrafico.URLJson = "#Url.Action("Receita", new { periodo = "trimestral" })";
GeradorGrafico.init();
});
put it into Global.asax.cs in Application_BeginRequest().
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();

get HtmlHelper.textbox value as query string mvc

I have the following idea that i am trying to implement
#foreach (var item in Model)
{
<div>User: #item.Name<br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit");
#Html.ActionLink("Update item", "updateMyItem", new { name = item.Name, lastvisit=????? })
</div>
}
I have seen this SO question Pass text in query string, but that is not what i want..
so my question is ..
in the above code how can I replace the (?????) with the value of the textbox(lastvisit)
and send the value as a querysting in the URL of the action link ??
Notice that I opted not to use a webform for my own reason and I know how to do it with webform.submit(), but my main concern is how to extract the value of #HTMLhelper.textbox()..
:)
Something like this might help. For this to work you need to render unique IDS for the links and textboxes.
Here is an example
Action method with a simple model
public ActionResult Index(int? id)
{
List<MyModel> mod = new List<MyModel>() {
new MyModel { SelectedValue = 1 } ,
new MyModel {SelectedValue = 2},
new MyModel {SelectedValue = 3}
};
return View(mod);
}
And this is the view with the script.
#model List<MVC3Stack.Models.MyModel>
#{
ViewBag.Title = "Home Page";
var i = 1;
}
<h2>#ViewBag.Message</h2>
<script type="text/javascript">
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "&lastvisit=" + $(this).val());
}
});
});
</script>
#foreach (var item in Model)
{
#Html.TextBox("lastVisit" + i, item.SelectedValue )
#Html.ActionLink("TestLink", "Index", "Home", new { id = "testLink" + i });
<br />
i++;
}
<input type="button" value="GetFile" id="getFile" />
here is a snapshot with the changed link
Hope this helps.
EDIT
My bad. Here is the update javascript which can do the trick.
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
$(this).change(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "?lastvisit=" + $(this).val());
}
});
});
});
Ok Nilesh I will answer my own question.. but I will cheat from your solution lol cuz it is inspiring .. thanx in advance
<script type="text/javascript">
$(document).ready(function () {
var myMainPath = "updateMyItem";
$("a").each(function(){
var name =$(this).parent("div").child("#itemName").val();
var visit = $(this).parent("div").child("#lastvisit").val();
$(this).attr('href', myMainPath +'?name=' + name + '&lastVisit='+ visit);
});
});
</script>
#foreach (var item in Model)
{
<div>User: <span id="itemName">#item.Name</span><br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit", new { id="lastvisit"});
Update item
</div>
}
you see it can be done by javascript , but i was mistaken to think that you can manipulate it via Razor on the server ..
I know this post is old, but i just started learning MVC thanks to the asp.net/mvc/ website and i faced a similar problem during the tutorial. My Index action expects 2 parameters which define sorting and filtering (through the macthing of a substring) of a set of record displayed in the view. My problem is that i can't sort a filtered subset, since the view is called but no parameter for filtering is passed once i activate the sorting clicking on the link of the header.
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString){...}
I thought i needed to access the TextBox, but apparently i just need to use the provided ViewBag object as already seen in this example!
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, searchString = ViewBag.SearchString })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString)
{
ViewBag.SearchString = searchString;
. . .
}
Maybe a similar behaviour could have been used for solving the problem that originated this post, i don't know.

Categories

Resources