Button command firing twice with ButtonField inside GridView inside UpdatePanel with FireFox - ajax

I have an update panel which contains a GridView, inside which is a ButtonField. Whenever I press the button I see Firefox doing two POST's (via Firebug). One gets aborted right away, but does reach the server. This causes problems on my server side code as the command (a copy) gets executed twice.
IE6 and IE8 do not exhibit this behavior.
Anyone know what's causing this or what I can do about it?
I've managed to reproduce the problem to its bare minimum on this page:
<form id="form1" runat="server">
<asp:XmlDataSource ID="XmlDataSource1" runat="server">
<Data>
<bla>
<wibble wobble="1" />
</bla></Data>
</asp:XmlDataSource>
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Label runat="server" ID="Counter" Text="0"></asp:Label>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="XmlDataSource1" onrowcommand="GridView1_RowCommand">
<Columns>
<asp:BoundField DataField="wobble" HeaderText="wobble"
SortExpression="wobble" />
<asp:ButtonField HeaderText="wobble" CommandName="IncrementWobble"
SortExpression="wobble" ButtonType="Image" ImageUrl="icons/page_copy.png" Text="increment" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</form>
While making this small version, I noticed that the problem only occurs with ButtonType="Image" and not with ButtonType="Button".
For completeness, the event handler:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "IncrementWobble")
{
int count = Int32.Parse(Counter.Text) + 1;
Counter.Text = count.ToString();
}
}

From here, I found a workaround:
Replacing the ButtonField with a TemplateField containing an ImageButton works around the problem. Good enough for me, but still seems like a bug in either ASP .NET or FireFox.

Related

RangeValidator in WebForms Page Fails with error

I have been tasked with maintaining an older webforms application without much training or experience.
I was asked to add a new field to an existing table and expose it in the web page. Here's the code to do that, which I modeled on other existing fields and code.
<asp:TextBox ID="PortableBarrelCompressionValuetextBox"
runat="server"
SkinID="FVTextBox"
Text='<%# Bind("PortableBarrelCompressionValue") %>'
<asp:RangeValidator
ID="RangeValidatorPortableBarrelCompressionValuetextBox"
runat="server"
ControlToValidate="PortableBarrelCompressionValuetextBox"
CssClass="failureNotification"
Display="Dynamic"
ErrorMessage="Whole Numbers Between 0 and 9999"
MaximumValue="9999"
MinimumValue="0"
Type="Integer"
Text='<%# Eval("PortableBarrelCompressionValue") %>'>
</asp:RangeValidator>
This only works correctly when the existing value is non-null (and of course, within range). If I change a valid number, say 22, to a different valid number, 200, it saves the change as expected.
However, if the value on an existing record was null and I try to add an integer, it fails with the error message:
Value {" is not a valid value for Int32."} System.Exception
It also fails if there is an existing, valid, value which deleted, with the same error.
This field is not required, so I have to allow for Nulls here.
I've learned enough in the last two days to decide this is happening because the field is an integer and that the Null can't be converted to a string for the validation (at least that's what I'm assuming now).
If that is true, and this is the problem, I need to find a way to resolve that.
Am I on the right track?
Is there a way to provide a validation that will also accept nulls in this field, in addition to integers in the proper range?
Thanks in advance.
This does not throw your error
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="FredWebForm.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<%--bind only used with controls that have datasource eg grid--%>
<asp:TextBox runat="server" Text='<%# GetStatus("PortableBarrelCompressionValue") %>' ID="MyTextBox" />
<asp:RangeValidator
ID="RangeValidatorPortableBarrelCompressionValuetextBox"
runat="server"
ControlToValidate="MyTextBox"
CssClass="failureNotification"
Display="Dynamic"
ErrorMessage="Whole Numbers Between 0 and 9999"
MaximumValue="9999"
MinimumValue="0"
Type="Integer"
Text='Needs to be a number between 0 and 9999'>
</asp:RangeValidator>
</asp:Content>
Code behind
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataBind();
}
}
protected string GetStatus(string theID)
{
return null;
}
}
I finally figured out my error.
It was not in this section at all.
I didn't realize that the definition of the LingDataSource for the form has to be updated as well.
Once I added this line:
<asp:Parameter Name="PortableBarrelCompressionValue"
ConvertEmptyStringToNull="true" />
It came back to life.
Thanks for all the support.

