Unable to make AJAX code work - c#

Just getting started with AJAX and tried a simple example in the microsoft 70515 book. However, the code doesnt seem to work, and I can't figure out why not - as it seems ok.
Edit: for some reason a part of the code did not get posted, (even as I am writing this now the code looks weird, it is like I can't post all my code??) I've fixad that now- but what's up with the down vote? I cant really see what is stupid about my question. Please explain.
Hoping somebody can spot the problem and help me out here :)
Markup .aspx:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="AjasxTest._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager>
<br /><br />
<script type="text/javascript">
function ClientCallbackFunction(args) {
window.LabelMessage.innerText = args;
}
</script>
</asp:Content>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="FooterContent">
<asp:DropDownList ID="DropDownListChoice" runat="server" OnChange="MyServerCall(DropDownListChoice.value)">
<asp:ListItem>Choice 1</asp:ListItem>
<asp:ListItem>Choice 2</asp:ListItem>
<asp:ListItem>Choice 3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="LabelMessage" runat="server"></asp:Label>
</asp:Content>
Code-behind:
namespace AjasxTest
{
public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "args", "ClientCallbackFunction", "");
string callbackScript = String.Format("function MyServerCall(args) {{{0};}}", callbackRef);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"MyServerCall", callbackScript, true);
}
public string GetCallbackResult()
{
return _callbackArgs;
}
string _callbackArgs;
public void RaiseCallbackEvent(string eventArgument)
{
_callbackArgs = eventArgument;
}
}
}

Your JS function is called ClientCallbackFunction but you're calling it in the DropDownList OnChange event as MyServerCall.
<script type="text/javascript">
function ClientCallbackFunction(args) {
window.LabelMessage.innerText = args;
}
</script>
...
<!-- Call correct JS function in OnChange -->
<asp:DropDownList ID="DropDownListChoice" runat="server" OnChange="ClientCallbackFunction(DropDownListChoice.value)">
...

Your code is pretty close, however the problem is in the fact you are trying to access ServerSide objects (such as Label and DropDownList) from the client side.
For example, an asp:Label control, when rendered to a web browser on the client side, is actually an HTML div. The ID of the label in Visual Studio might be "LabelMessage", but depending on the layout of your page and controls, the ID on the client side (i.e., for the user that clicks view source in FireFox or IE) could be generated as "FooterContent_LabelMessage1" or something like that.
ASP.net controls do come with a property you can use to access the generated ID in JavaScript, which can be accessed by YourControl.ClientID.
I've made these changes to your code and have been able to make it work. I also added some null reference checking in the JavaScript to ensure the objects we are trying to reference, in fact, exist. Note I've tested this in a blank, brand new ASP.net forms application.
Here's the updated code for the Default page (front end):
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="TheAnswer._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<br />
<br />
<script type="text/javascript">
function ClientCallbackFunction(args) {
var labelMessage = $get("<%= LabelMessage.ClientID %>");
if (labelMessage) {
labelMessage.innerText = args;
}
}
function MyServerCallWrapper() {
var dropDown = $get("<%= DropDownListChoice.ClientID %>");
if (dropDown) {
MyServerCall(dropDown.value);
}
}
</script>
</asp:Content>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="FooterContent">
<asp:DropDownList ID="DropDownListChoice" runat="server" onchange="javascript:MyServerCallWrapper();">
<asp:ListItem>Choice 1</asp:ListItem>
<asp:ListItem>Choice 2</asp:ListItem>
<asp:ListItem>Choice 3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="LabelMessage" runat="server"></asp:Label>
</asp:Content>
Note the $get() function is a built-in ASP.net (not JQuery) function that is shorthand for document.getElementById() - they are interchangeable and do exactly the same thing. You need to pass the ClientID in quotes to either of these methods in JavaScript, and it will return a reference to the object you are trying to access.
Just for fun, I modified one of the back-end functions so you know that the call back was processed on the server:
public string GetCallbackResult()
{
return _callbackArgs + " from the server!";
}
And voila! this works for me -
I hope it works for you too and I hope it's clear where the problem was; most of your example was working / setup perfectly.

Related

