I am very new to jQuery and have got a quick question.
I wish to use my server side classes in my jQuery code, something similar to this:
$(document).ready(function() {
var temp = <%# myClass.Id %>;
})
Is this possible? if so, how?
Thank you very much
This is the later question I refined my former question to:
I'm sorry, I think I didn't explain myself too well... I've got a class name User. It's a class I built in my business logic.
I've got a web page named UserProfile, inside it I've got the following property exposing the current logged in user:
public BL.User CurrUser { get { return (BL.User)Session["currUser"]; } }I want to be able to access this User class from my aspx page using Jquery. How do I do that?
The databinding syntax
<%# MyStaticClass.MyProperty %>
will only work if you call DataBind on the container (page). What you're after is most likely the following syntax:
<%= MyStaticClass.MyProperty %>
which will also give you access to you page / control members
<%= this.MyPageProperty %>
As was already mentioned you should really assign those values to java script variables and pass those variables to you JS functions.
This will only work if your javascript is embedded in your source files (e.g. the .aspx files):
<script type="text/javascript">
var id = <%# myClass.Id %>; // store as raw value
var id_string = '<%# myClass.Id %>'; // store in a string
</script>
As others have said, if the JavaScript is in your aspx page, then using server tags will work fine.
If you have your jQuery in an external script file, then you could put this in your aspx page
<script type="text/javascript">
var myClass = $('#<%= myClass.ClientID %>');
</script>
and then use the variable in your external script file
$(function() {
myClass.click( function() { ... });
});
For other options take a look at this question and answer - How to stop ASP.NET from changing ids in order to use jQuery
Related
I have web application where i want to call one method on body onload method.
I have method like this
<body id="pageid1" onload="SetupFeaturedProperty(1,['http://www.brightlogic-estateagents.co.uk/MRUS/upload/918-1.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/918-2.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/918-3.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/918-4.jpg']);SetupFeaturedProperty(2,['http://www.brightlogic-estateagents.co.uk/MRUS/upload/665-1.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/665-2.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/665-3.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/665-4.jpg']);SetupFeaturedProperty(3,['http://www.brightlogic-estateagents.co.uk/MRUS/upload/38-1.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/38-2.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/38-3.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/38-4.jpg']);SetupFeaturedProperty(4,['http://www.brightlogic-estateagents.co.uk/MRUS/upload/122-1.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/122-2.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/122-3.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/122-4.jpg']);SetupFeaturedProperty(5,['http://www.brightlogic-estateagents.co.uk/MRUS/upload/1076-1.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/1076-2.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/1076-3.jpg', 'http://www.brightlogic-estateagents.co.uk/MRUS/upload/1076-4.jpg']);">
And the arguments of these method can be change in after some time.
I want to pass the argument when my page is loaded.
I have tried lot of method to pass the argument from code behind page to this page but it's not working.
Please let me know a better solution for this.
Thanks
use this:
Page.ClientScript.RegisterStartupScript(this.GetType(), "myScript",getScript(),true);
and then:
private string getScript()
{
return "SetupFeaturedProperty(etc,etc,etc);";
}
If you are using UpdatePanels use the ScriptManager class instead of Page.ClientScript
There are multiple ways to do this. You can register the scripts using the RegisterClientScript method. You can make the body tag a server control and set it's onload attribute in the code behind or you can use Literal tag. However the method I find most clean is creating a JS variable and assigning it's value with a serverside code then using this variable in your JS code:
<script> var someVariable = <%= SomeProperty %>;</script>
Make sure that you define properties in your page and not move all your code behind in the markup.
Another good approach is to define a function for your event that takes the element as an input (pass this as the argument) and then attach the actual arguments as different attributes to the element.
<body runat="server" id="body" onload="onLoad(this)" data-someArg="someValue">...
You can set the attributes from your code behind like this
body.Attributes["data-someArg"] = "someValue";
This will be invalid in HTML4 but will work fine in all browsers and it will be valid in HTML5 as long as you prefix the attribute name with data-
Use ClientScript.RegisterStartupScript. Check MSDN:
MSDN - Javascript and ASP.NET 2.0
MSDN - ClientScript.RegisterStartupScript
One way to do it is to setup a Literal tag in your javascript. For example:
function somemethod()
{
var number1 = 10;
var number2 = <asp:Literal ID="litNumberFromCode" runat="server"/>;
alert(number1 + number2);
}
Then in your code behind access that control like any other:
litNumberFromCode.Text = 15;
Try using inline c# <% %> with your values printing
Is it possible to add a new ServiceReference instance to the ScriptManager on the Page during an asynchronous postback so that subsequently I can use the referenced web service through client side script?
I'm trying to do this inside a UserControl that sits inside a Repeater, that's why adding the ScriptReference programmatically during Page_Load does not work here.
EDIT 2: This is the code I call from my UserControl which does not do what I expect (adding the ServiceReference to the ScriptManager during the async postback):
private void RegisterWebservice(Type webserviceType)
{
var scm = ScriptManager.GetCurrent(Page);
if (scm == null)
throw new InvalidOperationException("ScriptManager needed on the Page!");
scm.Services.Add(new ServiceReference("~/" + webserviceType.Name + ".asmx"));
}
My goal is for my my UserControl to be as unobtrusive to the surrounding application as possible; otherwise I would have to statically define the ServiceReference in a ScriptManagerProxy on the containing Page, which is not what I want.
EDIT:
I must have been tired when I wrote this post... because I meant to write ServiceReference not ScriptReference. Updated the text above accordingly.
Now I have:
<asp:ScriptManagerProxy runat="server" ID="scmProxy">
<Services>
<asp:ServiceReference Path="~/UsefulnessWebService.asmx" />
</Services>
</asp:ScriptManagerProxy>
but I want to register the webservice in the CodeBehind.
Try something like this...
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "script1", "~/js/myjs.js");
}
Edit:
After checking your issue, Here is the reason why it is not working:
When you add ServiceReference to ScriptManager > Services section manually in page. It adds 1 client script include directive.
e.g:
<script src="TestService.asmx/jsdebug" type="text/javascript"></script>
or
<script src="TestService.asmx/js" type="text/javascript"></script>
which provide you to accessibility to your Frontend.Web.YourScriptMethods,
Now when you add ServiceReference in async postback - It is not adding this client script inclue. So you get client script error - method is undefined.
But i figured out a workaround for this; (do not know it is right way to do it)
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "testservice", "TestService.asmx/js");
}
You can replace the "TestService.asmx" path according to your project/web service.
This way you can achieve what you want.
Hope this helps,
Krunal Mevada
Old Ans:
Use following:
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
ScriptManager.GetCurrent(this).Services.Add(new ServiceReference("~/Service.asmx"));
}
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() {{ ... }}
Hi All,
I'm designing a user control, briefly it contains an asp:hiddenfield control, i'm going to access it via JavaScript function like this
function doAnyThing
{
var myVar = document.getElementById("myHiddenFiled");
}
but when I trace my code I found myVar assigned to null, does it matter
document.getElementById()
method is used in user control file (.ascx) or in regular (.aspx) file, taking into consideration it works in (.aspx) file correctly
You had to set by ClientID the final id of your control, that will depend by the structure of your page.
Try this:
function doAnyThing
{
var myVar = document.getElementById("<%= yourControlServerID.ClientID %>");
}
Obviously this function need to be placed in the .aspx file. I suggest you to switch to use a framework like jQuery, that allows you to retrieve controls by more sofisticate selectors. This case will be solved by:
$("[id$=yourControlServerID]");
and you can place your javascript code even in an external .js file.
to simplify you can use either:
JQuery
$("<%= yourControlServerID.ClientID %>"). ....
ASP.NET JavaScript annotation:
var myVar = $get("<%= yourControlServerID.ClientID %>");
the ASP.NET JavaScript annotation code is the same as:
var myVar = document.getElementById("<%= yourControlServerID.ClientID %>")
I can get simple examples to work fine as long as there's no master page involved. All I want to do is click a button and have it say "hello world" with the javascript in a .js file, using a master page. Any help very much appreciated :)
EDIT
As #Adam points out in the comments, there is a native jQuery mechanism that basically does the same thing as the hack in my original answer. Using jQuery you can do
$('[id$=myButton]').click(function(){ alert('button clicked'); });
My hack was originally developed as a Prototype work around for ASP.NET and I adapted it for the original answer. Note that jQuery basically does the same thing under the hood. I recommend using the jQuery way, though, over implementing my hack.
Original answer left for comment context
When you use a master page, ASP.NET mangles the names of the controls on the dependent pages. You'll need to figure out a way to find the right control to add the handler to (assuming you're adding the handler with javascript).
I use this function to do that:
function asp$( id, tagName ) {
var idRegexp = new RegExp( id + '$', 'i' );
var tags = new Array();
if (tagName) {
tags = document.getElementsByTagName( tagName );
}
else {
tags = document.getElementsByName( id );
}
var control = null;
for (var i = 0; i < tags.length; ++i) {
var ctl = tags[i];
if (idRegexp.test(ctl.id)) {
control = ctl;
break;
}
}
if (control) {
return $(control.id);
}
else {
return null;
}
}
Then you can do something like:
jQuery(asp$('myButton','input')).click ( function() { alert('button clicked'); } );
where you have the following on your child page
<asp:Button ID="myButton" runat="server" Text="Click Me" />
If your site has content pages in other folders, using the Page's ResolveUrl method in the src path will ensure that your js file can always be found:
<script type="text/javascript" src='<%= ResolveUrl("~/Scripts/jquery-1.2.6.min.js") %>' ></script>
Make sure that jQuery is being added in the master page. Given that you have this control:
<asp:Button ID="myButton" runat="server" Text="Submit" />
You can wireup the javascript with this:
$(document).ready(function() {
$('[id$=myButton]').click(function() { alert('button clicked'); });
});
$(document).ready() fires when the DOM is fully loaded, and all the elements should be there. You can simplify this further with
$(function() {});
The selector syntax $('[id$=myButton]') searches elements based on their id attribute, but matches only the end of the string. Conversely, '[id^=myButton]' would match the beginning, but for the purposes of filtering out the UniqueID that wouldn't be very useful. There are many many more useful selectors you can use with jQuery. Learn them all, and a lot of your work will be done for you.
The problem is that ASP.Net creates a unique id and name attribute for each element, which makes finding them difficult. It used to be that you'd need to pass the UniqueID property to the javascript from the server, but jQuery makes that unneccessary.
With the power of jQuery's selectors, you can decouple the javascript from the server-side altogether, and wireup events directly in your javascript code. You shouldn't have to add javascript into the markup anymore, which helps readability and makes refactoring much easier.
Just move the <script type="text/javascript" src="jquery.js" /> tag into the head tag in the master page. Then you can use jquery in all content pages.
There is no magic about using master pages with jQuery.
Adam's solution is the best. Simple!
Master page:
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
Content page:
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script type="text/javascript">
$(document).ready(function () {
$("[id$=AlertButton]").click(function () {
alert("Welcome jQuery !");
});
});
</script>
</asp:Content>
where the button is
<asp:Button ID="AlertButton" runat="server" Text="Button" />
Reference the the Jquery .js file in the head of the MasterPage as follows:
<script type="text/javascript" src="/Scripts/jquery-1.2.6.min.js"></script>
(some browsers don't like ending it with />)
Then you can write things like
$('#<%= myBtn.ClientID%>').show()
in your javascript making sure to use the ClientId when referencing an ASP.Net control in your client code. That will handle any "mangling" of names and ids of the controls.
Master page:
The jQuery library goes in the master page. See if the path is correctly referenced. You might like to add the extra documentation like this:
<head>
<script type="text/javascript" src="/Scripts/jquery-1.2.6.min.js"></script>
<% if (false) { %>
<script type="text/javascript" src="/Scripts/jquery-1.2.6-vsdoc.js"></script>
<% } %>
</head>
Master page:
<head>
<script type="text/javascript">
$(document).ready(
function()
{
alert('Hello!');
}
);
</script>
</head>
CodeBehind for content pages and user controls:
this.textBox.Attributes.Add("onChange",
String.Format("passElementReferenceToJavascript({0})", this.textBox.ClientID));
Check out this post:
http://blogs.msdn.com/webdevtools/archive/2008/10/28/rich-intellisense-for-jquery.aspx
also explains how to get intellisense for jQuery in Visual studio.
When pages are rendered along with master pages, control id gets changed on page rendering so we can't refer them in jQuery like this #controlid. Instead we should try using input[id$=controlid]. If control is rendered as input control or if as anchor tag use a[id$=controlid] in jQuery.
In case if some one wants to access a label, here is the syntax
$('[id$=lbl]').text('Hello');
where lbl is the label id and the text to display in the label is 'Hello'
I also started with the simplest of examples and had no luck. I finally had to add the jquery .js file outside of the <head> section of the master page. It was the only way I could get anything to work in Firefox (haven't tried other browsers just yet).
I also had to reference the .js file with an absolute address. Not entirely sure what's up with that one.
Adam Lassek linked to using jQuery selectors, though I think its worth explicitly calling out selecting elements by their class, as opposed to their id.
e.g. Instead of $("#myButton").click(function() { alert('button clicked'); });
instead use $(".myButtonCssClass").click(function() { alert('button clicked'); });
and add the class to the button:
<asp:Button ID="myButton" runat="server" Text="Submit" CssClass="myButtonCssClass" />
This has the benefit of not having to worry about whether two control ids 'end' the same way in addition to being able to apply the same jQuery code to multiple controls at a time (with the same css class).
PROBLEM --> when using Site.Master pages the control id names (for ASP controls) get the ContentPlaceHolderID prefixed to them.
(Note this not a problem for non-asp controls as they don't get 'reinterpreted' - i.e. they just appear as written)
SOLUTIONS:
Simplest --> add ClientIDMode="Static" to the asp control definition (or set with properties) in aspx page
Alternatives include:
Hardcoding the ContentPlaceHolderID name in the js code e.g "#ContentPlaceHolder1_controlName" - eek!!!!
using the <%= controlName.ClientID %> in the ASP page - plus, assigning it - there- to a variable (or object of variables). The variable (or object dot notation) can then be used in external js page
(NOTE: Can't use <%= controlName.ClientID %> in external js)
Using CssClass with a unique(same name as ID) in ASP page and refering to the control as ".controlName" instead of "#controlName"
Using the "[id$=_controlName]" instead of "#controlName" - this is involves a small search and is looking for a control that ends with the unique name - that way the start is irrelevant