asp.net Link button image not visible after postback - asp.net

I have a link button with image and label inside it.
After postback, the image and label is not visible.
< asp:LinkButton ID="AddNewRunLinkButton" runat="server" CssClass="Navigationlocalnav"
OnClick="AddNewRunLinkButton_Click" >
< img id="Img1" src="../../Images/add_newIcon.gif" runat="server" alt="Add New Run" />
< asp:Label ID="addText" Text=" Add New Run" runat="server"></asp:Label>
< /asp:LinkButton>
This link button is used to import/export data. I have added an attribute on click of this link button(AddNewRunLinkButton) to display a progress bar using javascript - SetInterval function.
If I remove this attribute, the image and label is getting displayed, otherwise only link button is getting displayed.
AddNewRunLinkButton.attributes.add("onclick","javascript:DisplayProgress()");
function DisplayProgress()
{
timeid = setInterval("addBlock",100)
}
function Addblock()
{
// Display a progress bar as follows - Increase the width of a div tag at this interval
}
Any help?

Since your code examples doesn't give much to go on I'm posting something I think might be what you're trying to do.
Markup and Javascript:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
var timeID = null;
var width = 0;
function DisplayProgress() {
timeID = setInterval('AddBlock();', 100);
}
function AddBlock() {
var p = document.getElementById("progressDiv");
if (width < 1000) {
width += 100;
p.style.width = width + "px";
}
else
timeID = clearInterval(timeID);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LinkButton runat="server" ID="lbAddNewRun" OnClick="lbAddNewRun_Click">
<img src="--url to an image--" alt="Add New Run" />
Add New Run
</asp:LinkButton>
</div>
<div id="progressDiv" style="background-color: Green; width: 0px; height: 20px;"></div>
</form>
</body>
</html>
Code-Behind:
protected void Page_Load(object sender, EventArgs e)
{
lbAddNewRun.Attributes.Add("OnClick", "javascript:DisplayProgress();");
}
protected void lbAddNewRun_Click(object sender, EventArgs e)
{
// Export/Import code.
}
This does not "hide" the image, for me atleast.
Remark:
Instead of adding the OnClick event in the code-behind you can add it directly in the markup since it is not dynamically created:
<asp:LinkButton runat="server" ID="lbAddNewRun" OnClick="lbAddNewRun_Click" OnClientClick="DisplayProgress();">
<img src="--url to an image--" alt="Add New Run" />
Add New Run
</asp:LinkButton>

I would use Async call to show the progress bar as opposed to what you are doing here. Sometime when you attach both client side and server side events, the page rendering doesnt work as expected. In this case you are using a Javascript timer with SetInterval and I believe that is causing the lable to disappear.

Related

How to get img src that changed by JavaScript in code behind C#.NET

this is my client code:
<form id="form1" runat="server">
<div>
<img id="mm" runat="server" />
</div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<script>
document.onclick = function () {
mm.src = "photo1.jpg";
}
</script>
</form>
and I try to get img src in code behind, but it returns null :
protected void Button1_Click(object sender, EventArgs e)
{
string s1= Request.Form["mm"];
string s2= mm.Attributes["src"];
string s3 = mm.Src;
}
How can I do this?
You simple can not. You can not get on code behind the srcof an image after have been change by javascript.
This is because this information is not travel back to server even by post back.
The work around is to save at the same time with the src to a hidden input control on the value... the same data.
So after the post back you read the value from that input control, because only that type of controls send back their values.
Here is an example base on your code
<asp:HiddenField runat="server" ID="ImgExSrc" />
<script>
document.onclick = function () {
mm.src = "photo1.jpg";
document.getElementById("<%=ImgExSrc.ClientID%>").value = mm.src;
}
</script>
and on code behind you just read the ImgExSrc.Value after the post back. Only with post back you can send your values to the server side.

Modal ASP.net user control

I have a web form app where a couple of user-controls have been developed and placed on a page where a customer is building an order. The user-controls are pretty extensive in what they do, causing post-backs, etc.
I'd like to display them in a modal fashion without putting them in a separate page (if possible). So therein lies my question.
Is it possible to place user-controls within divs/panels, display them modally and keep them displayed modally (even through postbacks) until the user clicks a button on the control to dismiss it?
I'm basically looking at the modal option because I need to disable the rest of the form while the user is dealing with the sections the user-control is on. So I'm looking for a best-practice approach I suppose and some nudges in the right direction for this.
Thanks!
ADDITION:
I wanted to update this with the code I wrote in hopes that it might help somebody else and also if there is a better way to implement this, then I'm all ears too.
The basics of this is that I'm passing everything back and forth between my user control and the container page through session vars. I use this to tell the container page whether or not the user control is "finished" and until the flag is set to true, the container page just keeps re-displaying the user control modally on each postback. Seems to work well so far.
Markup:
<%# Register Src="../controls/mylabel.ascx" TagName="mylabel" TagPrefix="uc1" %>
<div style="width: 100%;">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="ButtonAddToCart" runat="server" Text="Add to cart" OnClick="ButtonAddToCartClick" />
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel ID="pnlOutput" Visible="False" runat="server" Width="500px">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<div style="visibility: hidden;">
<asp:Button ID="ButtonHidden" runat="server" Text="Button" />
</div>
<asp:Panel ID="pnlDownload" Visible="False" runat="server">
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div style="width: 100%;">
<uc1:mylabel ID="mylabel1" runat="server" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
Code behind:
protected void Page_PreRender(object sender, EventArgs e)
{
InitializeControls();
}
protected void Page_Load(object sender, EventArgs e)
{
InitializeControls();
}
private void InitializeControls()
{
DisplayDownloadPanel(!SessionDownloadComplete);
if (SessionDownloadItemNumber != string.Empty)
{
Label1.Text = SessionDownloadItemNumber != "CANCEL" ? "Item ordered from control was: [" + SessionDownloadItemNumber + "]" : "Order was canceled.";
pnlOutput.Visible = true;
}
}
protected void ButtonAddToCartClick(object sender, EventArgs e)
{
bool haveWeSomeText = string.IsNullOrEmpty(TextBox1.Text) == false;
if (haveWeSomeText == true)
{
SessionDownloadComplete = false;
DisplayDownloadPanel(true);
}
}
private void DisplayDownloadPanel(bool show)
{
pnlDownload.Visible = show;
if (show == true)
{
ModalPopupExtender1.Show();
}
else
{
ModalPopupExtender1.Hide();
}
}
private string SessionDownloadItemNumber
{
get { return Session["DownloadItemNumber"] != null ? Session["DownloadItemNumber"].ToString() : string.Empty; }
}
private bool SessionDownloadComplete
{
get { return Session["DownloadComplete"] == null || Convert.ToBoolean(Session["DownloadComplete"]); }
set { Session["DownloadComplete"] = value; }
}
Have a look at ASP.NET Ajax Toolkit Modal popup extender
Take a look at the jQuery UI dialog.
It is a good solution for cross browser modal dialogs in the browser.
<script>
$(function() {
$( ".dialogClass" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Delete all items": function() {
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
});
</script>
There are a few initial hiccups integrating it with asp.net. But all those are very well documented here on stackover flow itself.

how to invoke server side and client side events in asp web forms

within an asp.net webform I have the following code
<asp:UpdatePanel ID="udpNames" runat="server">
<ContentTemplate>
<div class="expanderheaders">
<asp:Image ID="epImgNames" runat="server" ImageAlign="Middle" CssClass="expanderimage" />
<asp:LinkButton ToolTip="Expand Names" ID="lbtnNames" runat="server" OnClick="lbName_Click"
Text="Names" CssClass="detaillinks" />
</div>
<div class="detailsectionBorders">
<ajax:CollapsiblePanelExtender ID="epNames" runat="server" ExpandControlID="lbtnNames"
CollapseControlID="lbtnNames" Collapsed="true" ExpandedSize="420" ScrollContents="true"
ImageControlID="epImgNames" CollapsedImage="~/images/expandwn.png" ExpandedImage="~/images/expanup.png"
TargetControlID="namePanel" CollapsedSize="0" CollapsedText="Names" AutoExpand="false" />
<asp:Panel ID="namePanel" runat="server">
<asp:PlaceHolder runat="server" ID="PlaceHolderNames" />
</asp:Panel>
</div>
</ContentTemplate>
</asp:UpdatePanel>
DIV tag expanderheaders is a used as a header to the section. It contains a link button an image similar to a expander panel bar.
CollapsiblePanelExtnder is an ajax toolkit control that expands when a asp.net control is clicked (LinkButton) a user control is then loaded into the PlaceHolder to display a new section of data.
This all works fine but I am currently only able to click on the link button to expand the section (as expected). What I would like to do is have the ability to click on the entire div section (expanderHeaders) and have it serve as the control to expand the section.
I have looked at using jQuery and I have been able to duplicate the panel expansion as well as set the DIV layer to function as desired in accepting a client event and not just on an server side control. However, I have been unsuccessful in being able to invoke a server side method to load the user control when using jQuery.
Can anyone provide some guidance on how to either set the existing control up to where the link button could span the entire content of the div layer or use client side script/ jQuery to allow me to call a server side method to load a user control in the page?
Thanks in advance
update to James answer
I tried something similar to this
jquery
$(function () {
$("#panel").hide();
});
$(document).ready(function () {
$(".slide").click(function () {
$("#panel").show("slow");
});
});
and aspx
<div>
<div id="panel" >
<p>stuff here</p>
</div>
<div class="slide" id="div1" runat="server">
<p class="btn-slide">Expand Panel</p>
</div>
</div>
I'll omit the CSS as it is not that important for now
Using this approach clicking on the div layer seems to causes a postback each time clicked so the codebhind is never accessed.
protected void Page_Load (object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
div1.Attributes["onclick"] = ClientScript.GetPostBackEventReference(this, "ClickDiv");
}
}
protected override void RaisePostBackEvent (IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (eventArgument.ToUpper() == "CLICKDIV")
{
}
}
still no dice.
It would probably be easier to do this with jQuery:
//obviously, adjust this to your needs
$(document).ready(function(){
$(".expanderheaders").click(function(){
$(".detailsectionBorders").hide("slow");
}
});
To do it server-side, if you give the div an ID and can specify runat="server", you can do something like this:
<div id="div1" runat="server">
Expand Me
</div>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
div1.Attributes["onclick"] = ClientScript.GetPostBackEventReference(this, "ClickDiv");
}
}
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (eventArgument.ToUpper() == "CLICKDIV")
{
//logic here
}
}

