I'm writing a web page in ASP.NET. I have some JavaScript code, and I have a submit button with a click event.
Is it possible to call a method I created in ASP with JavaScript's click event?
Well, if you don't want to do it using Ajax or any other way and just want a normal ASP.NET postback to happen, here is how you do it (without using any other libraries):
It is a little tricky though... :)
i. In your code file (assuming you are using C# and .NET 2.0 or later) add the following Interface to your Page class to make it look like
public partial class Default : System.Web.UI.Page, IPostBackEventHandler{}
ii. This should add (using Tab-Tab) this function to your code file:
public void RaisePostBackEvent(string eventArgument) { }
iii. In your onclick event in JavaScript, write the following code:
var pageId = '<%= Page.ClientID %>';
__doPostBack(pageId, argumentString);
This will call the 'RaisePostBackEvent' method in your code file with the 'eventArgument' as the 'argumentString' you passed from the JavaScript. Now, you can call any other event you like.
P.S: That is 'underscore-underscore-doPostBack' ... And, there should be no space in that sequence... Somehow the WMD does not allow me to write to underscores followed by a character!
The __doPostBack() method works well.
Another solution (very hackish) is to simply add an invisible ASP button in your markup and click it with a JavaScript method.
<div style="display: none;">
<asp:Button runat="server" ... OnClick="ButtonClickHandlerMethod" />
</div>
From your JavaScript, retrieve the reference to the button using its ClientID and then call the .click() method on it.
var button = document.getElementById(/* button client id */);
button.click();
The Microsoft AJAX library will accomplish this. You could also create your own solution that involves using AJAX to call your own aspx (as basically) script files to run .NET functions.
I suggest the Microsoft AJAX library. Once installed and referenced, you just add a line in your page load or init:
Ajax.Utility.RegisterTypeForAjax(GetType(YOURPAGECLASSNAME))
Then you can do things like:
<Ajax.AjaxMethod()> _
Public Function Get5() AS Integer
Return 5
End Function
Then, you can call it on your page as:
PageClassName.Get5(javascriptCallbackFunction);
The last parameter of your function call must be the javascript callback function that will be executed when the AJAX request is returned.
You can do it asynchronously using .NET Ajax PageMethods. See here or here.
I think blog post How to fetch & show SQL Server database data in ASP.NET page using Ajax (jQuery) will help you.
JavaScript Code
<script src="http://code.jquery.com/jquery-3.3.1.js" />
<script language="javascript" type="text/javascript">
function GetCompanies() {
$("#UpdatePanel").html("<div style='text-align:center; background-color:yellow; border:1px solid red; padding:3px; width:200px'>Please Wait...</div>");
$.ajax({
type: "POST",
url: "Default.aspx/GetCompanies",
data: "{}",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: OnSuccess,
error: OnError
});
}
function OnSuccess(data) {
var TableContent = "<table border='0'>" +
"<tr>" +
"<td>Rank</td>" +
"<td>Company Name</td>" +
"<td>Revenue</td>" +
"<td>Industry</td>" +
"</tr>";
for (var i = 0; i < data.d.length; i++) {
TableContent += "<tr>" +
"<td>"+ data.d[i].Rank +"</td>" +
"<td>"+data.d[i].CompanyName+"</td>" +
"<td>"+data.d[i].Revenue+"</td>" +
"<td>"+data.d[i].Industry+"</td>" +
"</tr>";
}
TableContent += "</table>";
$("#UpdatePanel").html(TableContent);
}
function OnError(data) {
}
</script>
ASP.NET Server Side Function
[WebMethod]
[ScriptMethod(ResponseFormat= ResponseFormat.Json)]
public static List<TopCompany> GetCompanies()
{
System.Threading.Thread.Sleep(5000);
List<TopCompany> allCompany = new List<TopCompany>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
allCompany = dc.TopCompanies.ToList();
}
return allCompany;
}
Static, strongly-typed programming has always felt very natural to me, so at first I resisted learning JavaScript (not to mention HTML and CSS) when I had to build web-based front-ends for my applications. I would do anything to work around this like redirecting to a page just to perform and action on the OnLoad event, as long as I could code pure C#.
You will find however that if you are going to be working with websites, you must have an open mind and start thinking more web-oriented (that is, don't try to do client-side things on the server and vice-versa). I love ASP.NET webforms and still use it (as well as MVC), but I will say that by trying to make things simpler and hiding the separation of client and server it can confuse newcomers and actually end up making things more difficult at times.
My advice is to learn some basic JavaScript (how to register events, retrieve DOM objects, manipulate CSS, etc.) and you will find web programming much more enjoyable (not to mention easier). A lot of people mentioned different Ajax libraries, but I didn't see any actual Ajax examples, so here it goes. (If you are not familiar with Ajax, all it is, is making an asynchronous HTTP request to refresh content (or perhaps perform a server-side action in your scenario) without reloading the entire page or doing a full postback.
Client-Side:
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest(); // Create object that will make the request
xmlhttp.open("GET", "http://example.org/api/service", "true"); // configure object (method, URL, async)
xmlhttp.send(); // Send request
xmlhttp.onstatereadychange = function() { // Register a function to run when the state changes, if the request has finished and the stats code is 200 (OK). Write result to <p>
if (xmlhttp.readyState == 4 && xmlhttp.statsCode == 200) {
document.getElementById("resultText").innerHTML = xmlhttp.responseText;
}
};
</script>
That's it. Although the name can be misleading the result can be in plain text or JSON as well, you are not limited to XML. jQuery provides an even simpler interface for making Ajax calls (among simplifying other JavaScript tasks).
The request can be an HTTP-POST or HTTP-GET and does not have to be to a webpage, but you can post to any service that listens for HTTP requests such as a RESTful API. The ASP.NET MVC 4 Web API makes setting up the server-side web service to handle the request a breeze as well. But many people do not know that you can also add API controllers to web forms project and use them to handle Ajax calls like this.
Server-Side:
public class DataController : ApiController
{
public HttpResponseMessage<string[]> Get()
{
HttpResponseMessage<string[]> response = new HttpResponseMessage<string[]>(
Repository.Get(true),
new MediaTypeHeaderValue("application/json")
);
return response;
}
}
Global.asax
Then just register the HTTP route in your Global.asax file, so ASP.NET will know how to direct the request.
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute("Service", "api/{controller}/{id}");
}
With AJAX and Controllers, you can post back to the server at any time asynchronously to perform any server side operation. This one-two punch provides both the flexibility of JavaScript and the power the C# / ASP.NET, giving the people visiting your site a better overall experience. Without sacrificing anything, you get the best of both worlds.
References
Ajax,
jQuery Ajax,
Controller in Webforms
The Microsoft AJAX library will accomplish this. You could also create your own solution that involves using AJAX to call your own aspx (as basically) script files to run .NET functions.
This is the library called AjaxPro which was written an MVP named Michael Schwarz. This was library was not written by Microsoft.
I have used AjaxPro extensively, and it is a very nice library, that I would recommend for simple callbacks to the server. It does function well with the Microsoft version of Ajax with no issues. However, I would note, with how easy Microsoft has made Ajax, I would only use it if really necessary. It takes a lot of JavaScript to do some really complicated functionality that you get from Microsoft by just dropping it into an update panel.
It is so easy for both scenarios (that is, synchronous/asynchronous) if you want to trigger a server-side event handler, for example, Button's click event.
For triggering an event handler of a control:
If you added a ScriptManager on your page already then skip step 1.
Add the following in your page client script section
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
Write you server side event handler for your control
protected void btnSayHello_Click(object sender, EventArgs e)
{
Label1.Text = "Hello World...";
}
Add a client function to call the server side event handler
function SayHello() {
__doPostBack("btnSayHello", "");
}
Replace the "btnSayHello" in code above with your control's client id.
By doing so, if your control is inside an update panel, the page will not refresh. That is so easy.
One other thing to say is that: Be careful with client id, because it depends on you ID-generation policy defined with the ClientIDMode property.
I'm trying to implement this but it's not working right. The page is
posting back, but my code isn't getting executed. When i debug the
page, the RaisePostBackEvent never gets fired. One thing i did
differently is I'm doing this in a user control instead of an aspx
page.
If anyone else is like Merk, and having trouble over coming this, I have a solution:
When you have a user control, it seems you must also create the PostBackEventHandler in the parent page. And then you can invoke the user control's PostBackEventHandler by calling it directly. See below:
public void RaisePostBackEvent(string _arg)
{
UserControlID.RaisePostBackEvent(_arg);
}
Where UserControlID is the ID you gave the user control on the parent page when you nested it in the mark up.
Note: You can also simply just call methods belonging to that user control directly (in which case, you would only need the RaisePostBackEvent handler in the parent page):
public void RaisePostBackEvent(string _arg)
{
UserControlID.method1();
UserControlID.method2();
}
You might want to create a web service for your common methods.
Just add a WebMethodAttribute over the functions you want to call, and that's about it.
Having a web service with all your common stuff also makes the system easier to maintain.
If the __doPostBack function is not generated on the page you need to insert a control to force it like this:
<asp:Button ID="btnJavascript" runat="server" UseSubmitBehavior="false" />
Regarding:
var button = document.getElementById(/* Button client id */);
button.click();
It should be like:
var button = document.getElementById('<%=formID.ClientID%>');
Where formID is the ASP.NET control ID in the .aspx file.
Add this line to page load if you are getting object expected error.
ClientScript.GetPostBackEventReference(this, "");
You can use PageMethods.Your C# method Name in order to access C# methods or VB.NET methods into JavaScript.
Try this:
if(!ClientScript.IsStartupScriptRegistered("window"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "window", "pop();", true);
}
Or this
Response.Write("<script>alert('Hello World');</script>");
Use the OnClientClick property of the button to call JavaScript functions...
You can also get it by just adding this line in your JavaScript code:
document.getElementById('<%=btnName.ClientID%>').click()
I think this one is very much easy!
Please try this:
<%= Page.ClientScript.GetPostBackEventReference(ddlVoucherType, String.Empty) %>;
ddlVoucherType is a control which the selected index change will call... And you can put any function on the selected index change of this control.
The simplest and best way to achieve this is to use the onmouseup() JavaScript event rather than onclick()
That way you will fire JavaScript after you click and it won't interfere with the ASP OnClick() event.
I try this and so I could run an Asp.Net method while using jQuery.
Do a page redirect in your jQuery code
window.location = "Page.aspx?key=1";
Then use a Query String in Page Load
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["key"] != null)
{
string key= Request.QueryString["key"];
if (key=="1")
{
// Some code
}
}
}
So no need to run an extra code
This reply works like a breeze for me thanks cross browser:
The __doPostBack() method works well.
Another solution (very hackish) is to simply add an invisible ASP button in your markup and click it with a JavaScript method.
<div style="display: none;">
<asp:Button runat="server" ... OnClick="ButtonClickHandlerMethod" />
</div>
From your JavaScript, retrieve the reference to the button using its ClientID and then call the .Click() method on it:
var button = document.getElementByID(/* button client id */);
button.Click();
Blockquote
Related
I have an ASP.NET application in VB.NET. I have a Javascript function in mypage.aspx and another one in my callback.aspx page. I need this scripts to render and submit an IFrame on mypage.aspx.
When I click on the submit button:
<asp:Button ID="subbtn" Name="Submit" OnClientClick="onsubmit_action();" runat="server" />
this script is executed, where iframeId is the id of the IFrame:
function onsubmit_action() {
submitPage('iframeId');
}
The response of the IFrame (validation or success) is submitted to the callback.aspx file. I guess this happens through cross-site scripting that calls the callback function in the callback.aspx file;
function callback()
{
parent.pagecallback_success('<%=Request.QueryString("Id")%>');
}
that calls the function in mypage.aspx
function pagecallback_success(ref_id) {
var Url = "mypage.aspx?";
Url += "id=" + id;
window.location.href = Url;
}
The script works as expected. Now, I would like to call a server function
Protected Function Store(ByVal id As String) As Boolean
in mypage.aspx.vb and pass the variable id:
function hostedpagecallback_success(id) {
var Url = "mypage.aspx?";
Url += "id=" + id;
window.location.href = Url;
"<%= Store(id) %>"
}
The problem is that the compiler considers id as a server side function and gives a compile error. However if I use a sub (without parameters) instead of a function, the sub is executed 3 times, on page_load, when the IFrame is received and another time (connection is https cannot debug Javascript efficiently).
I am not good in cross-site scripting and code nuggets, probably it is really trivial but I do not know how to solve this problem. Anybody?
I think you are looking for page methods a feature of MS-Ajax. Put the [WebMethod]
on the method you want to call (server side) and call it client side with something like PageMethods.GetData(f, s, OnRequestComplete, OnRequestError);
The whole pattern takes an article to describe.
http://www.dotnetfunda.com/articles/article454-using-pagemethods-and-json-in-aspnet-ajax.aspx
I am using an ajax htmleditor in asp.net web application so i am trying to get the text the user has entered in the editor then i will send that text back to the client javascript function that will show the text in a div. But I am getting this error "Object reference not set to an instance of an object."
Firstly i tried to access the text of textbox linked with htmleditorextender through javascript but it was not working for me so i moved to ajax webmethod but this time also i am facing a problem. Please Help me.
[System.Web.Services.WebMethod]
public static string seteditor()
{
String x="";
try
{
Content c = new Content();
x = c.txteditor.Text;
}
catch (Exception ex) { x=ex.Message; }
return x;
}
Here, txteditor is the ID of asp:textbox which is linked with ajaxcontroltoolkit htmleditorextender.
You cannot get your aspx controls inside a static method.
If you are Calling a static method from jquery means the Page and its Controls don't even exist. You need to look another workaround for your problem.
EDIT:
I always pass my control values to page methods like this:
Assume I have two text controls: txtGroupName and txtGroupLevel
...My JS with Jquery will be :
var grpName = $("#<%=txtGroupName.ClientID%>").val();
var grpLevel = $("#<%= txtGroupLevel.ClientID %>").val();
data: "{'groupName':'" + grpName + "','groupLevel':'" + grpLevel + "'}",
Where groupName and groupRights are my webmethod parameters.
EDIT2:
Include your script like this:
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery-1.4.1.js") %>"></script>
I suggest you to use the latest jquery version.
Web methods do not interact with the page object or the control hierarchy like this. That's why they're static in the first place. You need to pass the text from the client as a parameter to the web method, not read it from the textbox.
This issue was torturing me from last 18 hours continuouslyFirst I tried javascript than webmethod and than on user1042031's suggestion I tried jquery and than again I tried javascript and look how much easily it can be done with a single line of code.
var a = document.getElementById('<%= txteditor.ClientID %>').value;
read this stackoverflow article Getting Textbox value in Javascript
I apologize to everyone who responded me in this question but i have not found that article in my initial search.
I have a situation where I want to hit a button in the GSP (actionSubmit) and update a div when I finish the call (which includes a call to a javascript function). I want to ultimate end up in the controller rendering the searchResults parameter and the div with the results (which is currently working).
Problem is, I need to (presumably) wrap my actionSubmit in a remoteForm. But how do I:
1) Run the javascript method already existent in the onClick
2) Render the page in the controller.
If I try both wrapped in a controller, I finish the remoteForm action and the javascript action "hangs" and never finishes.
Any ideas?
List.gsp
<g:actionSubmit type="button" value="Ping All" onclick="getIds('contactList');"/>
function getIds(checkList)
{
var idList = new Array();
jQuery("input[name=" + checkList + "]:checked").each
(
function() {
idList.push(jQuery(this).val());
}
);
$.ajax({
url: "pingAll",
type:"GET",
data:{ids:JSON.stringify(idList)}
});
}
controller:
def pingAll() {
String ids = params.ids
if(ids == "[]") {
render(template:'searchResults', model:[searchResults:""])
return
}
def idArray = contactService.formatIDString(ids)
idArray.each {
def contactInstance = Contact.get(Integer.parseInt(it))
emailPingService.ping(contactInstance)
}
/**
* Added this on 3/13. Commented out line was initial code.
*/
def searchResults = contactSearchService.refactorSearchResults(contactSearchService.searchResults)
render(template:'searchResults', model:[searchResults:searchResults, total:searchResults.size()])
}
You have a couple options:
1) You can avoid using the Grails remote tags (formRemote, remoteField, etc.), and I really encourage you to explore and understand how they work. The Grails remote tags are generally not very flexible. The best way to learn how they work is to just write some sample tags using the examples from the Grails online docs and then look at the rendered page in a web browser. All the tags do generally speaking are output basic html with the attributes you define in your Grails tags. Open up your favorite HTML source view (i.e. Firebug) and see what Grails outputs for the rendered HTML.
The reason I say this is because, the code you've written so far somewhat accomplishes what I've stated above, without using any GSP tags.
g:actionSubmit submits the form you are working in using the controller action you define (which you haven't here, so it runs the action named in your value attribute). However, you also have an onClick on your actionSubmit that is running an AJAX call that also submits data to your pingAll action. Without seeing the rest of your code and what else is involved in your form, you are submitting your form twice!
You can simply just not write actionSubmit, and simply do an input of type button (not submit) with an onClick. Then in your javascript function that runs, define a jQuery success option for your AJAX call
$.ajax({
url: "pingAll",
type:"GET",
data:{ids:JSON.stringify(idList)},
success:function(data) {
$('#your-updatedDiv-id-here').html(data);
}
});
2) If you want to use the GSP tags, I think you are using the wrong one. Without knowing the full extent of your usage and form data involved, it looks like g:formRemote, g:submitToRemote, and g:remoteFunction could serve your purposes. All have attributes you can define to call javascript before the remote call, as well as defining a div to update and various event handlers.
There is a similar post Retrieving HTTP status code from loaded iframe with Javascript but the solution requires the server-side to return javascript calling a function within the iframe. Instead, I would simply like to check the HTTP status code of the iframe without having to call a function within the iframe itself since my app either returns the full site through HTML or the single object as JSON. Essentially I've been trying to implement a callback method which returns success|failure dependent upon the HTTP status code.
Currently I have uploadFrame.onLoad = function() { ... so far pretty empty ... } and I am unsure what to check for when looking for HTTP status codes. Up until now, I've mainly relied upon jQuery's $.ajax() to handle success|failure but would like to further understand the mechanics behind XHR calls and iframe use. Thanks ahead of time.
UPDATE
The solution I came up with using jQuery
form.submit(function() {
uploadFrame.load(function() {
//using eval because the return data is JSON
eval( '(' + uploadFrame[0].contentDocument.body.children[0].innerHTML + ')' );
//code goes here
});
});
I think the best solution is injecting <script> tag into your iframe <head> and insert your "detecting" javascript code there.
something like this:
$('#iframeHolderDivId').html($.get('myPage.php'));
$('#iframeHolderDivId iframe head').delay(1000).append($('<script/>').text('your js function to detect load status'));
Maybe it's not the best solution but I think it works
I have a Link button in DataGrid for to edit the grid data, I'm using OnClientClick event for loading a modal form and also i'm using onSelectedIndexChanged event function of the GRID for loading editing data to to controls. see the server side code below
protected void GetSelectedData(Object src, EventArgs e)
{
String Team_Id = GridView1.DataKeys[GridView1.SelectedIndex].ToString();
using (MySqlConnection DbConnection = new MySqlConnection(ConfigurationManager.AppSettings["ConnectionStr"]))
{
DbConnection.Close();
string cmdText = "SELECT Team_Id,Team_code,Team_Name FROM Team_Details WHERE Team_Id=?Id";
MySqlCommand cmd = new MySqlCommand(cmdText, DbConnection);
cmd.Parameters.Add("?Id", MySqlDbType.Int32).Value = Convert.ToInt32(Team_Id);
DbConnection.Open();
MySqlDataReader DR = cmd.ExecuteReader();
while (DR.Read())
{
this.txtTeamCode.Text = DR.GetValue(1).ToString();
this.txtTeamName.Text = DR.GetValue(2).ToString();
}
}
}
see the Client side code for invoking the modal window,
function EditDialog(){
$('#newTeam').dialog("open");
alert(document.Team.txtTeamCode.value);
document.getElementById("cvCode").innerHTML = '';
document.Team.txtTeamCode.focus();
}
The problem is, while poping up the modal form, the fields (team code & team name) are getting blank. Please provide a solution to solve this issue.
You could use an AJAX request to populate the modal pop-up's fields - call an object/service that would return the required data items and then modify the GUI accordingly.
Take a look at JQuery's get() function. For usability it's probably best to do this asynchronously.
Here's a decent tutorial that offers a possible implementation.
HTH
You can make use of httphandlers or as the prev user mentioned make ajax calls.
You can also make use of Pagemethods to call the server side code from javascript.