Call VB function from javascript - asp.net

I have a javascript in my asp file where I would like to call a vb function from.
Asp javascript function:
<script type="text/javascript">
function functionName(sender, args) {
var variable = args.get_value();
PageMethods.VBFunctionName(variable);
}
</script>
Function in VB:
<System.Web.Services.WebMethod()>
Public Shared Function VBFunctionName(variable As String) As String
Dim result As String = variable
Return result.ToString()
End Function
And, I have also added the ScriptManager to enable page methods:
<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="True"></asp:ScriptManager>
But, It is not working! In the asp file, when I type 'PageMethods' the autocomplete for this option it's not available. So, I think the error is with the EnablePageMethods.
How could I resolve this problem?

The problem with your code is that you are making an Ajax call but not setting any callback to read the response from the server. You need to define a callback function (and optionally a failure function) to set what you are going to do with the response.
So your script tag should look like this:-
<script type="text/javascript">
function functionName(sender, args) {
var variable = args.get_value();
PageMethods.VBFunctionName(variable,onSuccess); //pass callback function
}
function onSuccess(response) {
alert(response); //Do whatever you wanna do with response.
}
</script>
Also, since we are working inside javascript script tag, I don't think Visual Studio will be able to suggest u the server methods.

I prefer using JQuery to call VB Function from javascript.
<script type="text/javascript">
function functionName(sender, args) {
var variable = args.get_value();
$.get( "#Url.Action("VBFunctionName")?variable=" + variable, function( data ) {
alert(data);
});
}
</script>

Related

$Find returns null