Telerik + RadChart: How to call a Server side Method on ClientSeriesClick Event

I have implemented a module where i am using telerik red bar chart.And i want to generate another bar graph on click on bar of existing chart i.e there are two charts one is shown on page load and second is detailed one which is shown after click on any bar of first chart.Have mentioned my code below:-
<asp:Panel ID="Panel1" runat="server">
<telerik:radhtmlchart id="RadHtmlChart2" runat="server" width="600" height="400"
onclientseriesclicked="OnClientSeriesClicked">
<%-- <ClientEvents OnSeriesClick="OnSeriesClick" />--%>
<PlotArea>
<Series>
<telerik:ColumnSeries Name="Series 1">
<SeriesItems>
<telerik:CategorySeriesItem Y="30" />
<telerik:CategorySeriesItem Y="10" />
<telerik:CategorySeriesItem Y="20" />
</SeriesItems>
</telerik:ColumnSeries>
</Series>
<XAxis>
<LabelsAppearance RotationAngle="33">
</LabelsAppearance>
<Items>
<telerik:AxisItem LabelText="Item 1" />
<telerik:AxisItem LabelText="Item 2" />
<telerik:AxisItem LabelText="Item 3" />
</Items>
</XAxis>
</PlotArea>
</telerik:radhtmlchart>
<asp:Panel ID="Panel2" runat="server">
//My Second chart Shown Here
</asp:Panel>
</asp:Panel>
Above code i have used for generating my first chart
Second Chart which i am trying to fill in my asp Panel2.
protected void RadAjaxManager1_AjaxRequest(object sender, Telerik.Web.UI.AjaxRequestEventArgs e)
{
RadHtmlChart chart = new RadHtmlChart();
chart.ID = "chart2";
ColumnSeries cs = new ColumnSeries();
CategorySeriesItem csi = new CategorySeriesItem();
cs.DataFieldY = "TOTALCALLS";
cs.SeriesItems.Add(csi);
chart.PlotArea.Series.Add(cs);
Panel2.Controls.Add(chart);
}
My Ajax Call
<telerik:radcodeblock id="RadCodeBlock1" runat="server">
<script>
function getAjaxManager() {
return $find("<%=RadAjaxManager1.ClientID%>");
}
</script>
</telerik:radcodeblock>
I just want to fill second bar graph i.e i want to use client seriesevent for calling my server side method in red chart
Invoke an AJAX request through the RadAjaxManager client-side API: http://docs.telerik.com/devtools/aspnet-ajax/controls/ajax/client-side-programming/overview. Something like:
getAjaxManager().ajaxRequest("someOptionalArgument");
You can find similar code in the drilldown chart demo: http://demos.telerik.com/aspnet-ajax/htmlchart/examples/drilldownchart/defaultcs.aspx. It changes the datasource of the current chart but the client-side logic is the same.
On the server, just make sure to recreate the second chart with each subsequent postback, as any other server control.

How to Preview uploaded image using telerik RadAsyncUpload and RadBinaryImage in ASP Update Panel?

