Run javascript function after Server-Side validation is complete - c#

Ok, I've got a lightbox with a small form (2 fields) in it, inside an UpdatePanel, and I want to close this lightbox (must be done via javascript) when the 'Save' button is pressed.
However, there is a need to have a server-side CustomValidator on the page, and I only want to close the lightbox if this returns as valid.
Does anyone know a way to trigger javascript (or jQuery) code from a server-side validator?

You can add a little snippet of code using the ScriptManager to execute after the response comes back to the UpdatePanel.
if (Page.IsValid){
ScriptManager.RegisterStartupScript(
customValidator1,
typeof(MyPageClass),
"closeBox",
"myLightBoxVariableOnThePage.close()",
true);
}

When that server side validator runs, it will send a whole new page to the browser. Anything that was shown in the browser before was destroyed, including any state kept in your javascript. If new page bears a strong resemblance to the old page, you should consider this a happy coincidence.
Therefore, the thing to do here is rather than executing a javascript function, have your CustomValidator make the correct changes to the page on success so that it's rendered to the browser correctly in the first place.

Related

WebBrowser and javascript

I am working with a website that has javascript that does some changes on the page load. However, when I load the page and handle the DocumentCompleted event, this change isn't there. If I then continue paste the DocumentCompleted event, I can see the change happen. However I need this change to happen during DocumentCompleted so I can check some things.
Is there an other event I can subscribe to, or a way to cause the webBrowser to do all the javscript on page?
Edit: This is what I am talking about.
I loaded a sample page just to show you, and clicked the submit button with all fields empty to generate an the error.
Here is the result:
http://s8.postimage.org/zfv6stcar/sfsdfsdfds.jpg
Now if I take the HTML at that precise moment from that WebBrowser control, and render it somewhere else, those errors go away. The same thing happens when the server sends back those errors. If I handle the DocumentCompleted event and take the html, it isnt there. But after the event, it shows up in the control.
Hope you understand, it's hard to explain.
The problem seems to be that the DocumentCompleted event is being fired before the javascript. You should do some reading on how client side/server side things function.
One option is to make a separate method for the DocumentCompleted event and call it form the javascript after it has been completed. This would get the sequencing of these events working properly, but is not very ideal.
Alternatively, you could call the javascript code at the beginning of your DocumentCompleted event. The link below gives a pretty good explanation of how to go about that.
http://forums.asp.net/t/1117189.aspx/1
Personally, I would avoid using javascript and do the validation on the client side .NET, but I don't know enough about the website to really say.
EDIT:
This should be the script you are looking for. Alternatively here is a thread related to your issue. Sorry I don't have the exact code as I don't have a project to test this on.
http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.registerstartupscript.aspx
Calling JavaScript Function From CodeBehind
RE-EDIT:
What is happening on the link you provided in the comments, is that each textbox is calling some javascript as well as the submit button. The best way to examine this is using the "Inspect Element" in the right-click menu on Google Chrome. For example, doing this on the textbox would show that it is registered with a few events:
onfocus="$('f_tip_Username').style.display = 'inline'"
onblur="$('f_tip_Username').style.display = 'none'"
onchange="$('f_err_Username').style.display = 'none'"
The first the element with the ID 'f_tip_Username', sets the display style of that element to inline (visible).
The submit button calls the following:
onclick="return o_edit_profile_form.validate()"
Doing a find on "o_edit_profile_form" in the source code, you can find the exact javascript location that is being called. Enjoy!
FINAL EDIT (hopefully?):
Follow these steps: go to your site, right click and go view source. Do a find for "f_tip_Username". This is the ID of one of the div tags being used. The third entry of it, should be a "div tag" that is used under the first textbox to warn of "min 3 characters".
You'll notice above that in the code is a input type "text" with the Name "Username". Notice the three events it has registered in it:
onfocus="$('f_tip_Username').style.display = 'inline'"
onblur="$('f_tip_Username').style.display = 'none'"
onchange="$('f_err_Username').style.display = 'none'"
These either hide or make visible, the div tag we found (f_tip_username) and also a separate div tag (f_err_Username) which is the error message div tag. Let me know if you are not able to find these in the source. Follow the steps I provided and you will find it in the "view source" OR in the DocumentText.

How can I use a Modal Pop Up control in ASP.NET similar to a WinForms Message box?

