Full postback triggered by LinkButton inside GridView inside UpdatePanel - c#

I have a GridView inside of a UpdatePanel. In a template field is a button I use for marking items. Functionally, this works fine, but the button always triggers a full page postback instead of a partial postback. How do I get the button to trigger a partial postback?
<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
<asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
<asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>

You need to register each and every LinkButton as an AsyncPostBackTrigger. After each row is bound in your GridView, you'll need to search for the LinkButton and register it through code-behind as follows:
protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);
}
This also requires that ClientIDMode="AutoID" be set for the LinkButton, as mentioned here (thanks to Răzvan Panda for pointing this out).

It's probably not advised but you can make everything on the GridView work asynchronously by excluding the EventName on the AsyncPostBackTrigger so e.g.
<Triggers>
<asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>
This will make the RowCommand event and any other event on the GridView fire asynchronously. Note as well that when you make ClientIDMode="Static" on the GridView it will cause a full postback.

My grid view is in conditional mode.
protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = lnk.UniqueID;
trigger.EventName = "Click";
UpdatePanel2.Triggers.Add(trigger);
}
}
And in the click event of the linkbutton I put:
protected void LinkButton2_Click(object sender, EventArgs e)
{
UpdatePanel2.Update();
}

Put the following element inside system.web element in web.config file
<xhtmlConformance mode="Transitional"/>

MSDN specifies that the UpdatePanel.ChildrenAsTriggers property "[g]ets or sets a value that indicates whether postbacks from immediate child controls of an UpdatePanel control update the panel's content" (see http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx).
Since your LinkButton does not appear to be an "immediate child control," then I would recommend configuring your LinkButton as an explicit AsyncPostBackTrigger.
Below your </ContentTemplate> tag, try adding this:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>

I had an issue where I had one form working fine (page1), another doing whole post backs (page2). Turned out when I made the 2nd page, I had done a bit too much cut/paste, and it still had a javascript call in the form definition.
< form id="form1" runat="server" onsubmit="return checkstuff();">
But checkstuff was not defined in page 2.
deleted the onsubmit, and the partial posts started working.
In the working page - page 1, checkstuff was defined, but was just a stub, which did nothing more than return true. Just for grins, I put an alert in checkstuff, and sure enough, it is called for all submits, partial or not. And, if I changed the stub to just return false, nothing happened at all.
Point in all this, the javascript is still exercised, as if a full page is being submitted. So double check your client side scripts.

this may be old but my solution was to put an update panel inside the itemTemplate and one outside the gridview as well.
the trigger should be the gridview and the outside trigger should be the gridview and PageIndexChanging. Try that.

You need to register each controls for each RowState.
1: Register your controls for RowState = Alternate and Normal)
2: Register your controls for RowState = Edit
3: ...
ASPX:
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton runat="server" ID="Btn1"
CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
Code behind :
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow
&& (e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
}
if (e.Row.RowType == DataControlRowType.DataRow
&& e.Row.RowState == DataControlRowState.Edit)
{
LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );
}
}

Related

Update a gridview row within a Updatepanel by the click of a checkbox not working

GOAL:
I would like to update the status of the checkbox in the database when OnCheckedChanged event of the Checkbox fires. This checkbox resides on each row of gridview. Don't want to postback the whole page so I have the gridview inside a Updatepanel.
PROBLEM:
I can't get the OnCheckedChanged event to fire once the gridview is placed in a updatepanel.
or am I approaching this the wrong way?
Here is what i have for the updatepanel,gridview,checkbox and checkbox event code
The Binding of this gridview is within a if (!IsPostBack)
Even though it is not shown in this example below, that Gridview is nested in another gridview, if that makes a difference.
HTML
<asp:UpdatePanel ID="gridUpdatePanel" UpdateMode="Conditional" runat="server" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:GridView ID="gvComponents" runat="server" AutoGenerateColumns="false" CssClass = "ChildGrid" OnRowDataBound="gvComponents_RowDataBound" ShowHeader="false">
<Columns>
//Other TemplateFields
<asp:TemplateField HeaderText="Revisions Required" Visible="false" ItemStyle-Width="10%" >
<ItemTemplate>
<div style="text-align:center;">
<asp:CheckBox ID="cbREVISION_REQD" runat="server" Enabled="true" Checked='<%# (bool)Eval("REVISION") %>' AutoPostBack="true" OnCheckedChanged ="cbREVISION_CheckChanged" />
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
C#
protected void cbREVISION_CheckChanged(object sender, EventArgs e)
{
//code to update the database
gridUpdatePanel.Update();
}
There seem to be nothing wrong with the approach! But, is
UpdateMode="Conditional"
a problem?
You have to try this for binding nested-gridview in cbREVISION_CheckChanged event:
protected void cbREVISION_CheckChanged(object sender, EventArgs e)
{
GridViewRow gvr = ((CheckBox)sender).Parent as GridViewRow; // gets the gridview row where checkbox cliked
GridView gv = gvr.Parent as GridView; // gets the cliked gridview or nested gridview
CheckBox chkbox = gvr.FindControl("cbREVISION_REQD") as CheckBox; // gets checkbox from cliked gridview
bool status = chkbox.Checked; // gets the status of the checkbox
// here bind your nested-gridview
gv.DataSource = dt; // dt is some data to which you set gridview
gv.DataBind(); // binding methed to bind gridview
}
It will work!

