Maintaining GridView current page index after navigating away from Gridview page - asp.net

I have a GridView on ASP.NET web form which I have bound to a data source and set it to have 10 records per page.
I also have a hyper link column on the GridView, such that a user can navigate to another page (details page) from the list. On the details page, they have "Back" button to return to the GridView page
Edit
Just to clarify the query
I am looking for sample code snippet on the Server Side on how to specify the page index to set the GridView after data binding. The idea is to ensure the user navigates to the same page index they were on.

The three basic options at your disposal: query string, session, cookie. They each have their drawbacks and pluses:
Using the query string will require you to format all links leading to the page with the gridview to have the proper information in the query string (which could end up being more than just a page number).
Using a session would work if you're sure that each browser instance will want to go to the same gridview, otherwise you'll have to tag your session variable with some id key that is uniquely identifiable to each gridview page in question. This could result in the session management of a lot of variables that may be completely undesirable as most of them will have to expire by timeout only.
Using a cookie would require something similar where cookie data is stored in a key/data matrix (optimized hash table might work for this). It would not be recommended to have a separate cookie name for each gridview page you're tracking, but rather have a cookie with a common name that holds the data for all gridview pages being tracked and inside that have the key/value structure.
Edit: A small code snippet on setting the page index.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
try
{
if(HttpContext.Current.Request["myGVPageId"] != null])
{
myGridview.PageIndex = Convert.ToInt32(HttpContext.Current.Request["myGVPageId"]);
}
}
catch(Exception ex)
{
// log it
}
}
}

I'm more of a fan of the Session approach, personally. Simply save your page index as a session variable, and, if this Session variable isn't null on page load, use it to fire your "OnPageIndexChanging" method, like so:
Set your current page number whenever the page number changes:
protected void GridViewIndexChanging(object sender, GridViewPageEventArgs e)
{
myGridView.PageIndex = e.NewPageIndex;
Session["pageNumber"] = e.NewPageIndex;
//whatever your page index changing does...
}
Then, on Page_Load do something like:
if (!IsPostBack)
{
if (Session["pageNumber"] != null)
{
GridViewIndexChanged(myGridView, new GridViewPageEventArgs((int)Session["pageNumber"]));
}
}

you can ues the Page Index Change Event of Gridview and Find out the Current Page Index for e:g
yourGridId.PageIndex=e.NewPageIndex;
ViewState["GridPageIndex"]=e.NewPageIndex;
on PageLoad Get the Viewstate Value
string pIndex=string.Empty;
pIndex=Convert.toInt32(ViewState["GridPageIndex"]);
if(!string.Empty(pIndex))
{
yourGridId.PageIndex =pIndex;
}

you must use query string and is recommended, otherwise you can use session object but don't use that for this as you may have grid view opening in different pages so use query string .
gridView1.CurrentPageIndex = (Request["pageNo"] != null) ? Request["pageNo"] as int : 0;
gridView1.DataSource = myDataSet;
gridView1.DataBind();
you can update your link on GridView_DataBound event

Related

How is this explained with ASP.NET page life cycle?