I am building a form, where required field validation must have been checked. I am not using asp validator. I am using JQuery validator like
function checkRequiredInputs(){
$("#frmSaleSubmissionInfo").validate({
rules:{
txtFName:{required: true},
txtLName:{required: true},
txtAddress:{required: true},
txtPhone:{required: true}
},
messages:{
txtFName:"Enter Name",
txtLName:"Enter Name",
txtAddress:"Enter Address",
txtPhone:"Enter Phone Number"
}
});
This is my client side validation. I am using c# in my code behind page. Now if I turned off allowjavascript option in my browser, as far as I know it won't allow javascript. So I am also doing server-side validation for required field. But, since ASP.NET does not have a message-box control, I am having trouble to let the user know what field he is keeping empty. Is there any way to use a control like the message box to show or let the user know what field(s) is/are required to fill the form successfully?
In my point of view, the best fitted to your requirement is using ASP.NET AJAX Toolkit ValidatorCallout control, which can help you to build such solution more fast way.
But if you don't want mixed up two javascript framework (ASP.NET AJAX and jQuery) than you can be expired here, where you can find a solution how to deal with a validation and jQuery.
If you want a modal popup, just send some javascript from the server code:
Response.Write(
"<script type='text/javascript'>alert('A required field is missing.');</script>");
alert() is a javascript function. Response.Write() adds the <script> element to the end of the HTTP response (i.e., the rendered HTML page).
A more elegant approach would be to use the ClientScriptManager to register a startup script:
protected void Page_Load(object sender, EventArgs e) {
this.ClientScript.RegisterClientScriptBlock(this.GetType(),
"RequiredFieldValidationScript",
"alert('A required field is missing.');",
true);
}
The javascript code alert('A required field is missing.'); will be executed after the postback.
See also: https://web.archive.org/web/20210417085026/https://www.4guysfromrolla.com/articles/021104-1.2.aspx
Without javascript, I can't imagine a simple way of recreating a modal type popup. You would have to go as to postback and re-render the page with a DIV blocking out the page and another div on top of it with the errors.
You can always pipe out the errors to a tag next to the submit button and call it a day though.

YUI Button initiates Postback Twice

I'm using ASP.NET 2.0 under VS 2005.
Page_Load is getting called twice for my .aspx pages. AutoEventWireup is set to true, but even if I set it to false and manually add the EventHandler, it still gets fired twice.
// also set AutoEventWireup to false
public _Default() {
this.Load += new EventHander(this.Page_Load);
}
// oops -- fired twice
In the Default.aspx page, after the user enters their username & password, I do a redirect to another page, but it seems to redirect back to the Default.aspx page.
I don't have any <img> tags without a src. The tags that have a RunAt="server" attribute are <asp:PlaceHolder>.
For everything else, I use YUI CSS and JavaScript. I don't have any <ASP:> controls.
What am I missing?
Update
I'm using the Button widget from the YUI library. If you specify "submit" in both Javascript and in the HTML code for a button, then when you submit, that JavaScript event gets generated twice.
This was a pain to figure out: I started commenting out bits and pieces of JavaScript and CSS (especially the includes), until the event fired only once.
A redirect is a postback in ASP.NET. If you trigger an event(enter user name and click, 1 postback), redirect to the same page(2nd postback). Am I understanding you correctly?
Are you by any chance using this.PreviousPage in the redirected Page ?
So I'm using the YUI framework. And I'm using the Button widget. If you specify "submit" in both Javascript and in the HTML code for a button, then when you submit, that Javascript event gets generated twice. Just remove one of the submits.
This was a pain to figure out: just start commenting out bits and pieces of Javascript and CSS (especially the includes), until the event fires only once. That way you can see what is causing the Page_Load to get fired twice.

user control event handler lost on postback

I have a menu usercontrol called LeftMenu that has a bulletedlist of linkitems. It's on the ascx page as such:
<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList>
I databind the list in the page_load under if(!isPostBack)
I'm having an issue on a page that loads the control. When the page first loads, the event handler fires. However, when the page posts back it no longer fires and in IE8, when I'm debugging, I get "Microsoft JScript runtime error: Object expected" in Visual Studio pointing at "__doPostBack('LeftMenu$PublisherList','0')." In FF I don't get the error, but nothing happens. I'm not loading the control dynamically, it's loaded on the aspx page using:
<%# Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %>
<Standards:LeftMenu ID="LeftMenu" runat="server"/>
Any ideas of where I'm losing the event handler?
I just realized this is happening on another user control I have as well. A text box and a button and I'm using the default button to make sure pressing the enter key uses that button. .Net converts that in the html to:
<div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')">
so as soon as i enter a key in the box I get a javascript error at the line saying "object expected." It seems like the two issues are related.
Edit Again: I think I need to clarify. It's not that I'm clicking on the menu item and it can't find the selected item on postback. I have this search page with the left navigation on it and then the main content of the page is something that causes a postback. Everything is fine with this postback. Once that page has been posted back, now if I click on the bulleted list in the left navigation I get a javascript error and it fails. The page_init for the LeftMenu control is never called.
It sounds like you might be losing the click because you are not DataBinding the list on PostBack. Therefore, the post back is trying to refer to a control (a specific bulleted list item) that does not exist.
You should try binding the list again on PostBack just to see if that fixes your issue. BUT, what should REALLY happen is that the LeftMenu and the BulletedList should store their information into ViewState so that you can ensure that the data that was shown to the user on their initial page load is the same data that the PostBack is processing and working with.
If you have EnableViewState=true for your UserControl and all controls within it, everything should work fine. With ViewState enabled, ASP will reinflate your controls from ViewState after Init has fired. This means that the postback event arg (which points to an index in your control list) will still find the control in that list position. Otherwise the list is empty on postback.
However, ViewState is the work of the devil and was designed simply to foster the illusion that you are working in a stateful environment. It is okay to use it for small amounts of data but typically not advisable for templated controls like repeaters and lists because you have no idea how much data is going to be created in ViewState.
If you are dealing with static, or relatively static data, store it in the application cache and rebind your lists in Page.Init every time (note that it has to be in Init because post-init is when ASP rebinds from ViewState; if you get in there first, your data will be used instead).
If you are dealing with volatile data, you have a problem because the data you rebind must be exactly the same as the original page request, otherwise the postback events will be firing against the wrong rows. In that case you need to either store your initial data in Session or you simply store the list of rows ids (in a hidden variable or Session) and you recreate the data to bind against from the ids each time.
An even better solution is to not use postback events at all. Try to turn all your events into GETs that have an ID on the query string. You can still create the list using binding the first time through the page (as you are currently doing), and you can even GET the same page with a new ID.
If you need to keep state on the same page but need to respond to the user changing a radio button selection (or something else), think about using Ajax calls to update the screen. You also do that with an ID that you pass to the Ajax call.
In general, the more you move from using stateful ASP, the lighter and more responsive your pages will become. You will also be in a better position to move to stateless MVC if necessary. You will also save lots of time lost to debugging obscure problems because ViewState is not available when you need it to be.
The best analysis of ViewState I've read is in the link below. If you fully understand how it works, you can continue to use it without necessarily incurring the costs.
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx
It's possible that this might be javascript related, and that a script that is loading earlier in the page is throwing an error and causing the page to not be loaded properly.
Are your usercontrols loading any javascript onto the page? Can you check for javascript errors on the initial load of the page?
I moved the code into an existing project we have and for some strange reason, I stopped getting the javascript errors and instead got:
"Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
I haven't quite figured out where I'm supposed to put the register event validation with a user control, but in the mean time I just set enableeventvalidation=false and it seems to work now.
It looks like the doPostBack function is missing since its arguments are literals so they couldn't be the cause. Is that one of your own functions or did you mean to call the ASP __doPostBack function?
Have a look at the Firefox error console or allow script debugging in IE and see exactly what object can't be found. Even better, download Firebug and debug it.
I had a similar issue. It turned out that Akamai was modifying the user-agent string because an setting was being applied that was not needed.
This meant that some .NET controls did not render __doPostBack code properly. This issue has been blogged here.

Popups with complex functionality using jQuery

I am using jQuery to simulate a popup, where the user will select a series of filters, which I hope to use to rebind a ListView in the original window.
The "popup" is opened via an ajax request and the content is actually a diferent aspx file (the rendered output is injected into a div that acts as the popup).
I have another ListView in this popup, and it has pagination.
My problem is that since the popup is in reality html content inside a div in the same page, when I try to paginate, the whole page postbacks and is replaced with the aspx that has the filters.
How can I fix this?
I tried using an update panel to contain the ListView but it didn't work.
$("div.yourthingie").hide();
Will hide the part you want to show :) Instead of generating the popup on the fly, leave a small part already made, and hide it in the begining, when you need to show, unhide and add the information you need to.
Hope it helps
Either get rid of the HTML "crust" and just produce the <div> with its contents, or use an IFRAME.
First, let's think through what is happening. When you submit the original page, you are taking a "normal" Request/Response trip to get the code. On the page is a JQuery AJAX bit that fires off what is essentially a modal dialog. The desired effect is the user plays with the new page until they have figured out their filters and submits back. The problem is this "modal page" loses information when someone paginates.
The solution to this is fairly simple, in theory. You have to store the "filters" in the popped up page so they can be resent, along with pagination information. OR you have to cache the result set while the user paginates.
What I would do to solve this is create a static page that has the "filters" in place and work out the AJAX kinks separate from having the page post back to a parent page. Once you have all of the AJAX bits working properly, I would then link it into the popup routine and make sure the pagination is still non-problematic. THe final problem is creating a JavaScript routine that sends back to the parent page and allows the parent page to send its JQuery bits back to the server.
I am not sure about the HTML DIV part of the equation and I think you can solve the problem without this solution. In fact, I believe you can make the "modal popup" page without invoking AJAX, if it is possible to either a) submit the filters to apply via the querystring or b) fake a form submit to the second page. The query string is an easier option, but it exposes some info. Faking a form submit is not that difficult, overall, but could be problematic with a popup.
I am just firing off some ideas, but I hope it spurs something for you.

Categories