button in gridview triggers all validators when it should not - c#

Let me start off by saying I know how to use CausesValidation and ValidationGroup. I have bizarre situation where I have an Ajax Tab container. Each tab has a gridview and the rows that generate in the gridviews all have a TemplateField containing an 'Add' button. The buttons in the gridview and tab containers all use ValidationGroup to prevent any cross contamination and all the 'Add' buttons are set to CausesValidation = "false"
I just added the last gridview and the 'Add' button triggers all validators on the page. Once more the 'Add' button is set as CausesValidation = "false" so there is NO reason for it to behave in this fashion. I even set this value on the front end AND in the code behind.
For attempts I have tried the suggestions in these links: "Solution 1" and "Solution 2"
Has anyone else come across this and found a solution?
Edit Request for code:
I will post only the Tab Panel in question as the whole container is almost 500 lines
<asp:TabPanel ID="tab_Browse" runat="server" HeaderText="Browse">
<ContentTemplate>
<table id="browseTable">
<tr>
<td>Category</td>
<td>
<asp:DropDownList ID="browseDDL" runat="server" AppendDataBoundItems="True">
<asp:ListItem Text="All categories" Value="999"></asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Button ID="btnBrowse" runat="server" Text="Browse" ValidationGroup="vgBrowse" OnClick="btnBrowse_Click" />
</td>
</tr>
</table>
<asp:GridView ID="gvBrowse" runat="server" AutoGenerateColumns="false" AllowPaging="true" PageSize="8"
OnPageIndexChanging="gvBrowse_PageIndexChanging" DataKeyNames="foodId"
OnRowDataBound="gvBrowse_RowDataBound" Width="790px">
<Columns>
<asp:TemplateField HeaderText="Food ID" Visible="false">
<ItemTemplate>
<%# Eval("foodId") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<%# Eval("Shrt_Desc") %> (100g)
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Calories" ItemStyle-Width="50px">
<ItemTemplate>
<%# Eval("cals") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fat Grams" ItemStyle-Width="75px">
<ItemTemplate>
<%# Eval("fat") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Carbs" ItemStyle-Width="50px">
<ItemTemplate>
<%# Eval("carbs") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-Width="110px">
<ItemTemplate>
<asp:Button ID="browseAdd" runat="server" CausesValidation="false" Text="Add to meal" CommandArgument="Standard" OnClick="showingEntry" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle CssClass="gvRowStyle" />
<HeaderStyle CssClass="gvHeader" />
<AlternatingRowStyle CssClass="altRow" />
</asp:GridView>
</ContentTemplate>
</asp:TabPanel>
Edit 2 Another interesting tidbit. If I put OnClientClick="alert(Page_IsValid)" on my add button it returns true even though the validators in the others tabs are triggered. if i click the button a second time it returns false and my codebehind fails as if the page posted back but skipped the OnDataBound method

I ended up resolving this problem by preloading the gridview with an empty row. Makes no sense as to why this resolved the problem, but it does.

Related

Unable to maintain data inside gridview across postback when used inside an user control

I've a textbox that is present inside a GridView that itself is a part of user control and I'm dynamically loading this user control on page_Init.
The controls in my user control are a DropDown, a TextBox and a GridView.
Now DropDown and TextBox are able to retain values across postback but textboxes inside the GridView are not retaining the values.
Adding User Control on page init:
if (postBackCntrl.Contains("AddUserControlButton"))
{
UserControl newGrid = (UserControl)LoadControl("~/UserControl.ascx");
newGrid.ID = "test" + gridList.Count;
gridList.Add(newGrid);
}
GridView Code: TextBoxes inside GridView ItemTemplate not able to retain values across postback:
<asp:GridView runat="server" ID="grdUser" CssClass="GridTable" Width="90%" AutoGenerateColumns="false"
ShowFooter="true" OnDataBound="MergeGridViewFooter">
<Columns>
<asp:TemplateField HeaderText="ContactUs">
<ItemTemplate>
<asp:TextBox ID="txtContactUs" runat="server" CssClass="textbox" Height="60px" TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnaddrow" runat="server" Text="Add Row" CssClass="ui-button jquery-ui" Style="font-size: 12px" OnClick="btnaddrow_Click" />
<asp:Button ID="btnDelRowAddress" runat="server" Text="Delete Row" CssClass="ui-button jquery-ui" Style="font-size: 12px" OnClick="btnDelRowAddress_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Definition">
<ItemTemplate>
<asp:TextBox ID="txtDefinition" runat="server" TextMode="MultiLine" Height="60px" CssClass="textbox"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Address">
<ItemTemplate>
<asp:TextBox ID="txtAddress" runat="server" TextMode="MultiLine" Height="60px" CssClass="textbox"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Set Item limit to be display in ajaxToolkit ComboBox or set the Combobox position downwards in asp.net