I have the following JScript on a page
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $find("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
and later
<asp:Button ID="ProcessButton" Text="Process All" runat="server" OnClick="Process_Click" OnClientClick="ProcessButtonDisable()" />
when running the page and firing off the button i get
Microsoft JScript runtime error: Unable to set value of the property 'disabled': object is null or undefined
and the dynamic page has converted it to:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $find("ctl00_ctl00_BodyContentPlaceHolder_MainContentPlaceHolder_ProcessButton");
button.disabled = true;
}
</script>
<input type="submit" name="ctl00$ctl00$BodyContentPlaceHolder$MainContentPlaceHolder$ProcessButton" value="Process All" onclick="ProcessButtonDisable();" id="ctl00_ctl00_BodyContentPlaceHolder_MainContentPlaceHolder_ProcessButton" />
as the control is clearly defined and the client id seems to be returning the correct id i don't know whats wrong
Any help?
ps in case this is not clear from the code the purpose of this is to prevent he user from clicking on the and resending the request before the page has time to reload after the initial click
-1 to all the previous answers for assuming JQuery. $find is a function defined by the Microsoft AJAX Library. It "provides a shortcut to the findComponent method of the Sys.Application class" which gets "a reference to a Component object that has been registered with the application through the addComponent method". Try using $get() instead, which "Provides a shortcut to the getElementById method of the Sys.UI.DomElement class."
This page explores both functions in detail: The Ever-Useful $get and $find ASP.NET AJAX Shortcut Functions
$find is differ from $.find. The first one is provides a shortcut to the findComponent method of the Sys.Application class which defined by the Microsoft AJAX Library. while the second is API method from jQuery which get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
So, $find has to find Component not html DOM. and ajax Library has to be defined.
For more information:
http://msdn.microsoft.com/en-us/library/vstudio/bb397441(v=vs.100).aspx
http://api.jquery.com/find/
try this:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $("#<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
[edit] or
<script type="text/javascript">
function ProcessButtonDisable() {
$("#<%=ProcessButton.ClientID %>").attr("disabled", "disabled");
}
</script>
You have to select what you are "finding" in first. For example, if you select document then use the method "find" you should have the result you want.
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $(document).find(("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
disabled is not a jQuery object property it is a DOM element property.
Try using either:
$('selector').get(0).disabled = true
, or
$('selector').attr('disabled','disabled');
You need to use the dot notation, as find() is a jQuery function, like this:
<script type="text/javascript">
function ProcessButtonDisable() {
var button = $.find("<%=ProcessButton.ClientID %>");
button.disabled = true;
}
</script>
Also, if you are going to take the trouble to look up the DOM element in your jQuery logic, then do not bother wiring up the OnClientClick on the server control; either wire up the click event via jQuery or pass the element itself to the JavaScript function:
Using jQuery to wire up the click event (recommended):
<script type="text/javascript">
$(document).ready(function() {
$("#<%=ProcessButton.ClientID%>").click(function() {
$(this).disabled = true;
});
});
</script>
Using the OnClientClick attribute to wire up the click event and pass the element (not recommended):
<asp:Button ID="ProcessButton" Text="Process All" runat="server" OnClick="Process_Click"
OnClientClick="ProcessButtonDisable(this)" />
<script type="text/javascript">
function ProcessButtonDisable(elem) {
elem.disabled = true;
}
</script>

execute code behind method every time DIV loads (ASP, ascx, ascx.cs)

The idea is that this div contains a quote from a customer that is retrieved from the server via a get random function, and every few seconds a jQuery runs that fades this quote out and brings another one into view.
This is my Div code in my .ascx:
< div class="testimonial" ID="Fader" onload="runTestimonial">
<q>"<asp:Literal runat="server" ID="Quote"></asp:Literal>"</q>
</div>
Code Behind (.ascx.cs):
protected void runTestimonial(object sender, EventArgs e)
{ --lots 'o code--
Partnership partnership = Partnership.GetRandomTestimonial(cmPage.CMPageId);
if (partnership != null)
{
Quote.Text = partnership.Testimonial;
Visible = true;
}
}
I am using this jQuery code:
setInterval(
(function () {
$('#Fader').fadeOut('slow', function () {
setTimeout(function () { $('#Fader').load().fadeIn('slow'); }, 300);
});
})
, (200))
The jquery should be fine. It links into the Div's Fader ID and does the fading and loading.
Originally the div generated the quote using a Page_Load method of the same structure and this worked. Now the change is I need to call it when I need to, not on Page_Load but on jQuery refresh.
So far I have the div refreshing in and out, but it's blank (If I revert it to the on Page_Load method, the same quote comes in and out). It's not getting to the ASP line or it's not executing it. I can just not get runTestimonial to work at all like the Page_Load does, probably because I don't know how to call it.
I don't know how to do C#, jQuery ASP or code behinding stuff really. Please help!
These are the steps of what you need to do, with jQuery and WebMethod:
1) You will change your runTestimonial() function into a WebMethod that will return a string (the random testimonial). So your function's signature would look like this:
[WebMethod]
public static string runTestimonial()
{
return randomTestimonial; //include your code
}
2) Add jQuery library in the head of your file.
<script src="http://code.jquery.com/jquery-latest.js"></script>
3) Create a function that will do an ajax call to your webmethod.
function getTestimonial()
{
$.ajax({
type: "POST",
url: "Default.aspx/runTestimonial",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
$("#Fader").html(msg); //msg contains the response from the server, this appends it to the div
}
});
}
4) Your div in your markup will NOT be a server control, so remove the onload. So it will look like this:
<div class="testimonial" ID="Fader"></div>
5) We are almost done, just make sure to call your getTestimonial() function inside your setInterval.
The [WebMethod] attribute is found in the System.Web.Services library, so make sure to include it at the top of your page:
using System.Web.Services;
That's all, that should work.
To put it simply, C# is server side, so the method runTestimonial doesn't exist on the client's browser. You need to create a javascript function that uses jQuery to call to the server with an ajax request. I would suggest checking out some tutorials on jQuery/ajax/ASP.Net. It seems like you are missing some of the fundamentals. Hope that helps!

Can't find ReportViewer event for rendering complete