Get Master Page Control Value In Content Page static webmethod in c#

I can fetch MasterPage control value in Content Page
but I can't understand how to fetch MasterPage control value in Content Page in static webmethod
on google, I found many interesting articles but all of them use ajax and jquery technology
but ajax and jquery is not suitable for me in this case
any suggestions, please?
my code below
masterpage
public partial class MasterPage : MasterPage
{
public string UserNamePropertyOnMasterPage
{
get
{
// Get value of control on master page
return lblUserName.Text;
}
set
{
// Set new value for control on master page
lblUserName.Text = value;
}
}
}
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
<span style="font-size: 25px; background-color: greenyellow">
<asp:Label ID="lblUserName" runat="server" Text="Shazam"></asp:Label>
</span>
</form>
code-behind of Default.aspx.cs
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblCurrentUserName.Font.Size = 20;
lblCurrentUserName.BackColor = Color.Yellow;
lblCurrentUserName.Text = "Value Received in Content Page : " + Master.UserNamePropertyOnMasterPage;
}
}
[WebMethod(EnableSession = true)]
[ScriptMethod]
public static void SetLabel(string UserNamePropertyOnMasterPage)
{
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
Label Hname = (Label)Master.UserNamePropertyOnMasterPage;
lblCurrentUserName.Text = Hname;
}
}
markup of Default.aspx
<%# Page Title="" Language="C#" MasterPageFile="MasterPage.master"
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%# MasterType VirtualPath="MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:Label ID="lblCurrentUserName" runat="server" Text=""></asp:Label>
</asp:Content>
It is not possible to call a master page method from a static web method. This is a fundamental concept to understand in C#. Basically the master page does not exist during the web request. Only the web method is called.
Use JavaScript/jQuery to update the current page HTML.

How can I recapture form data?