I have a ajaxtoolkit combobox inside a gridview and it works perfectly, but the problem is when I click the dropdown button the list overlaps the page so I want to limit the number to be displayed to 10 items per scroll. Next problem is when I try to add an update panel to the page, It destroys the rendering of the combobox. How can I solve this? Thanks in advance
here is my code for the combobox inside the gridview
<asp:GridView CssClass="pad" ID="dgvOrder" runat="server" BorderStyle="Double" AutoGenerateColumns="False" OnRowDataBound="dgvOrder_RowDataBound" OnRowDeleting="dgvOrder_RowDeleting" HorizontalAlign="Center" >
<Columns>
<asp:TemplateField HeaderText="No." AccessibleHeaderText="No.">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Description" AccessibleHeaderText="Description">
<ItemTemplate >
<ajaxToolkit:ComboBox ID="ddlItems" AutoPostBack="True" AppendDataBoundItems="True" onmouseover="this.size=4;" onmouseout="this.size=1;" DataTextField="item_desc" DataValueField="item_id" runat="server" AutoCompleteMode="Suggest" ItemInsertLocation="Prepend" OnSelectedIndexChanged="ddlItems_SelectedIndexChanged" DropDownStyle="DropDown" BorderStyle="Double" ></ajaxToolkit:ComboBox> <br />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="Please pick an item" ControlToValidate="ddlItems"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Inventory Code" HeaderText="Inventory Code">
<ItemTemplate>
<asp:Label ID="lblInvCode" runat="server" Text=""></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Qty" HeaderText="Qty">
<ItemTemplate>
<asp:TextBox ID="txtQty" runat="server" OnTextChanged="txtQty_TextChanged" AutoPostBack="True" onkeyup ="ValidateText(this);"></asp:TextBox><br />
<asp:RequiredFieldValidator ID="RequiredFieldValidator23" runat="server" ErrorMessage="Please input qty" ControlToValidate="txtQty"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="UOM" HeaderText="UOM">
<ItemTemplate>
<asp:Label ID="lblUOM" runat="server" Text=""></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="SOQ" HeaderText="SOQ">
<ItemTemplate>
<asp:Label ID="lblSOQ" runat="server" Text=""></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Reason" HeaderText="Reason">
<ItemTemplate>
<asp:TextBox ID="txtReason" runat="server" Enabled="False"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
and here is my code for the updatepanel
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
</ContentTemplate>
<Triggers>
(whole page inside)
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="txtIdNo" EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
Long Item Lists / Multiple Input Controls
All of the items in a ComboBox's list will be rendered to the web page it exists in. The AutoCompleteExtender, on the other hand, retrieves items from its ServiceMethod after the page is rendered. When your ComboBox contains a rather long list of items, or when you have a relatively large number of ComboBoxes on the same page (or within the same UpdatePanel), load times could be slowed down significantly. When ComboBoxes perform slowly because of the amount of markup they must render to the browser, an AutoCompleteExtender can be used instead to increase performance.
<ajaxToolkit:ComboBox ID="ComboBox1" runat="server"
DropDownStyle="DropDown"
AutoCompleteMode="None"
CaseSensitive="false"
RenderMode="Inline"
ItemInsertLocation="Append"
ListItemHoverCssClass="ComboBoxListItemHover"
<asp:ListItem>...</asp:ListIem>
...
For more information your can look it in this link.

Click event for ItemTemplate inside asp:GridView

