Error:
cannot refer to an instance member of a class within a shared method
I'm working on a web application that pulls data from a MSSQL server on the backened. Calling my web method from ajax isn't the issue, it's displaying the data once it has been received.
I have the following gridview on my report page:
<asp:GridView ID="gridReport" runat="server"></asp:GridView>
The web method that is pulling the data from the DB is called DBManager.asmx, it is declared as follows (this is called via ajax each time a drop-down is changed):
<WebMethod()> _
Public Function GetSpecificReport(ByVal strFilter As String) As String()
(it is NOT the code-behind file for the report page) The data being returned from the DB is currently in a DataSet (variable name: ds).
Is there any way to assign the DataSource for that GridView to the DataSet pulled from the .asmx file, or a nice workaround that I could try? I've tried creating shared methods in the code-behind report page with no luck, as well as putting the GetSpecificReport method inside the code-behind.
Thanks for the help, let me know if I should give more info or post more code.
I would offer 3 suggestions:
First and foremost, using something like telerik grid that allows you to return JSON from your webmethod and bind directly to that json:
http://www.telerik.com/products/aspnet-ajax/grid.aspx
That said, I whipped up a small example where you can render a gridview in your webmethod and re-emit the HTML.
You can also just draw your table in HTML using RenderControl:
Here is a simplified example that re-draws the control using jquery.ajax without any updatepanel or etc. Updatepanel probably works better though!
ASPX:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="TymeJVTest._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function blag() {
var gridID = "<%= GridView1.ClientID %>";
$.ajax({
type: "POST",
data: {},
contentType: "application/json;charset=utf-8",
dataType: "json",
async: true,
url: "Default.aspx/GetSomeData",
success: function (data) {
//not sure why this is data.d , but what the hey
var theHtml = data.d;
$("#" + gridID).html(theHtml);
},
failure: function () {
alert("Sorry,there is a error!");
}
});
}
</script>
<h2>
Welcome to ASP.NET!
</h2>
<p>
To learn more about ASP.NET visit www.asp.net.
</p>
<p>
You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
</p>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<a href="#"onclick="blag();" >Test</a>
</asp:Content>
CS:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int[] theObject = {1, 2, 3, 4};
GridView1.DataSource = theObject;
GridView1.DataBind();
}
[WebMethod]
public static String GetSomeData()
{
GridView gv = new GridView();
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
int[] someNewData = {10, 11, 12, 13, 14};
gv.DataSource = someNewData;
gv.DataBind();
gv.RenderControl(htmlWriter);
return stringWriter.ToString();
}
}
This will create a replacement gridview on the server, render it to html, then transmit it back.
You could also use something like AngularJS and just keep a piece of JSON that your server updates, and use this to bind to a grid in real-time with angular.
I think you can achieve what you want without too much changes using an updatepanel.
http://msdn.microsoft.com/en-gb/library/bb399001.aspx
Basically populate your grid on page load or whatever suits you then do refreshes using updatepanel.
Related
I'm trying to change a label text from cs file after I receive a message from the server.
I tried using to put the label in updatepanel but couldn't make it work.
How can i update the display of the label?
Usually this is something along the lines of
myLabel.Text = "Value";
If it's in an UpdatePanel, the rules are a little different. I think you need to get the control, then update its value. Something along the lines of:
Label lbl = (Label) updatePanel1.FindControl("myLabel");
lbl.Text = "Value";
If you are trying to avoid a post back, then you can use ASP.NET AJAX Page Methods to query the server via AJAX and then push the value returned into the label control, like this:
Markup:
<script type="text/javascript">
$(document).ready(function () {
$('.TheButton').click(function () {
$.ajax({
type: "POST",
url: "Default.aspx/GetDate",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$('.TheLabel').text(data.d);
}
});
return false;
});
});
</script>
<asp:Label ID="Label1" runat="server" Text="Nothing" CssClass="TheLabel" />
<br/>
<asp:Button runat="server" ID="Button1" CssClass="TheButton" Text="Update Label"/>
Code-behind:
[WebMethod]
public static string GetDate()
{
return DateTime.Now.ToString();
}
Note: ASP.NET AJAX Page Methods are static methods that are not part of the ASP.NET page life-cycle. They do not have access to any of the controls on the page, but are very useful for getting data from the server (in this case the server time). In the interest of simplicity, I used CSS class names on the server controls to make the jQuery selectors simpler.
I know how to do this with classic asp.
How do I do it with ASP.net?
Can I just make a code page like verifyLogin.cs
And call that page from Jquery?
Or would I have to make a page like verifyLogin.aspx with a code behind page?
There are lots of different ways to do it, depending on your requirements. Here's a very simple way to start though. Create a page called "AjaxData.aspx" with no code-behind:
<%# Page Language="C#" %>
<%
Response.ContentType = "text/plain";
string data = "some data";
Response.Write(data);
%>
Then use your AJAX call as normal:
$.get("AjaxData.aspx", function(data) {
alert(data);
});
I am trying to add dynamically a user control I created to an aspx page after it is loaded.
I tried sending an ajax request to a handler that used RenderControl function and sent back the control's html. I appended it to the DOM using javascript.
The problem is that some of the controls must go through their Page_Load function and that doesn't happen when using RenderControl function.
Does anyone have any idea how can I do that?
try this:
System.Web.UI.Page page = new System.Web.UI.Page();
CustomUserControl userControl = page.LoadControl("~/control.ascx") as CustomUserControl;
if (userControl == null)
{
//error
}
userControl.ArticleId = id;
//call any other properties or methods you need
page.Controls.Add(userControl);
System.IO.StringWriter sw = new System.IO.StringWriter();
HttpContext.Current.Server.Execute(page, sw, false);
responseString = sw.ToString();
hope this will help!
Why dont you load and add the user control dynamically to the page?
I don't think you can do this that way.
Your controls don't go through their Page_Load, because they are not added to any control. All you are doing is rendering their html (using RenderControl) and loading it using javascript. There's no place for Page_Load event.
I would use UpdatePanel instead in that way:
<asp:UpdatePanel>
<ContentTemplate>
<asp:Panel ID="pnlDynamic" />
</ContentTemplate>
</asp:UpdatePanel>
and then in code behind add your dynamic controls to panel
pnlDynamic.Controls.Add(new YourControl());
I'm trying to find out how to get properties and client methods of my controls be accessible via client scripts. For example, here is a very simple sample control:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="MyCustomControl.ascx.cs" Inherits="MyCustomControl" %>
<script type="text/javascript">
$(function() {
$("#<%=lnksave.ClientID %>").click(function() {
$("#<%=hiddenText.ClientID %>").val($("#<%=txtText.ClientID %>").val());
});
$("#<%=lnkshow.ClientID %>").click(function() {
alert($("#<%=hiddenText.ClientID %>").val());
});
});
</script>
<asp:HiddenField runat="server" ID="hiddenText" />
<input type="text" runat="server" id="txtText" />
<a id="lnksave" runat="server" href="#">Save text</a>
<a id="lnkshow" runat="server" href="#">Show text</a>
I wish another controls to access it the way like this on client side:
<%# Register Src="~/MyCustomControl.ascx" TagName="CustomControl" TagPrefix="mycontrols" %>
...
<asp:ScriptManager runat="server" ID="scriptManager1"></asp:ScriptManager>
<div>
<mycontrols:CustomControl runat="server" ID="control1" />
</div>
...
<script type="text/javascript">
$find("<%=control1.ClientID %>").set_text("sample text");
</script>
, where set_text is something like
function(text) {
$("#<%=hiddenText.ClientID %>").val(text);
}
What kind of changes should I do to my control to get it working this way? Some code example will be very helpful. Thanks in advance!
When I have a user control that needs a JavaScript exposure, I typically define a JavaScript object to encapsulate its behavior. So in your example I would have a separate JavaScript file MyCustomControl.js that looks something like:
// MyCustomControl JavaScript object constructor:
function MyCustomControl(clientID) {
this.id = clientID;
}
// MyCustomControl prototype:
// Declare any methods for the object here.
MyCustomControl.prototype = {
set_text: function(text) {
$("#" + this.id).val(text);
}
};
Then you add amethod to your user control server-side to generate a JavaScript object constructor call for the user control instance:
public string GetClientSideObject()
{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return string.format("new MyCustomControl({0})",
serializer.Serialize(this.ClientID));
}
You can then embed the output of GetClientSideObject() in dynamically generated script to create an instance of your control's JavaScript object:
<script type="text/javascript>
var myUserControl = <%= this.myUserControl.GetClientSideObject() %>;
myUserControl.set_text('Foo Bar Baz');
</script>
One of the nice things about this approach is most of your JavaScript is static and ends up in a separate .js file, which can be cached/combined/minified/etc just like any other script. It also clearly associates the instance with the original user control for anyone reading the code.
One thing to watch out for however is serializing your arguments to the constructor in GetClientSideObject(). I tend to use the JavaScriptSerializer class to write out my arguments, so I can be sure strings end up as quoted strings, and numbers are numbers, etc.
I have a textbox control Super1 in my MasterPage.
I am using javascript to access this control from my content page like this:
<asp:Content ID="ContentPage" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<script type="text/javascript">
function Somethin() {
{
document.forms[0].elements['Super1'].value = "sdfsd";
//document.getElementById('<%=Super1.ClientID%>').value = "sdfsdf";
}
}
</script>
</asp:Content>
But while page load it says Super1 not found. How can I access Super1?
In your masterpage's onload add this code :
string script = #"<script>
function Somethin() {
document.getElementById('" + Super1.ClientID + #"').value = 'sdfsd';
}
Somethin();
</script>";
if (!Page.ClientScript.IsClientScriptBlockRegistered("somethin_script_block"))
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "somethin_script_block", script);
}
this will add your script to the end of the page.
EDIT : I just realized, you use your controls ID directly in your javascript code. this may cause the exception. I update your code to fix it.
I hope this helps.
You have to make sure the document has loaded, make sure to call your functions that rely on the DOM being loaded onload. E.g.:
<script type="text/javascript">
window.onload = function() {
Somethin();
}
</script>
From the sample code you posted and since you said you are using a control, check the rendered id of the control you are trying to get at. In my experience the name is something crazy like ctl100_masterpagename_namingcontainer_controlname... that needs to show up in the js as well.
Super1 might be in a different naming container (the masterpage's control collection). You either need to render out the clientid of the control in a global javascript variable during the masterpage rendering so it can be accessed by javascript in the child page or you need to get a reference to the Masterpage, find the control there and write out the client Id in your child pages javascript...
Something like...
if the text box is in its own content place holder
var txtSuper1 = Master.FindControl("ContentPlaceHolderName").FindControl("Super1") as Textbox;
or if its not in a content place holder
var txtSuper1 = Master.FindControl("Super1") as Textbox;
3rd option might be to expose the control as a property of the masterpage (not sure) - my webforms is rusty.
On the master page, declare a javascript variable for the control, e.g:
<asp:TextBox id="Super1" runat="server"/>
...
<script type="text/javascript">
var txtSuper1 = document.getElementById('<%= Super1.ClientID %>');
</script>
It's important that you use the ClientID property, because the rendered control's ID (on the client) will be different from the server control's ID (due to naming containers).
Now you can access the textbox from javascript declared in the content pages:
<asp:Content ID="ContentPage" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<script type="text/javascript">
function Somethin()
{
txtSuper1.value = "sdfsd";
}
</script>
click me
</asp:Content>
BTW: in your code there are duplicate curly-braces in function Somethin() {{ ... }}