page life cycle when OnServerValidate fails (custom validator) - c#

I have a gridview within an update panel. When the page loads I have javascript enable/disable fields in the gridview (call it Function X(). When the update panel updates I use Sys.Application.add_load() to reload Function X(). This is all fine and dandy.
My problem:
When the custom validator's onservervalidate fails (args.IsValid = false) Function X() is not called and it needs to be called to enable/disable fields. How do I call Function X() at this point in the life cycle?

You will have to manually re-call your JavaScript functions, and you can do so like this, using JavaScript:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
function EndRequest(sender, args) {
functionX();
}

Related

Delaying Calling JQuery or javascript method from c#

I've got a mixture of JQuery and Ajax partial postbacks on a webforms page and I'm trying to stop the user navigating away from a page without their changes having been saved.
It's working pretty well unless one of the data validators on the page is invalid. There is a jquery method on the submit button that basically nulls the onbeforeunload event. In the event that the validators are invalid, I dont want that to happen, so I turned off the client side validation, and in the method, called Page.Validate(), then if the page was invalid, I tried to register a startup script as described here to reset like so:
if (!Page.IsValid) {
ScriptManager.RegisterStartupScript(this, this.GetType(), "", "setConfirmUnload(true);", true);
return;
}
If I run the click submit and the page is invalid, the call to setConfirmUnload(true) happens, but the method cant be found (presumably because I re-set this up every time a postback happens?
The actual error is " JavaScript runtime error: 'setConfirmUnload' is undefined", possibly because the bindEvents() hasnt yet re-run and therefore created it?
I thnk my problem stems from the fact that I am using partial postbacks and autopostbacks, setting up data as the user modifies the form. By default that blitzes my jquery, so I rebind the jquery calls on document.ready() as well as on postback using
<script type="text/javascript">
// attach the event binding function to every partial update
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (evt, args) {
bindEvents();
});
</script>
And my Bind Events method looks like:
function bindEvents() {
// stuff removed for brevity here...
$(function () {
// Prevent accidental navigation away
$(':input, select').bind(
'change', function () { setConfirmUnload(true); });
$('.noprompt-required').click(
function () { setConfirmUnload(false); });
function setConfirmUnload(on) {
window.onbeforeunload = on ? unloadMessage : null;
}
function unloadMessage() {
return ('You have entered new data on this page. ' +
'If you navigate away from this page without ' +
'first saving your data, the changes will be lost.');
}
window.onerror = UnspecifiedErrorHandler;
function UnspecifiedErrorHandler() {
return true;
}
});
}
If that's the case, is there a way I can force the script to run after the bindEvents() call has happened?

Executing Server-Side Methods by Clicking on a DIV

I'm working on an ASP.Net project, with C#.
Usually, when I need to put Buttons that will execute some methods, I will use the ASP Controller (Button) inside a runat="server" form.
But I feel that this really limits the capabilities of my website, because when I used to work with JSP, I used jquery to reach a servlet to execute some codes and return a responseText.
I did not check yet how this is done in ASP.Net, but my question concerns controllers and the famous runat="server".
When I add a runat="server" to any HTML Element, I'm supposed to be able to manipulate this HTML element in C# (Server-Side), and this actually works, I can change the ID, set the InnerText or InnerHtml, but the thing that I can't get, is why can't I execute a method by clicking on this element?
The "onclick" attribute is for JavaScript I think, and OnServerClick doesn't seem to work as well. Is it something wrong with my codes? or this doesn't work at all?
You will have to handle the click in the div using the Jquery and call
server-side methods through JQuery
There are several way to execute server side methods by clicking on a div or anything on your page. The first is mentioned __dopostback, second is handling the click in javascript or with jQuery and calling a function in a handler or a page method in a webservice or a page method in your page behind code.
Here is the handler version:
$("#btn1").click(function() {
$.ajax({
url: '/Handler1.ashx?param1=someparam',
success: function(msg, status, xhr) {
//doSomething, manipulate your html
},
error: function() {
//doSomething
}
});
});
I think the second version is better, because you can make a partial postback without any updatepanel, asyncronously. The drawback is, the server side code is separated from your page behind code.
Handler:
public class Handler1: IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
var param1= context.Request.QueryString["param1"];
//param1 value will be "someparam"
// do something cool like filling a datatable serialize it with newtonsoft jsonconvert
var dt= new DataTable();
// fill it
context.Response.Write(JsonConvert.SerializeObject(dt));
}
}
If everything is cool, you get the response in the ajax call in the success section, and the parameter called "msg" will be your serialized JSON datatable.
You can execute a method from jquery click in server, using __doPostBack javascript function, see this threat for more details How to use __doPostBack()
Add this code in your jquery on div onclick and pass DIv id whcih call click
__doPostBack('__Page', DivID);
On page load add this code
if (IsPostBack)
{
//you will get id of div which called function
string eventargs = Request["__EVENTARGUMENT"];
if (!string.IsNullOrEmpty(eventargs))
{
//call your function
}
}
Make the div runat="server" and id="divName"
in page_Load event in cs:
if (IsPostBack)
{
if (Request["__EVENTARGUMENT"] != null && Request["__EVENTARGUMENT"] == "divClick")
{
//code to run in click event of divName
}
}
divName.Attributes.Add("ondivClick", ClientScript.GetPostBackEventReference(divName, "divClick"));
Hope it helps :)
if you are referring to divs with runat="server" attributes, they don't have onserverclick events, that's why it doesn't work