I have a web form in asp.net contains a RadAsyncfileupload and a RadBinaryImage inside an Asp Update Panel like following
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<telerik:RadAsyncUpload ID="RadAsyncUpload1" runat="server">
</telerik:RadAsyncUpload>
<telerik:RadBinaryImage ID ="RadBinaryImage1" runat ="server" Width= "100px" Height="100px"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
in code behind
protected void RadAsyncUpload1_FileUploaded(object sender, Telerik.Web.UI.FileUploadedEventArgs e)
{
if (RadAsyncUpload1.UploadedFiles.Count == 1)
{
byte[] image;
long fileLength = RadAsyncUpload1.UploadedFiles[0].InputStream.Length;
image = new byte[fileLength];
RadAsyncUpload1.UploadedFiles[0].InputStream.Read(image, 0, image.Length);
RadBinaryImage1.DataValue = image;
}
}
but in runtime program controller does not fire RadAsyncUpload1_FileUploaded event
I have searched the Telerik forum and found that I should do something to script manager but I need some help on how to do it the reason is that in order to fire this event whole page should post back anyway some scripts can help me or any other ways!
mention that I need byte array of the image to save it in DB.
Thanks in advance
Saeed Soleimanifar
http://demos.telerik.com/aspnet-ajax/asyncupload/examples/persistuploadedfiles/defaultvb.aspx?#qsf-demo-source
I just added the same functionality by using this , if you find any problem let me know...
OR
Here is the part that does the magic
Page Source :
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script type="text/javascript">
function updatePictureAndInfo() {
__doPostBack('btnImgUpload', 'RadButton1Args');
}
</script>
</telerik:RadScriptBlock>
<telerik:RadBinaryImage runat="server" ID="imgBinaryPhoto" ImageUrl="~/Images/default-profile-pic.png"
Width="100px" Height="100px" ResizeMode="Fit" AlternateText="No picture available"
CssClass="preview"></telerik:RadBinaryImage>
<br />
<telerik:RadAsyncUpload ID="upldPhoto" runat="server" AllowedFileExtensions=".jpg,.png,.gif,jpeg,.tiff"
MaxFileInputsCount="1" MultipleFileSelection="Disabled">
</telerik:RadAsyncUpload>
<asp:Button ID="btnImgUpload" runat="server" Text="Upload" CssClass="button" OnClientClick="updatePictureAndInfo(); return false;" />
Code Behind:
Protected Sub FileUploaded() Handles upldPhoto.FileUploaded
Dim bitmapImage As Bitmap = ResizeImage(upldPhoto.UploadedFiles(0).InputStream)
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream()
bitmapImage.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp)
imgBinaryPhoto.DataValue = stream.ToArray()
End Sub

Changing the message when using UpdateProgress

I dont know if this is possible or not but I was wondering if there is a way to change a message in the UpdateProgress when using Ajax. I tried put the message in a label and for some reason i cant do it that way so just wondering you can how to do that. Here is what I have below.
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Logining In...
</ProgressTemplate>
</asp:UpdateProgress>
Just do like this
Page:
<asp:UpdateProgress ID="UpdateProgress1" runat="server" ClientIDMode="Static">
<ProgressTemplate>
<div id="overlay">
<asp:Label ID="lbl_wait" runat="server" clientIDMode="Static">Logining In...</asp:Label>
</div>
</ProgressTemplate>
</asp:UpdateProgress>
Code:
(UpdateProgress1.FindControl("lbl_wait") as System.Web.UI.WebControls.Label).Text = "Logged In...";

Only one instance of a ScriptManager can be added

Why do I get this error message: Only one instance of a ScriptManager can be added to the page?
I haven't been using HTML comment to hide an ASP.NET server tag and there is no other ScriptManager in the entire project.
Markup:
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="lblCount" CssClass="LikeCount" Text='<%#Eval("LikeCount") %>' runat="server"></asp:Label>
<asp:LinkButton ID="lbAddOne" CssClass="LikeAddOne" Text="+1" runat="server" OnClick="lbAddOne_Click" CommandArgument='<%#Eval("ReviewID") %>'></asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
Code-behind:
protected void lbAddOne_Click(object sender, EventArgs e)
{
LinkButton _sender = (LinkButton)sender;
string ReviewID = _sender.CommandArgument;
int UserID = ((User)Session["LoggedInUser"]).UserID;
lblCount.Text = (int.Parse(lblCount.Text) + 1).ToString();
CategoryAccess.AddLikeReview(ReviewID, UserID);
}
just add a reference to scriptmanager in the masterpage, then it will be available to any page referencing the master. this will be easier to maintain in the long run rather than adding references to individual pages.

Resources