Ok, let me start this with I am more of an MVC person. I have a result set that I am trying to add paging. All I really want is a previous and next button on my page which are Link controls. I need these controls to post back to the same page, but have a query parm like page=4. How do I add these links? I see the PostBackUrl property on the link. Should I just use Request.Url and stuff it into PostBackUrl? Then I have to do string searches on the parm... it gets nasty. Is that the only way? I have tried ViewState, please dont suggest that... it is unpredictable garbage as far as I am concerned.
The PostBackUrl property is for cross-page postbacks, you don't want to do that.
If you want to use a POST, you can use a LinkButton, handle the click event, and rebind your result set. Something like
public void BackButton_Click(object sender, EventArgs e)
{
// Get existing page from session, viewstate, etc
// RebindGrid
}
If you want to use a GET, you can use a HyperLink and set the NavigateUrl property to the correct Url. Something like
int page;
if( !int.TryParse(Request.QueryString["page"], out page) )
page = 1;
if( page > 1 )
BackUrl.NavigateUrl = Request.Path + "?page=" + (page-1).ToString();
else
NextUrl.NavigateUrl = Request.path + "?page=" + (page+1).ToString();
// Note: not syntax/bounds checked
Edit:
Perhaps what you're looking for a Post-Redirect-Get pattern?
Response.Redirect(HttpContext.Current.Request.Path + query, true);
You're talking about ASP.NET Webforms or MVC?
If you're talking about Webforms I don't think that you'll have success on that. I believe that you'll need to control this move between your pagination with Session or other way or re-bind your data for each page.
What I ended up doing was putting hiddens on the page for the vars I needed to pass back, then I read those. This is things like page number, which allows me to calculate prev and next page. Sorry to submit my own answer but this was a little odd and I thought I would tell what I ended up doing.
View state for some reason was empty every time, so it was doing me no good. This is in a DNN app, and I didnt want to spend time figuring out why viewstate was messed up.
Related
As if in this article I implemented an easy way to switch between languages on a website.
The issue is if I want to switch languages with a dropdown list, and leave the last selected language on the dropdown list control's view.
Every article I've seen about CulturalInfo-switching sends a Server.transfer() call right after the language switch, and that event causes the non-postback page reloading, including my dropdownlist control which realoads from default position.
I tried a response.redirect(), but it still is a non postback call
I think I need a way to check if it's a Server.transfer() call in the page load, but still haven't found a way to develop this
Thank you.
Assuming you followed the same approach as in that article, how about this:
string path = this.Request.Path;
if (path.LastIndexOf('?') > 0)
path += "&lang=" + senderLink.CommandArgument;
else
path += "?lang=" + senderLink.CommandArgument;
this.Server.Transfer(path);
Then, on the page that this.Server.Transfer executes, get lang value from this.Request.QueryString["lang"], and set the dropdown's SelectedItem appropriately.
Alternatively, keep Server.Transfer(Request.Path);, but on the receiving page, parse Session["MyCulture"] instead to set the dropdown. +1
I have a session variable that changes some things about how a page looks. I have a button that changes the value of this session variable. But ... the onClick event happens after page load, so by the time I update the session variable based on the button click, it's too late, the page has already been loaded.
Theoretically I could put all the logic about changing the display into a function and call it from page load, and then call it again from the onclick after the variable as been updated. But this is impractical: there are many user controls that check the value, used on many different pages in different combinations. I would have to hard-code the list of user controls on each page, and if someone added a new user control to a particular page, they'd have to remember to update this function, which is lame.
Is there a way to force a page reload? (I can use response.redirect back to myself and it works. If all else fails I guess this is what I'll do. But it means an extra round trip to the server, which is clumsy.)
Is there a way to process the onclick before the page load?
Some other magic solution?
If you have to change the look and feel of a page based on a specific value which can change, then you should have dedicated functions that set up the look and feel in a single unified place, and then you call those functions in every case where a value that affects the look and feel is called.
Examples:
private void SetDivVisibility()
{
// display logic here based on variables
}
private void MyControl_Click(...)
{
myvalue = blah;
SetDivVisibility();
}
It helps to bear in mind that the actual rendering of the page is last thing that happens, after both page load AND event processing.
Theoretically I could put all the logic about changing the display into a function and call it from page load
That's how you should do it. Cleanup your logic and markup - refactor and keep it DRY. That should help.
I can use response.redirect back to myself
That's the other option. Yes, a round trip is nasty.
you may put your code of styling your page in a void called by the page_load normally and called again from buttonclick
or call response.redirect to same url
or even onClick is client side use window.location.href
A design with a layout predicated on the existence of a session variable which won't exist until after it's been render is a huge design error. I like to call it the "Chicken or the Egg" syndrome. (yes, you can quote me.. ;)
I'd argue that your controls shouldn't get their layout completed in the on render. Instead, use a method (similar to databinding) where you can "rebind" the controls with the new session value on demand. This method would show/hide things based on the updated values.
I have page and I am displaying the same page for n number of times and binding Various Data.
There is a back button on the page, When I click on it it should just take the page where it should diplay the previous data in the controls.
I tried Server.Transfer, Response.Redirect(), But they are taking to the page I wanted but not to the immediate previous page.
Please help.
Thank you
Hari Gillala
May be this helps;
protected void Page_Load(object sender, EventArgs e)
{
this.btnBack.OnClientClick = "javascript:window.history.go(-1);return false;";
}
Would doing it on the client side suffice? Just use history.go(-1) on click of the button.
Server side:
You can store the data which has to be bound to the controls in the session.Create session variables before rendering the pages, give different names to the session variable, may be you can use static variable for naming..
Why don't you utilize History object of JavaScript?
http://www.javascriptkit.com/jsref/history.shtml
http://www.defaultdotaspx.com/Answer.aspx?QuestionType=JavaScript&QuestionID=264
http://www.developertutorials.com/questions/question/q-147.php
Are you binding "various data" via AJAX?
Hope this helps!
I'm guessing that what you mean in your question is: I have a bunch of filters on my page and every time a filter gets changed I want to create a new item in the browser history so I can use the Back button to go back through my filters.
Have a look at the AddHistoryPoint method (+ overloads) of the ScriptManager object. This method allows you to save the state of your controls into a collection and save that into a URL that gets inserted into your browser's history collection, so that you can then retrieve it when the Back button is pressed and reload the state into the controls on your page.
I am trying after the btnCreate_OnClick event to reset the form to it's default value just like the first page_load. The problem is after PostBack, every textbox and other controls, reloads the ViewState value. I cannot deactivate viewstate because of server event on DropDownList selection. The only way I found so far is to Redirect to self after the click event, but this loads the page twice and is therefor a bad solution. I have try ViewState.Clear() and update the UpdatePanel, but was unsuccessful.
I could do a loop for all controls and set the txtXXXXX.Text == "", but I'm quite sure it's not the best idea.
Something like Page.Reset() would have been just perfect but it doesn't exist.
Any thought on this problem of mine?
Thanks
If workable, I usually just use Response.Redirect to reload the same page from scratch.
An initial GET request to a page usually costs less than subsequent POSTs anyway, so there's not much reason to avoid it.
We can reset the ASP.NET Form Page with just 2 lines of code
protected void Button_Reset_Click(object sender, EventArgs e)
{
Session["ViewState"] = null;
Response.Redirect("/Roster/DRAC/Create.aspx");
}
Self redirecting gets tricky because of viewstate.
There is an html input type "reset" for buttons, but I'm not sure what or any integration msft has put into viewstate/asp.net for this. It generally works for simple javascript forms.
ex:
<input type="button" value="Reset" onclick="document.<formId>.reset();">
from google ----^
One way, not necessarily ideal, is to reset the values to their defaults using Javascript. If it is a large form, it can be ugly, but will prevent the need to do a self-redirection.
You also might try Server.Transfer instead of Response.Redirect(/self/)
I dont know if this helps but i change the name of every input on the form that i want to get fresh values by using javascript before submiting the form, since the .net page can no longer match the values from the form to the controls for the page it reloads them as if there was no postback. i also append a new value to the form so i know what button submitted the form and use that logic to decide what to load into all the controls and how to process the form data of course.
$("#Bset").children().click(function() { //all the btns click function
$.each($("form").find("input"), function(e,v) { //could filter this to subset of inputs
$(v).attr("name", "_" + $(v).attr("name")); // ctrl1 becomes _cntrl1
});
$("form").append("<input type='hidden' id='b' name='b' value='" + $(this).text() + "' />").submit();
});
then in the code behind
protected void Page_Init(object sender, EventArgs e)
{
id = int.Parse(Request.QueryString["id"]);
bk = db.dc.getDetailBK(id).Single();
if (Request.Form.Count > 0)
doPostBack();
mrl = (from a in db.dc.getMetricQTD(id, null, null, loadSavedGoals) select a).ToList();
}
i can then do things in dopostback that process the form data, interact with the db etc. that may change the values mrl is loaded with and refresh the data in the inputs tied to mrl regardless of wether they were modified or not on the form.
the other alternative would be to tie some buttons to use a webservice to handle your db interaction then call window.location to refresh the page.
$.ajax({
url: "webservice/dbfunction?"
data: {which btn pressed, some form values etc...}
success: function() {window.location("samepage.aspx?id=xxx");}
...
});
this would also avoid having to response redirect on the server side.
In our case the best performance solution was to set manually for each control the default value in the click event ex:
textbox1.Text = null;
textbox2.Text = null;
This avoid the double page_load and the loop. We don't event have to update the UpdatePanel since it executes before render.
Maybe in a more complex web application we would have to Redirect as most people seem to accept this as a solution.
Setting per control the default value was better suited to our case.
Thank you
I have a search form in an app I'm currently developing, and I would like for it to be the equivalent of method="GET".
Thus, when clicking the search button, the user goes to search.aspx?q=the+query+he+entered
The reason I want this is simply bookmarkable URLs, plus it feels cleaner to do it this way.
I also don't want the viewstate hidden field value appended to the URL either.
The best I could come up with for this is:
Capture the server-side click event of the button and Response.Redirect.
Attach a Javascript onclick handler to the button that fires a window.location.replace.
Both feel quirky and sub-optimal...
Can you think of a better approach?
Use a plain old html form, not a server side form (runat=server), and you should indeed be able to make it work.
This could however be a problem if you have an out of the box visual studio master page which wraps the entire page in a server side form, because you can't nest forms.
Web forms don't have to suck, but the default implementations often do. You don't have to use web forms for everything. Sometimes plain old post/get and process request code will do just fine.
I worked on a web site that had to post to a 3rd party site to do the search on the client's web site. I ended up doing a simple Response.Redirect and passed in the search parameters through the query string like so:
protected void Button1_Click(object sender, EventArgs e)
{
string SearchQueryStringParameters = #"?SearchParameters=";
string SearchURL = "Search.aspx" + SearchQueryStringParameters;
Response.Redirect(SearchURL);
}
And on your Search.aspx page in your pageload...
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.QueryString["SearchParameters"]))
{
// prefill your search textbox
this.txtSearch.Text = Request.QueryString["SearchParameters"];
// run your code that does a search and fill your repeater/datagrid/whatever here
}
else
{
// do nothing but show the search page
}
}
Hope this helps.
This function permits to submit a page using the GET method.
To submit a page using the get method you need to:
add this code Form.Method="get"; in the Page_Load method
Use this code < asp:Button runat="server" ID="btnGenerate" /> as a submit button
add rel="do-not-submit" attribute to all form elements that you don't want to include in your query string
change the codebehind logic of your page using Request.QueryString
disable the page viewstate with EnableViewState="false" (unless it's used for other purposes)
Code
$(document).ready(function(){ enableSubmitFormByGet(); });
function enableSubmitFormByGet(){
if($("form").attr("method") == "get"){
$("form").submit(function() {
$("[name^=" + "ctl00" + "]").each(function(i){
var myName = $(this).attr("name");
var newName = "p" + (i-1);
$(this).attr("name", newName);
});
var qs =$(this).find("input[rel!='do-not-submit'],textarea[rel!='do-not-submit'],select[rel!='do-not-submit'],hidden[rel!='do-not-submit']").not("#__VIEWSTATE,#__EVENTVALIDATION,#__EVENTTARGET,#__EVENTARGUMENT").serialize();
window.document.location.href = "?" + qs;
return false;
});
I would do (b) since (a) would require two round trips for a single query. Alternatively, you could disable viewstate on the page, remove any other hidden fields via javascript, and also use javascript to modify the form method from post to get. I've never done this for real, but my toy page using the included sample worked like a charm. It's arguably easier than encoding the search string and doing the get via javascript.
Actually, it sounds like you would be happier with ASP.NET MVC since this is easily doable there by simply setting the form method to GET in the view.
sample code using jquery
$(document).ready( function() {
$('input[type=hidden]').remove();
$('form').attr('method','get');
});
EDIT: It seems like you ought to be able to do the same thing server-side, too. Maybe in OnPreRenderComplete. Don't have access to Visual Studio right now to check.
I have always used Response.Redirect as it "works".
I don't think there is an optimal method.
Just use this in your .click event before the form submission:
$("#__VIEWSTATE").remove();
$("#__EVENTVALIDATION").remove();