OnCheckChanged Event of asp:CheckBox Not Firing When Unchecked From Within Nested GridView

I have conducted a lot of searches which included checkchanged or OncheckChanged keyword:
ASP.NET CheckBox does not fire CheckedChanged event when unchecking
https://forums.asp.net/t/1311576.aspx?Checkbox+not+firing+when+unchecking+using+OnCheckedChanged
OnCheckedChanged event not firing
OnCheckedChanged event handler of asp:checkbox does not fire when checkbox is unchecked
But this just doesn't seem to be working although I applied all suggestion from the links given above
I am tring to fire a CheckChanged Event From nested gridview, whose DataSource gets binded in parent grid's OnRowDataBound event.
My aspx markup
<asp:GridView ID="gvDocSchedule" runat="server" AutoGenerateColumns="false" CssClass="table table-striped color-black"
OnRowDataBound="gvDocSchedule_RowDataBound" DataKeyNames="UserID">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img alt="" style="cursor:pointer" src="UserPanel/images/Plus12.png" />
<asp:Panel ID="PanelSchedule" runat="server" Style="display:none">
<asp:GridView ID="gvScheduleDayNTime" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField ="ScheduleDay" HeaderText="CheckInTime1"/>
<asp:BoundField ItemStyle-Width="150px" DataField ="CheckInTime1" HeaderText="CheckInTime1"/>
<asp:BoundField ItemStyle-Width="150px" DataField ="CheckOutTime1" HeaderText="CheckOutTime1"/>
<asp:BoundField ItemStyle-Width="150px" DataField ="CheckInTime2" HeaderText="CheckInTime2"/>
<asp:BoundField ItemStyle-Width="150px" DataField ="CheckOutTime2" HeaderText="CheckOutTime2"/>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="hdnForChkBox" runat="server" value="No" />
<asp:CheckBox ID="CBoxAvailabilityTime1" ViewStateMode="Enabled" Checked="false" Enabled="true" EnableViewState="true" runat="server" Text="See Free TimeSlots For Booking In Time1" AutoPostBack="true" OnCheckedChanged="CBoxAvailabilityTime1_CheckedChanged" />
<br />
<asp:CheckBox ID="CBoxAvailabilityTime2" runat="server" Text="See Free TimeSlots For Booking In Time1" AutoPostBack="true" OnCheckedChanged="CBoxAvailabilityTime2_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ControlStyle-Font-Bold="true" DataField="UserFirstName" HeaderText="Doctor's First Name" />
<asp:BoundField DataField="UserLastName" HeaderText="Doctor's Last Name" />
<asp:BoundField DataField="SpecializationName" HeaderText="Doctor's Specialization" />
<asp:BoundField DataField="HospitalName" HeaderText="Hospital" />
</Columns>
</asp:GridView>
I was trying it with CBoxAvailabilityTime1CheckBox. As you guys can see ViewStateMode and EnableViewState has been taken care of not only in server tag but also in content page's tag, also these properties are true for master page
Parent Grid gets binded when user press a button and nested grid gets binded in parent's OnRowDataBound event
Here is My aspx.cs code
protected void CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvParentRow in gvDocSchedule.Rows)
{
if (gvParentRow.RowType == DataControlRowType.DataRow)
{
GridView gvDocSchedulesGetChildGrid = (GridView)gvParentRow.FindControl("gvScheduleDayNTime");
if (gvDocSchedulesGetChildGrid != null)
{
foreach (GridViewRow gvChildRow in gvDocSchedulesGetChildGrid.Rows)
{
CheckBox CBoxAvailabilityTime1 = (CheckBox)gvChildRow.FindControl("CBoxAvailabilityTime1");
CheckBox CBoxAvailabilityTime2 = (CheckBox)gvChildRow.FindControl("CBoxAvailabilityTime2");
if (((CheckBox)CBoxAvailabilityTime1).Checked)
{
CBoxAvailabilityTime2.Enabled = false;
}
if (!((CheckBox)CBoxAvailabilityTime1).Checked)
{
CBoxAvailabilityTime2.Enabled = true;
}
}
}
}
}
}
With this setup CheckChanged Event Fires on Checking.
On Checking it hits Page_ Load skips if(!IsPostBack) (as AutoPostBack=true) and then control is directly transferred to
CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e) event handler function
but on the other hand it doesn't fire on unchecking it postsbacks goes to Page load again Skips if(!IsPostBack) and does nothing instead of calling
CBoxAvailabilityTime1_CheckedChanged(object sender, EventArgs e)
"Note:-" Page_Load is not involved. I can't bind parent grid in page_load,
!IsPostBack because I dont need to bind it at first time when page gets loaded rather its binding happens inside a button click event, if a button is clicked only then parent grid must get binded.
Update 1:- This is how I bind data to parent grid
I am calling this function in a button click event
protected void BindDataToGridViewDocInArea()
{
using (SqlConnection con = new SqlConnection(constr))
{
con.Open();
SqlCommand cmdFillGridDocInArea = new SqlCommand("some query with parameter here", con)
cmdFillGridDocInArea.Parameters.AddWithValue("#AID", ddlAskArea.SelectedValue);
SqlDataAdapter sdaFillGridDocInArea = new SqlDataAdapter(cmdFillGridDocInArea);
DataTable dtFillGridDocInArea = new DataTable();
sdaFillGridDocInArea.Fill(dtFillGridDocInArea);
if (dtFillGridDocInArea.Rows.Count > 0)
{
gvDocSchedule.DataSource = dtFillGridDocInArea;
gvDocSchedule.DataBind();
}
else
{
lblError.Text = string.Empty;
lblError.Text = "No Record Exists Against Requst Specified";
}
con.Dispose();
}
}
Tested a stripped down version of you snippet. It seems to be working. When you check CBoxAvailabilityTime1, it disables CBoxAvailabilityTime2. When you uncheck CBoxAvailabilityTime1 the other one is enabled again.
However this is only when the DataBinding of gvDocSchedule is inside an IsPostBack check. When it's not the checkboxes will always go to their default unchecked state after PostBack.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//this works
gvDocSchedule.DataSource = LoadFromDB();
gvDocSchedule.DataBind();
}
//this does not
gvDocSchedule.DataSource = LoadFromDB();
gvDocSchedule.DataBind();
}
Or in your case something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindDataToGridViewDocInArea();
}
}