I have the following code, which simply inserts a record into the database, based on some text fields and a dropdown. The dropdown gets bound in the Page Load Event.
protected void btnAdd_Click(object sender, EventArgs e)
{
try
{
Personeel p = new Personeel();
p.achternaam = txtNaam.Text;
p.naam = txtVoornaam.Text;
p.fk_afdeling_id = Convert.ToInt16(cmbAfdeling.SelectedValue);
BLLpersoneel BLLp = new BLLpersoneel();
BLLp.insert(p);
lblFeedback.Text = "Done and done!";
rptPersoneel.DataBind();
}
catch (Exception err)
{
lblFeedback.Text = err.Message;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if(Page.IsPostBack == false)
{
BLLafdeling BLLa = new BLLafdeling();
cmbAfdeling.DataSource = BLLa.selectAll();
cmbAfdeling.DataTextField = "naam";
cmbAfdeling.DataValueField = "afdeling_id";
cmbAfdeling.DataBind();
}
}
My question is about IsPostBack.
On first load, the page has no PostBack, so it will bind the data to the dropdown "cmbAfdeling".
Then, when submitting the form, there IS a postback, so we don't reach the code inside the if statement. To me, that would mean that ASP.NET would NOT bind the data to the combo box.
However, the data is still there after submitting (and thus having a postback).
How is this explained?
This is due to the ViewState. The data in the ComboBox is stored in the ViewState and is sent back & forth during postback.
This might be worth reading to understand what is happening: http://msdn.microsoft.com/en-us/library/ms972976.aspx
It's explained by a concept called viewstate:
If you examine the code produced by your asp, you will find some hidden fields, one of which is the "viewstate". The viewstate saves the important values of your asp in order to be able to populate the elements every time the pages gets loaded, even if it's after a postback.
The data is maintained during postback, as you don't clear the data during postback or on load it will persist.

Click event not detected in UserControl

I've some UserControls which are created dynamically, with parameters :
foreach (DataRow dr in drc)
{
question = (from ques in bdd.QUESTION where ques.ID_QUESTION == idQuestion select ques).FirstOrDefault();
List<Object> listParams = new List<Object>();
listParams.Add(question);
AdminQuestion qa = (AdminQuestion)(Controller.LoadControl(Page, "~/UserControls/AdminQuestion.ascx", listParams.ToArray()));
pnl_question_list.Controls.Add(qa);
}
This is a method I found on SoF and it works great.
This method is called when I click on a button, and all my usercontrols are correctly created.
In this usercontrol, I have a button :
<asp:Button ID="btn_validation_modify_question" runat="server" Text="Modifier"
CssClass="clear_left_float_left myBouton myBoutonEnvoyer"
OnClick="btn_validation_modify_question_Click"/>
And my method :
protected void btn_validation_modify_question_Click(object sender, EventArgs e)
{
QUESTION q = (from m in bdd.QUESTION where m.ID_QUESTION == question.ID_QUESTION select m).FirstOrDefault();
q.MESSAGE = txt_modify_question_message.InnerText;
q.ID_THEME = new Guid(ddl_modify_question_theme.SelectedValue);
bdd.ApplyCurrentValues<QUESTION>("QUESTION", q);
bdd.SaveChanges();
}
But when I click on the button, it don't apply the method, and reload the page, like if I didn't have any declared method.
Is there something I don't know? I already used this technique and everything worked...
If you add controls dynamically, you'll normally need to do it on Init or PreInit page events. Otherwise event handlers will never work.
So, dynamically added controls must be programmatically added to the Web page on each and every page visit. The best time to add these controls is during the initialization stage of the page life cycle, which occurs before the load view state stage. That is, we want to have the control hierarchy complete before the load view state stage arrives. For this reason, it is best to create an event handler for the Page class's Init event in your code-behind class, and add your dynamic controls there.
Note You may be able to get away with loading your controls in the
Page_Load
event handler and maintaining the view state properly. It all depends on whether or not you are setting any properties of the dynamically loaded controls programmatically and, if so, when you're doing it relative to the
Controls.Add(dynamicControl)
line. A thorough discussion of this is a bit beyond the scope of this article, but the reason it may work is because the
Controls
property's
Add()
method recursively loads the parent's view state into its children, even though the load view state stage has passed.
Here you have more information.
EDIT
Just to be sure we're talking about the same, here you have how your code should look like
protected void Page_Init(object sender, EventArgs e)
{
...
foreach (DataRow dr in drc)
{
question = (from ques in bdd.QUESTION where ques.ID_QUESTION == idQuestion select ques).FirstOrDefault();
List<Object> listParams = new List<Object>();
listParams.Add(question);
AdminQuestion qa = (AdminQuestion)(Controller.LoadControl(Page, "~/UserControls/AdminQuestion.ascx", listParams.ToArray()));
pnl_question_list.Controls.Add(qa);
}
...
}
PageLoad(){
If(!Page.IsPostBack())
foreach (DataRow dr in drc)
{
question = (from ques in bdd.QUESTION where ques.ID_QUESTION == idQuestion select ques).FirstOrDefault();
List<Object> listParams = new List<Object>();
listParams.Add(question);
AdminQuestion qa = (AdminQuestion)(Controller.LoadControl(Page, "~/UserControls/AdminQuestion.ascx", listParams.ToArray()));
pnl_question_list.Controls.Add(qa);
}
}
Did you try with this solution? And not use Page_Init()?

jQuery UI autocomplete is not displaying results fetched via AJAX

I am trying to use the jQuery UI autocomplete feature in my web application. What I have set up is a page called SearchPreload.aspx. This page checks for a value (term) to come in along with another parameter. The page validates the values that are incoming, and then it pulls some data from the database and prints out a javascript array (ex: ["item1","item2"]) on the page. Code:
protected void Page_Load(object sender, EventArgs e)
{
string curVal;
string type ="";
if (Request.QueryString["term"] != null)
{
curVal = Request.QueryString["term"].ToString();
curVal = curVal.ToLower();
if (Request.QueryString["Type"] != null)
type = Request.QueryString["Type"].ToString();
SwitchType(type,curVal);
}
}
public string PreLoadStrings(List<string> PreLoadValues, string curVal)
{
StringBuilder sb = new StringBuilder();
if (PreLoadValues.Any())
{
sb.Append("[\"");
foreach (string str in PreLoadValues)
{
if (!string.IsNullOrEmpty(str))
{
if (str.ToLower().Contains(curVal))
sb.Append(str).Append("\",\"");
}
}
sb.Append("\"];");
Response.Write(sb.ToString());
return sb.ToString();
}
}
The db part is working fine and printing out the correct data on the screen of the page if I navigate to it via browser.
The jQuery ui autocomplete is written as follows:
$(".searchBox").autocomplete({
source: "SearchPreload.aspx?Type=rbChoice",
minLength: 1
});
Now if my understanding is correct, every time I type in the search box, it should act as a keypress and fire my source to limit the data correct? When I through a debug statement in SearchPreload.aspx code behind, it appears that the page is not being hit at all.
If I wrap the autocomplete function in a .keypress function, then I get into the search preload page but still I do not get any results. I just want to show the results under the search box just like the default functionality example on the jQuery website. What am I doing wrong?
autocomplete will NOT display suggestions if the JSON returned by the server is invalid. So copy the following URL (or the returned JSON data) and paste it on JSONLint. See if your JSON is valid.
http://yourwebsite.com/path/to/Searchpreload.aspx?Type=rbChoice&term=Something
PS: I do not see that you're calling the PreLoadStrings function. I hope this is normal.
A couple of things to check.
Make sure that the path to the page is correct. If you are at http://mysite.com/subfolder/PageWithAutoComplete.aspx, and your searchpreload.aspx page is in another directory such as http://mysite.com/anotherFolder/searchpreload.aspx the url that you are using as the source would be incorrect, it would need to be
source: "/anotherFolder/Searchpreload.aspx?Type=rbChoice"
One other thing that you could try is to make the method that you are calling a page method on the searchpreload.aspx page. Typically when working with javascript, I try to use page methods to handle ajax reqeusts and send back it's data. More on page methods can be found here: http://www.singingeels.com/Articles/Using_Page_Methods_in_ASPNET_AJAX.aspx
HTH.

What code do I type in next page after passing gridview button clicked rowindex

I pass the row index value into next page when gridview button clicked using this code
if(e.CommandName=="select")
{
int Id = int.Parse(e.CommandArgument.ToString());
//Label1.Text = Id.ToString();
Response.Redirect("~/manclothes1.aspx?Id=" + e.CommandArgument.ToString());
}
but i don't know what code i write in next page to display row data
please can anyone help me
In ASP.NET you don't actually pass code to a new page. Instead you modify the controls on the current page and the ASP.NET framework re-renders the page for you. Instead of the Response.Redirect line you want something like
DataGrid1.EditItemIndex = Id;
In the page_load of manclothes1.aspx you can try
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Id"] != null)
{
var id = Request.QueryString["Id"];
// do something with id variable
...
}
}
You'll probably want to reference whatever code on the current page populates the gridview with data in the first place. Essentially, where the code on the current page gets many rows to populate a gridview, the code on the manclothes1.aspx page will get one row. If it's data from a database, the query will likely be very much the same but with an additional WHERE clause to filter by (I'm assuming) an ID value, which is probably a primary key (or the primary key, if we're talking about only one table).
To put this into context, what the call to Response.Redirect() is doing is telling the client (browser) to issue an entirely new request (a GET request, that is) for an entirely new resource (manclothes.aspx with a query string parameter). So understand that "the next page" knows nothing of the gridview on the current page. Nor should it, really. The request should be handled entirely separate from the current page.

