Client-Side validation prvent Manually Postback by JavaScript eval() - c#

I encouter some postback issue when using GetPostBackEventReference. Here is the Scenario:
I have a javascript modal popup dialog and got a button in this modal dialog which used to select things (this is NOT an asp:button control)
When this javascript dialog HTML button is clicked, it will call the MS AJAX web service call by the javascript: eval() method. And this MS AJAX web service call is dynamically generated. So the code is like this:
var serviceCall = svcCall + "(" + parameters + ")"; //dynamically generate the MS AJAX web service call here
eval(serviceCall);
//use eval to trigger the MS AJAX web service call
As you may all know, after complete the MS AJAX web service, you can define a callback function to handle the completion:
function OnComplete(result, userContext, methodName) {
//force to call postback manually
eval($(userContext[0]).val());
//close the javascript dialog here
}
As I have mentioned before, the MS AJAX web service call is built dynamically, and when the MS AJAX web service call is construct, it will be passing a userContext which contain the postback value (i.e. "__doPostBack('ctl00$ContentPlaceHolder1$btnSelectUser','')", so when the javascript eval() is called, it simulate a asp:button click postback.
The userContext[0] basically holding a asp:hidden field's ClientID, and the hidden field's value is set during the Page_Load event:
protected void Page_Load(object sender, EventArgs e)
{
btnSelectUser.ValidationGroup = "popupSelect";
btnSelectUser.CausesValidation = false;
this.hdnBtnPostback.Value = Page.ClientScript.GetPostBackEventReference(btnSelectUser, string.Empty, false);
}
As you can see, this is how I bound the asp:button (i.e. btnSelectUser) 's Click Event to the asp:hiddenfield using the GetPostBackEventReference, and set the registerForEventValidation argument to false. I have also tried to use different ValidationGroup and set the CausesValidation to false, but no hope. :(
In summarize, I bound the asp:button's Click PostBackEventReference(i.e. __doPostback(....)) to the asp:hidden field's Value attribute, and using javascript eval() to eval this hidden field's value in order to manually trigger postback.
p.s. the btnSelectUser is an asp:button control and used to call out the javascript modal dialog.
Ok, here is the Problem:
In the same page, there is some asp:validator, e.g. and , and of coz, when the page run into error, this validator and callout will display to the user. e.g. When the user didn't fill in anything and submit the form, the ValidatorCalloutExtender will display a ballon and tell the user. Imagine one of this ballon/validatorCalloutExtender come out and on top of your screen at the moment.
Then you click the btnSelectUser (asp:button) to show the javascript modal dialog, and in the dialog, you Add some users, and once you hit the SELECT button inside this modal dialog, a MS AJAX web service is trigger as mentioned above, and once this web service is complete, it eval() the asp:hidden field's value (i.e. __doPostback(...))......and do the postback manually.
However, because of the validatorCalloutExtender ballon has display, it somehow cannot trigger the postback in this way, but when I close the ballon/validatorCalloutExtender, the manual postback using eval() is just working fine. Even more strange is that, when the ballon is displayed, the first time I click the SELECT button inside this modal dialog it doesn't fire the postback, however, if I do the same thing again (i.e. open up the javascript dialog, and choose some users, then click the SELECT button again). It able to do the manual postback....and I don't understand why the first time doesn't work.
This has really drive me crazy, hope anyone here can help, would be really appreciate. Thank you so much folks. :)
Have a nice day. Looking to heard from you all shortly.

When you call __doPostBack(eventTarget, eventArgument) a form submission is triggered:
This from post will proceed if WebForm_OnSubmit(); return true.
WebForm_OnSubmit result depends on ValidatorOnSubmit result, which in turn depends on
ValidatorCommonOnSubmit result if Page_ValidationActive == true.
Now if you are still with me, as in the function below:
function ValidatorCommonOnSubmit() {
Page_InvalidControlToBeFocused = null;
var result = !Page_BlockSubmit;
if ((typeof(window.event) != "undefined") && (window.event != null)) {
window.event.returnValue = result;
}
Page_BlockSubmit = false;
return result;
}
The result of ValidatorCommonOnSubmit depends on Page_BlockSubmit, so the only thing to block your postback is Page_BlockSubmit == true, it has nothing to do with validation callouts.
I was unable to simulate your case, but if you could post a full code sample it will help me track down the issue.