ASP.NET TextBox OnTextChanged triggered twice in Firefox

Hi I'm facing a weird problem that only happens in FF. I have a TextBox control with OnTextChanged handler. The event handler is working fine most of the time, but when the user changed the text and press Enter in FF, the OnTextChanged event is called twice. I observed the problem in Firebug that the first request is actually canceled because of the second event.
Test.aspx
<%# Page Language="C#" AutoEventWireup="True" CodeFile="~/Test.aspx.cs" Inherits="T.Test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Custom TextBox - OnTextChanged - C# Example</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager runat="server" ID="SM">
</asp:ScriptManager>
<h3>Custom TextBox - OnTextChanged - C# Example</h3>
<asp:UpdatePanel runat="server" ID="Panel1">
<ContentTemplate>
<asp:Panel runat="server" ID="Panel2">
<asp:TextBox ID="TextBox1" AutoPostBack="true" OnTextChanged="OnTextChanged" runat="server">Hello World!
</asp:TextBox>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Test.aspx.cs
using System;
using System.Web.UI;
namespace T
{
public partial class Test : Page
{
protected void OnTextChanged(object sender, EventArgs e)
{
var a = 0;
}
}
}
Put a break point # var a, and you'll be able to see that after changing text and press enter in FF (v3.5.7), the OnTextChanged event is invoked twice.
So my question is, what's the best way to properly handle OnTextChanged event so that hitting enter in the textbox doesn't trigger double postback.
Regards,
I don't know why it's isolated to FireFox, but if you remove the AutoPostBack property, that will solve the problem.
There is also an explanation here of why it's posting back twice.
I know its an old thread but maybe helpful for others.
I had the same issue when validating the text entered. I was getting 2 events fired so I put this script at the top of the page which causes the enter to just tab to the next control instead of submitting the form. The text box remained the same AutoPostBack="true" OnTextChanged="xxx_TextChanged"
''''
<script type="text/javascript">
$('body').on('keydown', 'input, select', function (e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
</script>
''''

