I have a gridview button that I programmatically created and I want to load an update panel on the client side with the sent data. I have a hidden value field that gets its data on the click of the gridview button and the dropdownlist in my updatepanel depends on that value.
while calling __doPostBack directly will work, it's not a perfect solution because the name of that function is strictly speaking an implementation detail of the .Net framework.
A better solution is to use ClientScriptManager.GetPostBackEventReference, which gives you a more resilient interface to the same functionality. Do note that GetPostBackEventReference and GetCallBackEventReference are not the same thing - the former causes a page reload (partial or full, depending on how your UpdatePanels are set up), while the latter doesn't.
The easiest way to do this is to call __doPostBack from client side.
On client side button1_onclick method, calls:
__doPostBack('<%=UpdatePanel1.ClientID %>','Refresh:0,1,2'); //refresh update panel
On page behind add the following event handler to capture the post back call:
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
string arg = Request.Form["__EVENTARGUMENT"];
if (string.IsNullOrEmpty(arg)) return;
if (arg.StartWith("Refresh")
{
//parse data first then do your thing here...
}
}
And of course don't forget to wire event to the above method:
protected void Page_Init(object sender, EventArgs e)
{
UpdatePanel1.Load += new EventHandler(UpdatePanel1_Load);
}
we use the __dopostback() method which simulates a postback and causes the updatepanel to refresh
__doPostBack('controlName','');
Don't forget that the control name is it's HTML ID (which may well contain dollars etc) and not just it's ASP.NET ID.
As far as I know you can either call this method and pass in the hidden value field, or the div that it is in.
Related
I checked SO for a solution but I didn't come to anything useful, they were either unanswered like this orphan link or irrelevant. Now I ask it here:
Is it possible to make validators show their messages on first load of the page?
I have a couple of validators (required, custom, range ...) on my page, and I have grouped them. I want the required validation group show their messages on first load (when !page.IsPostBack) so my customer can see what is mandotary and what is not at the first glance.
Following code should work for your requirement.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// for all validators to fire, first time
Page.Validate();
// Or Only validators under a specific group will fire
Page.Validate("ValidationGroupName");
}
}
Just call Validate() on the validator(s) from Page_Load.
if(!IsPostBack)
{
this.UserNameRequired.Validate();
// and all the other mandatory validators
}
Sure... just call the submit method of your form.
Isn't that what you really need? submit the form and get all messages?
$(function() {
// this will submit the form, but as you have validation,
// it will fire up all validations
$("form").submit();
});
It's a simple trick, that I sometimes do.
i'm a beginner in .NET, and search since yesterday morning to resolve my problem without finding the solution.
Here is my problem :
I create dynamically some User Controls by this way, because I need to give parameters :
List<ANNOUNCEMENT> listAnnouncement = getAnnoucements();
foreach(ANNOUNCEMENT ann in listAnnouncement)
{
if(ann.IS_CURRENT_ANNOUNCEMENT && currentAnnouncement == null)
{
currentAnnouncement = ann;
}
List<Object> listParams = new List<Object>();
listParams.Add(ann);
AnnouncementPresentation ap = (AnnouncementPresentation)(Controller.LoadControl(Page, "~/UserControls/AnnouncementPresentation.ascx", listParams.ToArray()));
/* important for the end of the method */
ap.modifyAnnouncementButtonClick += new EventHandler(modifyAnnouncementButtonClick);
pnl_announcements.Controls.Add(ap);
}
In this ASCX, I have a button, and when user will click on it, I want to call a method contained in my ASPX, so I do this in the ASCX :
public event EventHandler modifyAnnouncementButtonClick;
protected void btn_modify_announcement_Click(object sender, EventArgs e)
{
PageAdminAnnonces.currentAnnouncement = annonce;
modifyAnnouncementButtonClick(sender, e);
}
And this in the ASPX :
protected void modifyAnnouncementButtonClick(object sender, EventArgs e)
{
initListOfAnnouncement();
lbl_errors.Text = currentAnnouncement.TITLE;
}
I think everything works, but there is the problem : It works once, and at the end of the method, I delete my ASCX as you can see, and create new ASCX. But they don't have the methods, and when I click again, nothing works, so the ASPX is reloaded. After reloading, it works again.
Do i do something wrong?
According to the information in the comments, I suppose that your solution does not work because you are recreating the controls in the Click event handling method, which is very late in the page's lifecycle and should not be used for adding controls.
As mentioned in the comments, I suggest you to create the controls in Page_Init or Page_Load and not recreate them in the button's Click handling method. You should also assign a unique ID to each of them. Then, in the Click handler, you can use FindControl method to acces the created controls. Alternatively you can just save the references to the controls upon creation, so you can access them later easily.
Useful links:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
http://visualstudiomagazine.com/articles/2010/10/11/more-on-adding-controls-dynamically.aspx
I have a GridView with dynamically created image buttons that should fire command events when clicked. The event handling basically works, except for the very first time a button is clicked. Then, the postback is processed, but the event is not fired.
I have tried to debug this, and it seems to me, that the code executed before and after the first click is exactly the same as for any other clicks. (With the exception that in the first click, the event handler is not called.)
There is some peculiarity in that: The buttons which fire the event are created dynamically through databinding, i.e. databinding must be carried out twice in the page lifecycle: Once on load, in order to make the buttons exist (otherwise, events could not be handled at all), and once before rendering in order to display the new data after the events have been processed.
I have read these posts but they wouldn't match my situation:
ASP.NET LinkButton OnClick Event Is Not Working On Home Page,
LinkButton not firing on production server,
ASP.NET Click() event doesn't fire on second postback
To the details:
The GridView contains image buttons in each row. The images of the buttons are databound. The rows are generated by GridView.DataBind(). To achieve this, I have used the TemplateField with a custom ItemTemplate implementation. The ItemTemplate's InstantiateIn method creates the ImageButton and assigns it the according event handler. Further, the image's DataBinding event is assigned a handler that retrieves the appropriate image based on the respective row's data.
The GridView is placed on a UserControl. The UserControl defines the event handlers for the GridView's events. The code roughly looks as follows:
private DataTable dataTable = new DataTable();
protected SPGridView grid;
protected override void OnLoad(EventArgs e)
{
DoDataBind(); // Creates the grid. This is essential in order for postback events to work.
}
protected override void Render(HtmlTextWriter writer)
{
DoDataBind();
base.Render(writer); // Renews the grid according to the latest changes
}
void ReadButton_Command(object sender, CommandEventArgs e)
{
ImageButton button = (ImageButton)sender;
GridViewRow viewRow = (GridViewRow)button.NamingContainer;
int rowIndex = viewRow.RowIndex;
// rowIndex is used to identify the row in which the button was clicked,
// since the control.ID is equal for all rows.
// [... some code to process the event ...]
}
private void DoDataBind()
{
// [... Some code to fill the dataTable ...]
grid.AutoGenerateColumns = false;
grid.Columns.Clear();
TemplateField templateField = new TemplateField();
templateField.HeaderText = "";
templateField.ItemTemplate = new MyItemTemplate(new CommandEventHandler(ReadButton_Command));
grid.Columns.Add(templateField);
grid.DataSource = this.dataTable.DefaultView;
grid.DataBind();
}
private class MyItemTemplate : ITemplate
{
private CommandEventHandler commandEventHandler;
public MyItemTemplate(CommandEventHandler commandEventHandler)
{
this.commandEventHandler = commandEventHandler;
}
public void InstantiateIn(Control container)
{
ImageButton imageButton = new ImageButton();
imageButton.ID = "btnRead";
imageButton.Command += commandEventHandler;
imageButton.DataBinding += new EventHandler(imageButton_DataBinding);
container.Controls.Add(imageButton);
}
void imageButton_DataBinding(object sender, EventArgs e)
{
// Code to get image URL
}
}
Just to repeat: At each lifecycle, first the OnLoad is executed, which generates the Grid with the ImageButtons. Then, the events are processed. Since the buttons are there, the events usually work. Afterwards, Render is called, which generates the Grid from scratch based upon the new data. This always works, except for the very first time the user clicks on an image button, although I have asserted that the grid and image buttons are also generated when the page is sent to the user for the first time.
Hope that someone can help me understand this or tell me a better solution for my situation.
A couple problems here. Number one, there is no IsPostBack check, which means you're databinding on every load... this is bound to cause some problems, including events not firing. Second, you are calling DoDataBind() twice on every load because you're calling it in OnLoad and Render. Why?
Bind the data ONCE... and then again in reaction to events (if needed).
Other issue... don't bind events to ImageButton in the template fields. This is generally not going to work. Use the ItemCommand event and CommandName/CommandArgument values.
Finally... one last question for you... have you done a comparison (windiff or other tool) on the HTML rendered by the entire page on the first load, and then subsequent loads? Are they EXACTLY the same? Or is there a slight difference... in a control name or PostBack reference?
Well I think the event dispatching happens after page load. In this case, its going to try to run against the controls created by your first data-binding attempt. This controls will have different IDs than when they are recreated later. I'd guess ASP.NET is trying to map the incoming events to a control, not finding a control, and then thats it.
I recommend taking captures of what is in the actual post.
ASP.NET is pretty crummy when it comes to event binding and dynamically created controls. Have fun.
Since in my opinion this is a partial answer, I re-post it this way:
If I use normal Buttons instead of ImageButtons (in the exact same place, i.e. still using MyItemTemplate but instantiating Button instead of ImageButton in "InstantiateIn", it works fine.
If I assert that DoDataBind() is always executed twice before sending the content to the client, it works fine with ImageButtons.
Still puzzled, but whatever...
I am using two kinds of buttons, on button takes the user to the next screen. Here I am using a session variable to take the user to the next screen:
protected void Buttondocumentdetails_Click(object sender, EventArgs e)
{
Session["Narration"] = TextBox2.Text;
Response.Redirect("~/TJFAQ0001.aspx", false);
}
This is working properly -- after clicking this button the user is sent to the next screen, which is is "TJFAQ0001.aspx". On this page I am using button to take the user to the previous screen:
protected void previous_Click(object sender, EventArgs e)
{
Session["Narration"] =null;
Response.Redirect("TJFAQOO1.aspx", false);
}
This is working, but all the data has been cleared. I want the same data when I click previous button. How can I do this?
First of all you can use Server.Transfer instead of Response.Redirect.
You can pass the page field data in a context variable and then pass it to the next page. When redirected to the previous page pass this back and do the necessary processing and then fill the data back to the controls.
Do not use Session variable in this context. You can add a context variable when using Server.Transfer.
You have to repopulate the data in TJFAQOO1.aspx page when it gets loaded on click of previous button as it is a new get request and postback kind of facility is not available.
I am trying to fire a form submit via jQuery and have a particular server side event fire.
Client Side Code:
$("input[name=__EVENTARGUMENT]").val("SomeArg");
form = $("body form");
form.submit();
Server Side Code:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (Request["__EVENTARGUMENT"] == "SomeArg")
{
//do some stuff
}
}
}
The problem is, the "__EVENTARGUMENT" hidden input does not exist. I discovered that if I add an ASP.net server control dropdownlist with autopostback = true, the EVENTARGUMENT hidden input is created. Is there a cleaner way to have ASP.net create these hidden inputs, and allow me to get their values server side without adding controls I do not actually need on the page?
Add asp.net HiddenField control to the page
But you will have a problem which is to get this control id, which as.net generates automatically, you can solve this using the ClientID property for the hidden field like this article mentions