ASP updatepanel doesn't refresh ajax tabpage

I have an ajax tabcontainer in an updatepanel with all tabpages set visible until you want to add a tabpanel based on the dropdownlist selected value
CODE:
<cc1:TabContainer ID="tabControlParameters" runat="server" CssClass="ajax__tab_xp"
ScrollBars="Both" ActiveTabIndex="15" UseVerticalStripPlacement="True">
<%--EnvironmentTab --%>
<cc1:TabPanel ID="pnlEnvironment" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="pnlDatabase" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="pnlFirstError" HeaderText="Environment" runat="server" Visible="false">
<ContentTemplate>
//somecontent
</ContentTemplate>
</cc1:TabPanel>
With a button add which is inside the Updatepanel and has a correct async trigger assigned to it.
From C# codebehind I've made a loop to check if the dropdownlist selectedvalue = panel_headertext if so make it visible
CODE:
protected void btnAddParameters_Click(object sender, EventArgs e)
{
String Parameter = ddlParameterTypes.SelectedValue.ToString();
AjaxControlToolkit.TabContainer container = (AjaxControlToolkit.TabContainer)tabControlParameters;
foreach (object obj in container.Controls)
{
if (obj is AjaxControlToolkit.TabPanel)
{
AjaxControlToolkit.TabPanel tabPanel = (AjaxControlToolkit.TabPanel)obj;
if (tabPanel.HeaderText == ddlParameterTypes.SelectedValue)
{
tabPanel.Visible = true;
tabPanel = tabControlParameters.ActiveTab;
container.ActiveTab = tabPanel;
}
}
}
}
Now this works perfectly if the updatepanel trigger is set to fullPostback but it's set to async postback then it only works on the first click even though the event is fired every time I'm clicking on the button. Am I missing something obvious here?
Petar
You have the same value in HeaderText for each of your TabPanels. I think it'll work if you correct the HeaderText attributes.

How to call JavaScript function in GridView Command Field?