How do I fire a aspx script when a dynamically added button is clicked?

Here is the context:
I am building a .aspx page that allows the user to administrate some xml documents we have on our server. The page content is loaded using AJAX, so buttons and forms are dynamically added to the document.
If I had static buttons that I was creating within the .aspx page before it loads on the client's machine, I could attach an event to it very easily. However, I'm dynamically adding and removing buttons and forms on the fly, using jQuery.
Here is a simplified example:
In the following jsFiddle, I'm pretending that the html document contains the following script:
<script language="C#" type="text/C#" runat="server">
void SaveAllChanges(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
clickedButton.Text = "foobar";
}
</script>
And that I have a javascript file that contains the following:
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
Obviously the buttons I am creating can not run the function SaveAllChanges with the way it is now. I added the onclick attribute to show what I needed to happen, in a pseudo-code kind of style.
How can I make it so that dynamically added buttons can run the C# method I have defined within the script tag at the top of the document?
Here is the jsfiddle: http://jsfiddle.net/2XwRJ/
Thanks.
You can give all buttons that must save changes a common class (e.g. class="ajaxButton") and have one jQuery method that responds to click events on elements matching that class (use live so that updates to the DOM are reflected).
$("button.ajaxButton").live("click", function(){
// Perform your Ajax callback to run server-side code
});
What you need to do is use something like ..
$(document).ready(function() {
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button id="#dynamicCommentButton" onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
$(document).on('click', '#dynamicCommentButton', function() {
alert($(this).attr('id'));
});
});
You are not going to be able to add the buttons like you have it there as this code here is just adding it as an HTML DOM element and the onclick attribute will be the on the client element. As a result clicking the button will try fire a SaveAllChanges javascript function
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
What would be best would be to create that SaveAllChanges function in javascript and then you can handle it from there. Two of the ways I see you being able to do this are:
Have a http endpoint setup (script service, web api or just posting to a page) that you call using Ajax from your javascript. You can then pass through any needed arguments.
You could have a hidden element and hidden button on the page so that when the javascript is called it populates any arguments you need and then clicks the hidden button and posts the page back.
Personally I would choose the first approach from a user experience stand point as the page will not be posting back each time. I have used something similar to the second approach and it works fine but just feels very clunky.

JQuery causing postback in .NET

