Hi All i am using the below code and wanted to make a button visible and invisible based on checkbox status. I am using the trigger to call a event where i will write code to make that button visible or invisible. If i use the below code i get an error like "System.InvalidOperationException: A control with ID 'chkDelete' could not be found for the trigger in UpdatePanel 'UpdatePanel1'." Please help me.
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers ="false">
<ContentTemplate>
<asp:GridView ID="gvEventMechanic" runat="server" AutoGenerateColumns="False" PageSize="5"
GridLines="None" AllowSorting="true" BorderWidth="1"
EnableViewState="true" AllowPaging="true">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Disable
</HeaderTemplate>
<ItemStyle HorizontalAlign="Center" />
<ItemTemplate>
<asp:CheckBox ID="chkDelete" runat="server" AutoPostBack="true" ></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="chkDelete" EventName="CheckBoxEventChanged" />
</Triggers>
</asp:UpdatePanel>
As an alternative, why don't you use client-side environment to do this? It's more easy and more native.
$('#input[type=checkbox][id*=chkDelete]').change(function(){
$('#button').toggleClass('disabled');
});
Now, based on this class, you can use CSS to dim your button, if it's a span, or a div (custom button). Otherwise you can use:
$('#input[type=checkbox][id*=chkDelete]').change(function(){
if ($(this).is(':checked'))
{
$('#button').removeAttr('disabled');
}
else
{
$('#button').attr('disabled', 'disabled');
}
});
This will let you get all the information you need to delete the appropriate record.
// If you bind a list of objects as your data source you can use this to get the
// index into the list.
protected void OnCheckedChanged( Object sender, EventArgs e )
{
if ( sender is CheckBox )
{
// we do this to get the index into the list of the item we want to work with.
CheckBox cb = sender as CheckBox;
GridViewRow gvr = cb.NamingContainer as GridViewRow;
int dataItemIndex = gvr.DataItemIndex; // index into your list, regardless of page
int rowIndex = gvr.RowIndex; // row index in gridview.
}
}
ControlId for the CheckBox field <asp:CheckBox ID="chkDelete" runat="server" AutoPostBack="true" ></asp:CheckBox> will different for each row that is why it can't map the controlId to the trigger.
I suggest you to use checkbox's CheckedChanged event to trigger your method.
Yes it is CheckedChanged.
Although it doesnot look what you have mentioned in checkbox. but it works this way.
Related
On client side button click event, I want to get control id that are place in Item template of Grid View. I tried this code but it doesn't work. Thanks
function buttonClicked(sender, args) {
var gv = $find('<%= GridView1.ClientID %>');
var textbox = $GridView1.findControl(gv.get_element().parentNode, "Textbox");
}
Here is the Gridview
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="upTest" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" DataSourceID="KurzDS" DataKeyNames="Id" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="Textbox" runat="server" Text="Textbox"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="Textbox1" runat="server" Text="Textbox1"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn" Text='btn' CommandArgument='<%# Eval("Id")%>' CommandName="btn" runat="server" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
Thanks for including the GridView example. Now that I can see what you are attempting, I have a much better answer for you.
First, make a slight change to the button template, change out CommandArgument for OnClientClickand since you are using this button client side instead of posting back to the server, you can simplify it like this:
<asp:Button ID="btn" Text='btn' OnClientClick='<%# Eval("ID", "YourJavascriptFunction({0} - 1); return false;") %>' runat="server" CausesValidation="false" />
I have the click event call your JavaScript function and it sends in a parameter of the server side resolved id. Notice I subtract 1 first though. This is because the server side ASP.Net Eval function give the ID starting at 1. But, each of the ids that get generated for your text input elements start with a zero base.
Now look at the JavaScript function below.
// Clicking the first button sends in a 0, second sends in a 1, etc.
function YourJavascriptFunction(id) {
// each of the TextBox1 elements has an ASP.Net server side
// generated id that ends with GridView2_Textbox1_0,
// GridView2_Textbox1_1, etc.
let selectId = "input[id$='GridView2_Textbox1_" + id + "']";
// The text we use in the querySelector function states
// find the DOM element with a tag of "input" where the id
// ends with . . . The $ in id$= is the part that says the
// value must "end with"
let textBox1 = document.querySelector(selectId);
// Now that we have TextBox1 from the same row as the button,
// getting the value is easy.
alert(textBox1.value);
}
I left off a jQuery example as this querySelector command works in almost every browser including IE8 and above, so you shouldn't need jQuery for something this simple.
Let me know if I can help further.
In my application i have export button when i click grid view in edit command i want to disable export button after it will enable. I disable export button in Edit command but when i click edit button it shows disable in minute seconds and after page post back it is enable how can i disable export button with or without post back when i click edit command.
my code:
<asp:UpdatePanel ID="panl1" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl1" runat="server">
<asp:Button ID="btnExport" runat="server" OnClick="btnExport_Click" Text="Export" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<triggers>
<asp:PostBackTrigger ControlID="btnExport" />
</triggers>
<asp:GridView ID="GridView2" runat="server" Width="100%" CssClass="mydatagrid" HeaderStyle-CssClass="header" RowStyle-CssClass="rows" AutoGenerateColumns="false"
EmptyDataText="No files uploaded" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound" OnDataBound="GridView1_DataBound">
<Columns>
<asp:TemplateField HeaderText=" ">
<ItemTemplate>
<asp:ImageButton ID="Btn1" runat="server" Text="Edit" CommandName="mybutton" Width="20px" ImageUrl="~/images/page_white_edit.png" ToolTip="Edit" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Please tell me thank you.
Remove the UpdatePanel around btnExport, it makes no sense anyway since it's the only element in there and you cancel the UpdatePanel functionality by setting a PostBackTrigger to the button. Or place the GridView inside the UPdatePanel and keep the PostBackTrigger. Either way you can then just disable/enable the button on your edit commands in the GridView RowCOmmand method.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "mybutton_edit")
{
btnExport.Enabled = false;
}
else if (e.CommandName == "mybutton_cancelEdit")
{
btnExport.Enabled = true;
}
}
PS the <Triggers> must be placed inside <asp:UpdatePanel>.
I have two Buttons and GridView which are:
<asp:Button ID="btn-search" runat="server" OnClick=btn_search_Click />
<asp:Button ID="btn-export" runat="server" OnClick=btn_export_Click />
<asp:GridView ID="gridview1" runat="server" />
btn-search is a control to bind data to the gridview1 from an SqlDataSource. btn-export is disabled at Page_Load and will be enabled when gridview1 has at least one row (btn-export will stay disabled if there is no data/row in gridview1).
At first I wrote this in code behind:
protected void btn_search_Click(object sender, EventArgs e)
{
/* Binding data to GridView */
if (this.gridview1.Rows.Count > 0)
{
this.btn_export.Enabled = true;
}
}
and it worked.
But, then I have to wrap the gridview1 in an UpdatePanel so it wont refresh the whole page when data binding in GridView, using btn-search as AsyncPostBackTrigger.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Button ID="btn-search" runat="server" OnClick=btn_search_Click />
<asp:Button ID="btn-export" runat="server" OnClick=btn_export_Click />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="gridview1" runat="server">
<Columns>
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_search" />
</Triggers>
</asp:UpdatePanel>
When the data was bound to gridview1, the btn-search still disabled.
I try to write this.btn_export.Enabled = true in GridView and UpdatePanel event such as OnDataBound, OnDataBinding, OnRowDataBound but it still not worked.
Grayfield, it doesnt work because when you click the search button only the update panel content is updated.
Try adding the buttons inside the ContentTemplate of the update panel and it should work.
<asp:UpdatePanel runat="server" ClientIDMode="Static" ID="TasksUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlDropDown" runat="server" ClientIDMode="Static" CssClass="pnlDropDown">
<!-- TASK NAME -->
<asp:DropDownList ID="ddlTaskName" CssClass="chosen-select" DataSourceID="dsPopulateTaskName" AutoPostBack="true" DataValueField="Task Name" runat="server" Width="100%" Font-Size="11px" AppendDataBoundItems="true" OnSelectedIndexChanged="ddlTaskName_onSelectIndexChanged">
<asp:ListItem Text="All" Value="%"></asp:ListItem>
</asp:DropDownList>
</asp:Panel>
<asp:GridView ShowHeaderWhenEmpty="false" AlternatingRowStyle-BackColor="#EBE9E9" AutoGenerateColumns="false" OnSorting="yourTasksGV_Sorting" AllowSorting="true" ID="yourTasksGV" runat="server" ClientIDMode="Static" EmptyDataText="You currently have no tasks assigned to you" OnRowDataBound="yourTasksGV_RowDataBound" OnRowCreated="yourTasksGV_RowCreated">
<Columns>
<asp:TemplateField HeaderStyle-Width="2%">
<ItemTemplate>
<asp:ImageButton ImageUrl="~/cies.png" runat="server" ID="btnShowDepend" OnCommand="btnShowDepend_Command" CommandName="TaskDepend" CommandArgument='<%#Eval("TestIt") %>' ToolTip="Click to view Dependencies" />
</ItemTemplate>
</asp:TemplateField>
<asp:HyperLinkField HeaderStyle-Width="16%" Target="_self" DataNavigateUrlFields="Task Detail" DataTextField="Task Name" DataNavigateUrlFormatString="" HeaderText="Task Detail" SortExpression="Task Name" ItemStyle-CssClass="taskTableColumn" />
<asp:BoundField HeaderStyle-Width="10%" DataField="Workgroup" HeaderText="Workgroup" SortExpression="Workgroup" ItemStyle-CssClass="taskTableColumn" />
<asp:BoundField HeaderStyle-Width="7%" DataField="Status" HeaderText="Status" SortExpression="Status" ItemStyle-CssClass="taskTableColumn" />
</Columns>
</asp:GridView>
</ContentTemplate>
<%--<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlTaskName" EventName="onSelectIndexChanged" />
</Triggers>--%>
</asp:UpdatePanel>
Whenever the ddlTaskName_onSelectIndexChanged function is executed there is a full page postback rather than just updating the UpdatePanel
ddlTaskName_onSelectIndexChanged function:
protected void ddlTaskName_onSelectIndexChanged(object sender, EventArgs e)
{
PullData(ViewState["sortExp"].ToString(), ViewState["sortOrder"].ToString(), false); //calls a function to update the GridView
}
With the above code, the page does a full postback rather than just partial (only update the GridView) whenever the index is changed in the ddlTaskName
What code can I add/modify to ensure the full postback isn't executed and only update the GridView on index changed.
Thought... Do I need to add them in two separate UpdatePanel?
If I uncomment the triggers, I get the following error: A control with ID 'ddlTaskName' could not be found for the trigger in UpdatePanel 'TasksUpdatePanel'.
I am attaching the dropdownlist to the Gridview like this:
Is it because of this:
protected void yourTasksGV_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView hGrid = (GridView)sender;
GridViewRow gvrRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableHeaderCell tcCellTask = new TableHeaderCell();
tcCellTask.Controls.Add(ddlTaskName);
gvrRow.Cells.Add(tcCellTask);
yourTasksGV.Controls[0].Controls.AddAt(0, gvrRow);
}
}
your code seems fine. did you try to comment out asp:Panel tab?
if you unccoment triggers, you need to put asp:UpdatePanel around gridview
As per this post it looks like your asp:Panel could be the culprit with the ClientIDMode="Static". Try changing this so it inherits.
You'd need to specify ChildrenAsTriggers="true" in your UpdatePanel tag. The error you're getting is because your dropdown doesn't physically exist in the markup, which is what a Trigger line expects to find during compliation/runtime - instead, you are adding it dynamically as a control in your RowCreated function. It might be possible to, in that same function, add a trigger to the UpdatePanel dynamically, if you wanted to try that, instead.
How do I preserve a value entered in a TextBox inside a gridview's templatefield when the gridview gets databound again?
Can anyone tell me why?
And maybe help me in finding a solution?
for example i Click on A button and click event is Gridview1.DataBind() but we lose all values on TextBoxes.
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
<ContentTemplate>
<%--post GridView--%>
<asp:GridView ID="posts" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<%--Comments Gridview--%>
<asp:GridView ID="comments" runat="server"></asp:GridView>
<%--a Textbox and bUtton For sending new Comment--%>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
protected void Button1_Click(object sender, EventArgs e)
{
posts.DataSource = GetData();
posts.DataBind();
}
Edit1
let me explain more , when a user send a new comment, i will broadcast a message ( with signalr) to all other users to update their Gridviews ( when a client get broadcast message button1_Click, will be call by a jquery ). my problem is if other users are typing new comments on their textboxes will lose their typed comments.
To store array of strings in SessionState object and then read it back refer to the following sample code snippets:
string[] _arr = {"a", "b", "c" }; // sample array - replace by 15 entries pertinent to your case
Session["arrString"] = _arr ;
Read it back from SessionState as:
string[] arrFromSession = (string[])Session["arrString"];
Hope this will help. Rgds,