Related

Run Javascript when Asp.net page is loading

I wonder if there is way to run JS code whenever a asp.net page is contacting the server.
I.e. I'm looking for a general event handler that is triggered whenever a call to the server is made for runat="server" components.
I know there's a way to get jQuery.ajax() to run JS code before and after a call to the server is made, but I'm not sure how to do it in asp.net. Especially, since this projects uses a lot of custom components.
The goal here is to show some kind of loading image when a button is clicked, to prevent the user to click a button twice and also to show the user that the system is working.
If the click causes the page or an updatepanel to refresh, I'd only like to display the loading image before the refresh, eg. User clicks, "loading" is shown, page/update panel is refreshed (causing the "loading" to disappear), the new page/content is displayed as normal.
Update 1:
I can't use UpdateProgress because some of the buttons aren't inside UpdatePanels. What I really want to do is to fire a JS as soon as any button/control that will contact the server is clicked. I.e. if the user clicks a dropdown which doesn't contact the server, nothing should happend. But if that dropdown has any connection to the server, a JS should be run.
I understand that this is ASP.NET Ajax and not jQuery Ajax, I only used jQuery as an example. Because I've used a jQuery method before (with jQuery Ajax) to trigger JS before the server call was made. Eg. to lock the element that was clicked or to display a "Loading..." screen.
I could of course add a bit of a JS hack to every page which adds a "onclick" event to every button manually, but I thought it would be better if there was a general solution for this (since I've got lots of pages, each with a few buttons that contact the server on them).
Update 2:
When I think about it, it doesn't necessarily need to be a JS that is triggered. It would be good enough if the page somehow only made sure that the same button wasn't clicked twice. Either by disabeling the button or by adding something in front of it (like a "Loading..." screen).
You can use an UpdateProgress for this to use with update panels, but if you are doing a full page postback (i.e. not ajax) the only loading animation you can have is the browsers own.
UpdateProgress:
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Shiny loading aninmation
</ProgressTemplate>
</asp:UpdateProgress?
Here is how you can do it using jquery:
$(function() {
$('a[href]').on('click', function(e) {
var self = this;
e.preventDefault();
loadAsync($(self).attr('href'));
});
});
function loadAsync(url) {
$('div#result').fadeOut(200, function() {
$('div#loader').fadeIn(200, function() {
$.get(url, function(data) {
$('div#result').html($(data));
}).done(function() {
console.log('done');
}).fail(function() {
$('div#result').html('Error');
}).always(function() {
$('div#loader').fadeOut(200, function() {
$('div#result').fadeIn(200);
});
});
});
});
}

MVC 4 with jQuery Mobile page seems to be caching and controller method not being called

EDIT
Figured it out.. $.ajaxSetup({ cache: false }); wasn't working because i had data-ajax set to turned off on the form and therefore i wasn't able to set no cache ajax on it.. just for completeness if anybody knows how to get this done WHILE dada-ajax is set to false then please post so here
Something else that I just tried and it worked was to simply add data-ajax="false" to any link that you want a page refresh on. Meaning that if I have data-ajax="false" on a link it will always refresh the page before showing it!
For example the link I had a problem with was
Add a new weekly update
and the problem was that for some reason that page was caching and always showing the cached page.. So one of the easy fixes was to add data-ajax="false" to it and that forced a reload of the page everytime
Add a new weekly update
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
Question:
I have a options menu which brings up a form which also has a cancel and submit button.
Once the form is submitted there is certain validation that runs and if something is missing it returns to the form with some validation text.
Now if I click the cancel button at anytime i should be brought back to the options menu and if I click on the same button that brings up the form i should see a brand new clean form and this works fine if I do it before the validation.
The problem is that if I submit a non valid form which returns with the error validation messages and THEN press cancel it seems that the page becomes cached or something similar because from that point on anytime I click on the form options menu button the same form shows up each with the validation errors and data. I put a break point in the method that returns the form View() and they are never hit so for some reason it skips the entire method which creates a new form and somehow just shows the old page.
The cancel button is the following
Cancel
Does anybody know what is happening? is it being cached somehow when it returns to the same page with the validation errors??
** EDIT **
I Tried adding [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] in front of the controller by to no avail..
I also now added
$.ajaxSetup({ cache: false });
to the top of my $(document).ready(function () but that also does not seem to be doing anything, do I just put it there or do I have to call it somehow?
I checked System.Web.HttpContext.Current.Cache and the page doesn't show up there.
Have you tried setting the output cache options on the controller action like
[OutputCache(Duration=600,VaryByParam="id")]
You might also want to try making sure jquery is not caching the request as well. You can globally turn off jquery ajax caching using the information here: How to set cache: false in jQuery.get call
You can try using $.mobile.changePage() to transition to the page, it allows you to set some options, one of which is reloadPage.
reloadPage (boolean, default: false) Forces a reload of a page, even if it is already in the DOM of the page container. Used only when
the 'to' argument of changePage() is a URL.
Source: http://jquerymobile.com/demos/1.1.1/docs/api/methods.html
You could work this into your link with something like:
<script>
function changeMyPage(url) {
$.mobile.changePage(url, { reloadPage : true });
}
</script>
Cancel
jquery Mobile pulls multiple pseudo-pages into the DOM at one time and normally deletes (.removes()) a pseudo-page after you've navigated away from it. It however sounds like that's not happening so you may need to use my above code (or something similar) to force a refresh of the page.
You need to clear your ModelState before hand.
This should work:
if (ModelState.IsValid)
{
//saving
if (result > 0)
{
**ModelState.Clear();**
return View(new CategoryViewModel());
}
}
How to Clear model after submit the data in database in MVC3

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.

how can i call a javascript function when an ASP.net validation summary is filled

i have a validationSummary in my page. i want to call a javascript function after the validationSummary is filled. how can i achieve this?
i think i should add an attribute in the code behind, but i can't figure out what is the attribute's key.
any help?
You will want to call the javascript function Page_ClientValidate() to initiate the ASP.NET validation wired to your page controls. Once this is called, the Page_IsValid boolean value will be properly set.
Here is an example of how I am using it. If ASP.NET validation is successful, I disable the button, otherwise the button remains enabled and the validation summary is displayed to the user. The OnClientClick is from a ASP:Button control.
OnClientClick="javascript:Page_ClientValidate(); if (Page_IsValid==true) { this.disabled=true; }"
I don't think that's possible. It is, however, possible to intercept validation by setting OnClientClick on the controls that do postbacks. Then you can check the global JavaScript variable Page_IsValid for the validation result.
One thing to keep in mind is that, when there are no validators on a page, Page_IsValid will be undefined.
I started to implement the solution by #EverettEvola but also where the validation logic was being called multiple times and displaying multiple ValidationSummary popups. My solution was as follows:
On the button (in my case the button was a submit button)
OnClientClick="return CustomValidationOnClick()"
And the CustomValidationOnClick()
function CustomValidationOnClick(source, args) {
//Manually kickoff page validation
//This call will display the Validation summary popup if page is invalid
Page_ClientValidate();
//Page_IsValid set by the result of the Page_ClientValidate() call
if (Page_IsValid == true) {
this.disabled=true;
return true; //if Submit button return true to continue form submit
}
else {
//do whatever here
return false; //if Submit button return false to cancel form submit
}
}

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.

Categories