I created an adrotator in jquery for the first time and when I use it on a page that uses pagemethods to do ajax calls to the server and show a modal. The page posts back. When I remove the rotator the page works as it should. In the rotator I have the following code in the document ready function.
$(".animation_control a.play").live('click', function () {
$(this).removeClass('play');
$(this).addClass('pause');
Play();
});
$(".animation_control a.pause").live('click', function () {
$(this).removeClass('pause');
$(this).addClass('play');
clearInterval(timer);
});
$(".animation_control a.pause").click(function () {
});
//Toggle Teaser
$("a.collapse").click(function () {
$(".main_image .block").slideToggle();
$("a.collapse").toggleClass("show");
});
If I comment out this code the page stops the complete page refresh and and posts back async like it should. Any ideas on why this would cause the page to do a complete postback instead of a partial one?
As a guess, since the code is incomplete, you should add return false to your event handlers to prevent the links from actually firing.
.live('click', function (e) {
e.preventDefault();
//your code
Anchors are used to navigate to a page/region in the same page, and according to this part, clicking an anchor MUST move us to the HREF that the anchor is pointing to.
in order to cancle this default behavior, we will need to do either return false or to prevent the default action using jQuery.
This is an example of what i mean.

Javascript event on page postback

Is there any javascript event which is triggered on postback?
If not, how can I run client side code immediately after or before a page postback?
I believe what you are looking for is the Sys.WebForms.PageRequestManager beginRequest Event
Excerpt:
The beginRequest event is raised before the processing of an
asynchronous postback starts and the postback is sent to the server.
You can use this event to call custom script to set a request header
or to start an animation that notifies the user that the postback is
being processed.
Code Sample: (From the link)
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args)
{
var elem = args.get_postBackElement();
ActivateAlertDiv('visible', 'AlertDiv', elem.value + ' processing...');
}
function EndRequestHandler(sender, args)
{
ActivateAlertDiv('hidden', 'AlertDiv', '');
}
function ActivateAlertDiv(visstring, elem, msg)
{
var adiv = $get(elem);
adiv.style.visibility = visstring;
adiv.innerHTML = msg;
}
</script>
I hope that helps. The PageRequestManager class seems to be little known about and little utilized.
Take a look at:
Run javascript function after Postback
I solved my problem using this:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function (s, e) {
alert('Postback!');
});
</script>
there are a lot of options too, like
$('#id').live('change', function (){});
$(document).ready(function () {});
ClientScriptManager.RegisterStartupScript(this.GetType(), "AKey", "MyFunction();", true);
and keep going. depends on what you need.
PageRequestManager events: https://learn.microsoft.com/en-us/previous-versions/aspnet/bb398976(v=vs.100)
You could add the javascript in your page load like this...
Page.ClientScript.RegisterStartupScript(this.GetType(), "alert",
"alert('hello world');", true);
OR
Page.ClientScript.RegisterStartupScript(this.GetType(), "alertScript",
"function Hello() { alert('hello world'); }", true);
The Page.ClientScript object has a RegisterOnSubmitStatement This fires after any input submits the form. This may or may not be what you're looking for, but I've used it for notifying the user of unsaved changes in editable forms.
The advantage to using this over RegisterStartupScript is that with RegisterOnSubmitStatement, if a user navigates away and back using the browser, whatever script you've injected using RegisterStartupScript could possibly fire again, whereas RegisterOnSubmitStatement will only run if the user has submitted the form.
Use AJAX, with an event handler for the onComplete.
The onsubmit event on the form tag
When using jQuery it's like this
$("#yourformtagid").submit(function () {
...
}
There isn't a javascript event triggered when a page loads after a postback, but you can add javascript to your html template (.aspx file) and only run it if the page was posted, like this:
<script type='text/javascript'>
var isPostBack = '<%= this.IsPostBack%>' == 'True';
if (isPostBack) {
alert('It's a PostBack!');
}
</script>
If you want to customize the javascript to run only under particular conditions (not just any postback), you can create a page-level variable (protected or public) in your page's class and do something similar:
var userClickedSubmit = '<%= this.UserClickedSubmit%>' == 'True';
if (userClickedSubmit) {
// Do something in javascript
}
(Nothing against ClientScript.RegisterStartupScript, which is fine - sometimes you want to keep your javascript in the page template, sometimes you want to keep it in your page class.)

Categories

Resources