I am attempting to recapture some form values after they have been posted, but am having quite a bit of difficulty. My form has 2 fields:
<strong>Username:</strong> <asp:TextBox ID="txtUsername" runat="server" Width="200px" /><br /><br />
<strong>Password:</strong> <asp:TextBox ID="txtPassword" runat="server" Width="200px" TextMode="Password" />
And in the code behind, I have tried to capture the username, but keep coming up empty handed. Here is my current implementation:
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.Request.HttpMethod == "POST")
{
txtUsername.Text = Request.Form["txtUsername"];
}
}
What am I missing?
your code works perfectly fine for me:
ASPX:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" id="MainHTML" runat="server">
<head runat="server">
<title></title>
<script type="text/javascript">
</script>
</head>
<body>
<form runat="server">
<strong>Username:</strong> <asp:TextBox ID="txtUsername" runat="server" Width="200px" /><br /><br />
<strong>Password:</strong> <asp:TextBox ID="txtPassword" runat="server" Width="200px" TextMode="Password" />
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
</body>
</html>
cs:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.Request.HttpMethod == "POST")
{
txtUsername.Text = Request.Form["txtUsername"];
}
}
}
Without seeing the rest of the .aspx page, there's nothing glaringly obviously wrong there, but:
are the TextBoxes within a form with runat="server"?
have you run a trace to see what the Form variables, if any, contain?
are you sure the page is being submitted, and not just refreshed?
have you tried a breakpoint to see whether the if condition evaluates to true (similar to above point)?
I would think you can add onclick= to the button that is submitting the form since the textboxes are running at server. After the equal sign if you press tab twice it will automatically generate an event in the code behind. Then you can do something like this in the code behind to save it in session.
string firstName = txtUsername.Text;
string lastName = txtPassword.Text;
Session["FirstName"] = firstName;
Session["LastName"] = lastName;
and to access it later
string firstName = Session["FirstName"];
First of all to checking if it is a post you can check with this:
if (IsPostback) { //do something here }
and you will see that if it is done on the same page will not work coz it post to itself.When you click a button in the same page data are generally saved in viewstate.So before give you more info we need to have more info about it work to better help you.

I get a "Microsoft JScript runtime error: Object doesn't support this property or method" error for anything with autopostback=true on one of my pages

I have a .NET application with the following aspx code:
<%# Page Language="C#" AutoEventWireup="True" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default"%>
<%# Register TagPrefix="asp" Namespace="AjaxControlToolkit" Assembly="AjaxControlToolkit"%>
<%# Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<form id="form1" runat="server">
<asp:ToolkitScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ToolkitScriptManager>
<table>
<tr>
<td>
<asp:RadioButtonList ID="rblTest" runat="server" AutoPostBack="True"
onselectedindexchanged="rblTest_SelectedIndexChanged">
<asp:ListItem Text="1" Value="1"></asp:ListItem>
<asp:ListItem Text="2" Value="2"></asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:PlaceHolder ID="ph1" runat="server" Visible="False">
Some text
</asp:PlaceHolder>
</td>
</tr>
</table>
</form>
</body>
</html>
I then have a C# method as follows:
protected void rblTest_SelectedIndexChanged(object sender, EventArgs e)
{
if (rblTest.SelectedValue == "2")
ph1.Visible = true;
else
ph1.Visible = false;
}
Below is where the crash occurred. It crashes any time I use a control that has autopostback=true. I use the same syntax on about 15 other forms and those all work just fine. Am I missing a property somewhere or is there something wrong with my method? I originally had an UpdatePanel around the controls and I plan on adding it again, but I need to get the postback working first.
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['Default'];
if (!theForm) {
theForm = document.Default;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit(); <-----Crashed at this line.
}
}
//]]>
</script>
What am I missing or is there some common mistake that I may have made somewhere? Thanks in advance for your help.
Your __doPostBack script is trying to submit a form with id "Default" (see document.forms["Default"] line; yet your markup shows a form with id "form1" so it's clear why it doesn't work: the __doPostBack function is not finding the form and calling theForm.submit() fails.
You can attempt to fix it by renaming the form to use the id "Default" since I don't think you can control the way the __doPostBack script is generated.

How to execute javascript pageload event on multi instance web user control

I'm developing an web user control for that i need to set some properties at page load (client side page load). My control works fine with one instance on page.
But when i need multiple instance of that control on same page.Page load event shows effects only on last control.
My control
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControlLoadTest.ascx.cs" Inherits="WebUserControlLoadTest" ClientIDMode="Predictable" %>
<link rel="stylesheet" href="GridViewCSSThemes/YahooGridView.css" type="text/css" media="screen" />
<script runat="server" type="text/C#">
static Int16 _count;
public static Int16 count
{
get { return _count++; }
}
</script>
<script type="text/javascript">
function pageLoad() {
document.getElementById('<%= Hidden_RowIndex.ClientID%>').value = '<%= count%>';
document.getElementById('<%= txtUC.ClientID%>').value = "Count : " + document.getElementById('<%= Hidden_RowIndex.ClientID%>').value;
}
</script>
<asp:HiddenField ID="Hidden_RowIndex" Value="" runat="server" />
<asp:TextBox ID="txtUC" CssClass="tb10" Enabled="false" runat="server"></asp:TextBox>
Use control on aspx page
<%# Page Language="C#" AutoEventWireup="true" CodeFile="ContextMenuTest.aspx.cs" Inherits="ContextMenuTest" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<%# Register TagPrefix="uc1" TagName="UCTest" Src="~/WebUserControlLoadTest.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Java Script Load Test</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="server" ID="ScriptManager1" EnablePageMethods="true" />
<table style="padding:1%;width:100%;">
<tr>
<td>
<uc1:UCTest runat="server" ID="UCTest1"/>
</td>
</tr>
<tr>
<td>
<uc1:UCTest runat="server" ID="UCTest2"/>
</td>
</tr>
</table>
</form>
</body>
After execution result will be Count - 0 in first Control and Count - 1 in Second.
But it shows 1 Control blank and second with Control -1 text.
Can any one tell me how can i make different instance of java-script page-load event in multi instance web user control.
The problem is
static Int16 _count;
public static Int16 count
{
get { return _count++; }
}
If you declare your control multiple times, then you override the counter each time the control is rendered.
You need a smarter Javascript, for examle, add a class on the control wrapper inside WebUserControlLoadTest.ascx something like
<div class="myControl">
<asp:HiddenField ID="Hidden_RowIndex" Value="" runat="server" />
<asp:TextBox ID="txtUC" CssClass="tb10" Enabled="false" runat="server">
</asp:TextBox>
</div>
and at the top of the aspx page you can have this:
$(document).ready(function(){
var count = 0;
$("myControl input:hidden").each(function(){$(this).value = count++});
});

ASP/C#, adding text to textbox problem

For some reason, I cannot get text into any textbox or label!
I'm using Master pages and the code is going in the code behind view. I have created the textbox:
<asp:Textbox ID="whatever" runat="Server">
When I want to add some text I simply add the code in the code behind view like:
whatever.Text = "myText";
I get an error that says:
"System.NullReferenceException:Object reference not set to an instance of an object"
hightlighting this line in red: whatever.Text = "myText";
I guess its because it saying it not there but how can it let me reference the textbox?
Apologies if the answer is on the site, I have searched but found nothing. :)
This is my code in Basket.asp - I've changed the textbox to a label, it's called bskItems
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder3" runat="server">
<asp:Label ID="bskItems" runat="server"></asp:Label>
<div id="cart">
<asp:Button ID="btnCheckout" CssClass="BasketBtnAdd" runat="server" CommandName="checkout" Text="Checkout" />
</div>
</asp:Content>
This is my masterpage, where I'm using a loginView. ContentPlaceHolder3 is where the textbox should be. I only want it to display a count of items.
<asp:LoginView ID="loginView" runat="server">
<LoggedInTemplate>
<asp:LoginName ID="loginName" runat="server" FormatString="Hi, {0}!"/>
(<asp:LoginStatus ID="loginStatus" runat="server" />)
<%
if (HttpContext.Current.User.IsInRole("Admin"))
{
%>
<asp:SiteMapDataSource ID="admin" SiteMapProvider="admin" runat="server" ShowStartingNode="false" />
<asp:Menu ID="Menu" runat="server" DataSourceID="admin">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
<%
}
if (HttpContext.Current.User.IsInRole("Users"))
{
%>
<asp:SiteMapDataSource ID="user" runat="server" SiteMapProvider="user" ShowStartingNode="false" />
<asp:Menu ID="Menu1" runat="server" DataSourceID="user">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
<%
}
%>
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server"></asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="ContentPlaceHolder3" runat="server"></asp:ContentPlaceHolder>
</LoggedInTemplate>
<AnonymousTemplate>
<asp:LoginStatus ID="loginStatus" runat="server" />
<asp:SiteMapDataSource ID="anon" runat="server" SiteMapProvider="anon" ShowStartingNode="false" />
<asp:Menu ID="Menu2" runat="server" DataSourceID="anon">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
</AnonymousTemplate>
</asp:LoginView>
In addition to the other answers, if you're setting the value in Page.OnLoad, remember that the Master page controls haven't been created yet.
Here's a complete layout of the order in which things happen: Complete Lifecycle of an ASP Page
What I usualy do is to make the control visible as a property of my MasterPage.
On the master page (AMasterPage.master):
public TextBox MyTextBox { get { return this.theTextBoxControl; } }
So then, on a child using this masterPage (APage.aspx) :
((AMasterPage)this.Master).MyTextBox.Text = "myText";
When accessing Master Page members from Code-Behind in a Content Place Holder file, I believe you need to do:
this.Master.whatever.Text = "new Text";
Check this link on ASP.NET Master Pages, from MSDN.
You need to do get a reference to the textbox on the master page, then set the text
TextBox tb = Master.Page.FindControl("whatever") as TextBox;
if(tb != null)
{
tb.Text = "myText";
}
Set the ClientIDMode on the textbox to "Static". When the page is rendered it assigns the TextBox's ID to something random. By changing the ClientIDMode to "Static", you should be able to reference the ID because the ID will stay the same and not change.
Or try adding an OnDataBinding event handler and casting the "sender" as a (TextBox). For example:
protected void TextBox_OnDataBinding(object sender, EventArgs e)
{
var txt = (TextBox)sender;
txt.Text = "Something";
}
This should talk to the control directly.

Categories

Resources