javascript timer

I am developing an online exam application using asp.net. In the start exam page I have created a javascript countdown timer.
How can I move to the next page automatically after the timer reaches 00?
Here is my code:
long timerStartValue = 1000 ;
private int TimerInterval
{
get
{
int o =(int) ViewState["timerInterval"];
if(o==0)
{
return (o);
}
return 50 ;
}
set
{
ViewState["timerInterval"] = value;
}
}
protected void Page_PreInit(object sender,EventArgs e)
{
string timerVal = Request.Form["timerData"];
if(! String.IsNullOrEmpty(timerVal))
{
timerVal = timerVal.Replace(",", String.Empty) ;
this.timerStartValue = long.Parse(timerVal);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if(! IsPostBack)
{
this.timerStartValue = 10000; //3599000;//14400000;
this.TimerInterval = 500;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
this.timerStartValue = 3599000;
}
protected void Page_PreRender(object sender, EventArgs e)
{
System.Text.StringBuilder bldr=new System.Text.StringBuilder();
bldr.AppendFormat("var Timer = new myTimer({0},{1},'{2}','timerData');", this.timerStartValue, this.TimerInterval, this.lblTimerCount.ClientID);
bldr.Append("Timer.go()");
ClientScript.RegisterStartupScript(this.GetType(), "TimerScript", bldr.ToString(), true);
ClientScript.RegisterHiddenField("timerData", timerStartValue.ToString());
}
Thanks in advance,
sangita
It sounds like when you click the "Next" button, you are loading an entirely new page. This of course changes all the content and resets all the javascript. You can't maintain state across pages without a bit of work.
The solution to this could be to save the timer state when the next button is pressed, and pass it to the next stage. You could do this by saving the timer state to a hidden form input and submitting it along with the Next button.
The other option would be to load your questions via AJAX. Instead of moving to a new page every time the next button is clicked, you could simply replace the question portion of the page with a new question, and leave the timer intact. This is probably the solution I would use.
Are u reloading the entire page when clicking on the next button ? That may leads to realod the java script file also.So the variable values will reset.May be you can think about showing the questions /answers via Ajax.You need not reload the entire page when showing the next question.the part when you show the quiz will only be updated.so you can maintain the global variables in your java script too. Check the below link to know about partial page updating using jQuery.
http://www.west-wind.com/presentations/jquery/jquerypart2.aspx
Hope this helps.
You can put the timer in an iframe if you can't get rid of the postback.
You need a way to persist information between pages, and there's really only one possibility: To make it part of the next page request.
Now, this could be subdivided into 2 categories:
1) As part of the url: http://www.example.com/page?timer=123;
2) As part of the headers;
And number 2 opens new possibilities:
a) As part of POST data;
b) As a client-side cookie only;
c) As a cookie tied to information on the server;
Number 1, 2a and 2b can be manipulated by the user. So what you can do is store some value in a cookie, a hash for example or a database row ID, that you'll use to fetch information on the server.
tl;dr? Use a asp "Session object". It lets you keep things on the server-side and users will have no idea what they are.

Resources