I have a Gridview with the following markup:
<asp:GridView ID="gdvResxKeyValue" runat="server" Width="100%" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="imgEditResxValue" CssClass="sfEdit" runat="server" ImageUrl="~/Administrator/Templates/Default/images/imgedit.png" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I need to have a handler for the Image click event. Is there any easier way to do so?
You can use an Image Button instead of Image. Try this code.
<asp:GridView ID="gdvResxKeyValue" runat="server" Width="100%" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="imgEditResxValue" CssClass="sfEdit" runat="server" ImageUrl="~/Administrator/Templates/Default/images/imgedit.png" OnClick="YourEventName" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You just need to specify your server side event name here.
Use an asp button and set its style to be display:none
<asp:Image ID="imgEditResxValue" CssClass="sfEdit" runat="server" ImageUrl="~/Administrator/Templates/Default/images/imgedit.png" onclick="ClickImage(this)" />
.......
<asp:Button ID="hiddenButton" runat="server" OnClick="hiddenButton_Click" style="display:none"></asp:Button>
<script type="text/javascript">
function ClickImage(imageControl)
{
document.getElementById('<%=hiddenButton.ClientID%>').click();
}
</script>
This will raise the server side event of the button and you can do your work there.
Try this:
jquery Solution
<asp:Image ID="imgEditResxValue" CssClass="sfEdit" runat="server" ImageUrl="~/Administrator/Templates/Default/images/imgedit.png" onclick="this.next().click()"/>
<asp:LinkButton Text="text" runat="server" OnClick="call_method"/>

DropDownList event within Accordian and GridView

An event bound to a DropDownList in a standalone GridView obviously would work in this fashion , but things are bit more complicated in this scenario.
The event does not fire for the DropDownList. What's interesting is the event bound to the Button Does fire. Not sure what the difference would be between the DropDownList and TextBox.
I've tried both OnSelectedIndexChanged and OnTextChanged - neither work.
The nesting is as follows:
GridView A
Ajax Accordion
GridView B (With DropDownList)
<AjaxToolkit:AccordionPane ID="AccordionPane1" runat="server">
<Header>
</Header>
<Content>
<asp:GridView runat="server" ID="gv" AutoGenerateColumns="false"
BorderWidth="0" AlternatingRowStyle-BorderStyle="None" ShowFooter="true">
<Columns>
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<asp:Label runat="server" ID="lblId" Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label runat="server" ID="lblType"></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList runat="server" ID="ddlType" OnTextChanged="ddlType_SelectedIndexChanged"
AutoPostBack="true">
</asp:DropDownList>
<asp:Button runat="server" ID="btnTest" OnClick="btnTest_Click" Text="TEST" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</Content>
Thank you!
UPDATE
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(object);
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(obj);

asp.net with c#

I have one page which is placed in the Master Page.
In the master page I have 1 dropdown and one GridView, dropdown is display the category, based on the dropdown list selection it will display the list of videos in the Grid.
In the content page I have the video player, in the page load it will play the video by default.
But when I choose the drop down list which is available in the master page, the page is refreshing, SO the video is start play from the first.
The content page should not refresh, So the video will continuously play.
How can I stop the page refresh in the content page?
All are in master page.
`<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<asp:DropDownList ID="drp_Channel" Width="220px" CssClass="ddl"
AutoPostBack="true" runat="server"
onselectedindexchanged="drp_Channel_SelectedIndexChanged">
<asp:ListItem>-- Select Channels --</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="up2" runat="server" UpdateMode="Conditional">
<asp:GridView ID="grd_Video" runat="server" AutoGenerateColumns="False" OnRowCommand="LinkName"
GridLines="None" ShowHeader="False" Width="100%" EmptyDataText="No Videos Found" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="img_Video" runat="server" BorderColor="#666699" CssClass="imgbox"
ImageUrl='<%#(string)FormatImageUrl((string)Eval("Video_Thumbnail")) %>'
CommandName="imgClick" CommandArgument='<%# Bind("Video_ID")%>'
BorderWidth="0px" Height="40px" ToolTip="Click to view video" Width="50px"
BorderStyle="Double" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnk_VideoName" runat="server" ToolTip="Click to view video"
CommandName="lnkClick" CommandArgument='<%# Bind("Video_ID")%>'
Text='<%# DataBinder.Eval(Container, "DataItem.Video_Name") %>'
CssClass="linkVideo" Width="130px"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="#cccccc" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>`
in code behind for binding grid,
DataTable dt1Video = new MDBusiness.MDSUser().GetVideo(intNetId, intChanId, intCatId);
grd_Video.DataSource = dt1Video;
grd_Video.DataBind();
up1.Update();
up2.Update();
Set AutoPostBack = "False" on your dropdownlist to stop the postback from occurring. Users will then be able to change the dropdownlist without anything happening.
You'll need to use AJAX with your dropdownlist if you want to be able to use it without the postback.
for a quick answer
Install ASP.NET AJAX library
Wrap the GridView in a UpdatePanel
Set the trigger to be the DropDownList
Done :)
Remember to see this Screencast... it is exactly what you are after!

Categories

Resources