I have return one Javascript function which asks the confirm message to the user.
The JavaScript functions is
function ConfirmOnDelete() {
if (confirm("Are you sure to delete?"))
return true;
else
return false;
and GridView is like below:
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" />
Here I want to call the JavaScript function when user clicking the Delete in the GridView Command Field.
How to call this?
Assuming you want to keep using your CommandField, you could do this programmatically using your GridView's OnRowDataBound event.
Specify the event handler for the RowDataBound event in your GridView declaration:
<asp:GridView ID="gv" runat="server" OnRowDataBound="gv_RowDataBound"....
Then in your event handler (code-behind) find your button (here I'm assuming ImageButton, though this depends on your ButtonType property in your CommandField) and add JavaScript to its OnClientClick property.
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
((ImageButton)e.Row.Cells[cell].Controls[ctrl]).OnClientClick = "return confirm('Are you sure you want to delete?');"; // add any JS you want here
}
}
In the above example, cell refers to the column index of your CommandField and ctrl refers to the control index (Delete button) within the cell you're referencing.
You better avoid ask the confirmation for deletion on the server side, capture the user final decision using javascript then go to the server side to execute your logic. CommandField will not be the best solution here.
JS:
<script type="text/javascript">
function DeleteConfirm() {
if (confirm("Are you sure you want to delete this customer from excluded customer list ?")) {
return true;
}
return false;
}
</script>
HTML:
<asp:TemplateField HeaderText=" ">
<ItemTemplate>
<asp:LinkButton ID="lnk_RemoveFromlist" runat="server" Text="Delete"
CommandName="Delete" OnCommand="Delete_Command" CommandArgument='<%# Eval("ID").ToString()' OnClientClick='return DeleteConfirm()'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Code:
protected void Remove_Command(object sender, CommandEventArgs e)
{
//Implement your Delete Logic
}
for cancel button have command name as "cancel" and for delete button "delete" , check
if(e.CommandName == "delete")
{
//script to delete();
}
else if(e.commandName == "cancel")
{
//close with some script;
}
To call javascript function in codebehind,
Page.ClientScript.RegisterStartupScript(this.GetType(), "Call my function","loadPopupBox();", true);
In general you have to specify OnClientClick="return confirm('Are you sure you want to delete ?');" but that doesn't work with CommandField better use TemplateField, this explains better http://davesquared.net/2007/10/confirm-delete-for-gridview.html
you can use OnClientclick event of button to call the function.For example
<asp:button id="btndelete" runat="server" Text="delete" Onclientclick="if(!ConfirmOnDelete())return false;"/>
HTML:
<asp:GridView ID="GridView1" runat="server" OnRowDeleting="gv1_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:CommandField ShowDeleteButton="true" HeaderText="delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CODE:
protected void gv1_RowDeleting (object sender, GridViewDeleteEventArgs e)
{
GridView1.Attributes.Add("OnClick", "return confirm('Really wanna delete?');");
// implement your delete logic
Response.Write("<script>alert("Delete Successful");</script>");
}
This will Call Javascript function when we will click on "Delete" Command Field in Gridview and Response.write function will give an alert that data has been deleted. You can add whwtever function you want to execute in this function.
use start up script
ScriptManager.RegisterStartupScript(Page, this.GetType(), "ConfirmOnDelete", "ConfirmOnDelete();", true);
or you can also use onclientclick as well

Programmatically access GridView columns and manipulate

I have a GridView :
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" GridLines="None"
HorizontalAlign="Left" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1" onrowcommand="GridView1_RowCommand1">
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:TemplateField HeaderStyle-Width="150">
<HeaderTemplate>
<b>Downloads</b>
</HeaderTemplate>
<ItemTemplate>
<!-- <asp:HyperLink ID="hyperlinkDownload" runat="server" NavigateUrl="" >Download
MP3</asp:HyperLink> -->
<asp:LinkButton CommandName="download"
CommandArgument='<%# Eval("Name") %>' runat="server">Download MP3</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView>
I want to query the value of a particular field in a DB and if it's true, display the LinkButton. if false, I want the linkButton not to be displayed.
is there a way to access the GridView programmatically and make visible certain of its columns or manipulate its items ?
help.
You can do this by adding a handler to the RowDataBound event. Add an event handler along this lines of this in your code behind:
protected void myGrid_RowDataBound(Object sender, GridViewRowEventArgs e)
{
var data = e.Row.DataItem as DataRowView;
if (data != null)
{
var lbtDownload = e.Row.FindControl("lbtDownload");
lbtDownload.Visible = (bool) data.Row["HasFileForDownload"];
}
}
In your markup, attach the event handler to the grid:
<asp:GridView OnRowDataBound="myGrid_RowDataBound" ...>
You will also need to assign an id to the LinkButton, matching the one that you are search for using the FindControl() method in the event handler.
Disclaimer: I am on currently a Linux machine with no chance of testing this. Please report any bugs in the code - feel free to correct them if you have editor rights.
Yes there is.
1) You need to subscribe the RowDataBound event.
2) Give the LinkButton an ID.
3) Insert in codebehind
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton _bt = e.Row.FindControl("ID") as LinkButton;
if(_bt != null)
{
// have a look at the e.row.DataItem and try to get the value of your desired visibility property
_bt.Visible = true;
}
}
}
4) If this does not work with accessing the DataItem, start thinking about a LinqDataSource.

Categories