I'm trying to fire an event (to remove a custom progress/status indicator) when the ReportViewer control is finished rendering. I've explored the events for the ReportViewer control and I can't seem to find one that actually fires when the report is complete.
I'm using Visual Studio 2010 and ASP.NET 4.
Thanks for your help.
I know this is old, but I wasn't satisfied with the polling approach. You can register a property change listener for changes to isLoading instead (as described here).
In summary, add a bit of javascript to the script manager e.g. in your form element:
<asp:ScriptManager ID="scriptManager" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Reports/ReportViewer.js" />
</Scripts>
</asp:ScriptManager>
<rsweb:ReportViewer ID="reportViewer" runat="server"/>
Then hook it up and add any client-side logic you need in ReportViewer.js:
Sys.Application.add_load(function () {
$find("reportViewer").add_propertyChanged(viewerPropertyChanged);
});
function viewerPropertyChanged(sender, e) {
if (e.get_propertyName() == "isLoading") {
if ($find("reportViewer").get_isLoading()) {
// Do something when loading starts
}
else {
// Do something when loading stops
}
}
};
One option would be to continuously poll the isLoading property of the client side ReportViewer api. If the isLoading property returns true continue showing the progress indicator, if it returns false hide it and stop polling.
I haven't tried it myself but according to the documentation is look like it should work.
I achieve this using JQuery like so:
$(document).ready(function () {
document.getElementById('ctl00_ctl00_DefaultContent_AdminContent_reportViewer').ClientController.CustomOnReportLoaded = function () {
alert('You see this after Report is Generated');
}
});
Try below code snippet:
<script type="text/javascript">
var app = Sys.Application;
app.add_init(ApplicationInit);
function ApplicationInit(sender) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
$('#ReportViewer1_ctl05').css('width', '1047px');
if (!prm.get_isInAsyncPostBack()) {
prm.add_endRequest(EndRequest)
}
}
function EndRequest(sender, args) {
var reportViewerControlId = "ReportViewer1";
if (sender._postBackControlClientIDs[0].indexOf(reportViewerControlId) >= 0) {
// do your stuff
}
}
</script>
EndRequest function will be triggered once report rendering gets completed.

How register (call) jQuery function from asp.net usercontrol from codebehind file?

How register (call) jQuery function from asp.net usercontrol from codebehind file?
You can use ClientScriptManager.RegisterStartupScript(), for example:
var script = "$(function() { $('#message').fadeIn(); });";
Page.ClientScript.RegisterStartupScript(GetType(), "keyHere", script, true);
This gets rendered to the page as:
<script type="text/javascript">
$(function() { $('#message').fadeIn(); });
</script>
The script is just any JavaScript, nothing special about jQuery, just put in there whatever you would manually put in the page, since that's how it ends up.

Check what control initiated AJAX Request

asp.net 2.0 / jQuery / AJAX
<script type="text/javascript">
//updated to show proper method signature
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(hideMessage);
function hideMessage(sender, args)
{
var ctl = args.get_postBackElement();
//check if ctl is the disired control
//hide user notification message
}
</script>
i have several controls on the page that might initiate the AJAX request, but i only want my js to fire when i click one particular button. how do i check what control initiated the request so i can fire JS accordingly.
EDIT: I worked around it, but I'd still like to know if I can do it this way.
Clarification: I can't call the JS from onclick event, because the page is inside of the UpdatePanel, and i only want the JS to execute when AJAX Request ends and it was triggered by one particular button on the page. On server side, i set the myLabel.Text to some text, and then js checks if the $(myLabel.CliendID)'s innerHTML is not blank and fires the js. checking the innerHTML is my work-around since i can't figure out how to check the "sender" of AJAX Request. Hope this makes more sense now.
edit2: I've read some documentation, and turns out you CAN check the "sender" control.
Thank you.
This is what I am doing in my code to identify what control has initialized the request. All javascript code.
function pageLoad() {
if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequest);
}
}
function endRequestHandler(sender, args) {
if (sender._postBackSettings.sourceElement.id == '<%= gvResults.ClientID %>') {
//do something because of this...
}
}
function initializeRequest(sender, args) {
if (CheckForSessionTimeout()) {
args.set_cancel(true);
}
else {
if (sender._postBackSettings.sourceElement.id == '<%= gvResults.ClientID %>') {
//do something because of this
}
}
}
EDITHere is the method of checking for timeout on the client side.
var sessionTimeoutDateTime = new Date();
var sessionTimeoutInterval = <%= this.SesstionTimeoutMinutes %>;
function CheckForSessionTimeout() {
var currentDateTime = new Date()
var iMiliSeconds = (currentDateTime - sessionTimeoutDateTime);
if (iMiliSeconds >= sessionTimeoutInterval) {
ShowSessionTimeout();
return true;
}
return false;
}
I would recommend that you do not have each control execute the same javascript function. OR, if they do, pass a parameter that indicates which one executed it.
Then, you can include your ajax in the js function that the control executes.
And, if I'm not understanding the issue correctly, perhaps you could explain it in more detail or post some code.
I've read some documentation, and turns out you CAN check the "sender" control. JS in the question is updated to show the proper method signature.
This article gives even better explanation.

Resources