ASP.NET 3.5: Display UpdateProgress during Page_Load()

I am building an ASP.NET site using Visual Studio 2008 and have a page looking like this (stuff snipped)
<asp:Content ID="Content2" ContentPlaceHolderID="PageContentPlaceHolder" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
the page here..
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="100">
<ProgressTemplate>
<div>
<asp:Image ID="AjaxImage" runat="server" ImageUrl="Ajax.gif" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</asp:Content>
The page_load starts a long (>5s) process
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LongRunningProcess();
}
}
How can I display the UpdateProgress while the LongRunningProcess is running? It does work when I move the LongRunningProcess() call to a button onclick handler.
Move your page_load code into a new function.
Add a AJAX timer into the ContentTemplate section of your page. Set the interval to 500. (1/2 second)
Double-click on the Timer object in Design view to create a _tick handler.
In the _tick handler created in the previous step, call the following code
protected void My_Timer_Tick(object sender, EventArgs e)
{
My_Timer_Name.Enabled = false;
My_Page_Load_Function(); // Function created in step 1 above)
}
protected void My_Page_Load_Function()
{
System.Threading.Thread.Sleep(5000); // A delay to simulate doing something.
lblMyLabel.Text = "Done!"; // Write output to page.
}
Create a normal div that shows the Ajax.gif so it shows "processing" by default.
In the javascript pageLoad() function, make a call back to the page using Ajax's PageMethods.
function pageLoad(sender, args) {
PageMethods.getVersions(LoadVersionsCallback);
}
The method you are calling in your .aspx.cs file has to be static, it can take parameters and looks something like:
[System.Web.Services.WebMethod]
public static string getVersions()
{
StringBuilder sb = new StringBuilder();
... etc.
return sb.ToString();
}
The javascript function that you specified when you called the method will run when the method completes. It will be passed the results. At the end of this function you hide the Ajax.gif div.
function LoadVersionsCallback(result) {
// do something with the results - I load a dropdown list box.
...etc.
// here is where you hide your div holding the Ajax.gif
}
And then you work on making whatever it is you are doing run in less than 1 second....
I would put a Ajax timer on the page and set it for less than a second... It will only run once and after its first tick then you need to disable it otherwise it will fire again. (you don't want to start your long running process more than once...)
then on the OnTimerTick event I would start your long running process that way your page fully renders and you can display your UpdateProgress while its running.
you out to be able to move the code that you had for your button click to the time tick...
I used JBrooks idea above (i.e. showing the progress indicator as part of a Panel that also includes the Iframe, so that it shows even before the Iframe first loads), but simplified it: style the iframe so that when it does appear it is on top of the animated GIF.
Requires no Javascript or C# code-behind.
Here's the relevant ASPX, followed by the CSS. You'll have to noodle with the "top" setting in the style to cover the image you use.
<asp:Panel ID="DetailPanel" runat="server" CssClass="submitBox detailPanel">
<asp:Table ID="Table1" runat="server" Width="100%">
<asp:TableHeaderRow ID="TableHeaderRow10" runat="server">
<asp:TableCell ID="TableHeaderCell" runat="server"
Font-Bold="true" HorizontalAlign="Center">
Title Text
</asp:TableCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell HorizontalAlign="Center">
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/animated_progress.gif" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<div class="iframeOverlay">
<iframe id="IframeDetail" runat="server" style="width: 100%; height: 100%;" />
</div>
</asp:Panel>
.iframeOverlay
{
z-index: 2;
position: relative;
top: -50px;
}
With Jquery.
<script>
$(document).ready(function() {
$('#<%= UpdateProgress1.ClientID %>').show();
});
</script>
<script> $(document).ready(function() { $('#<%=
UpdateProgress1.ClientID %>').show(); }); </script>
This worked well for me, just had to add it to the end of the BODY section and works like a charm.

Resources