Asp Firing All Validation Summaries - asp.net

I need to make multiple validation summaries validate their controls and display any error messages.
I have a large form that I've broken into separate panels, each with it's own validation group and summary. I have one button that must validate the entire page and cause all the validation groups to be validated and show the error message.
My idea is to just iterate through a collection of Validators/Validation Summaries/Validation Groups in the code behind and fire their validate events, but I'm having trouble implementing it so that the validations summaries/errors appear on the page. Any ideas?
EDIT: I made a JavaScript function to try and get it working on the client side
<script type="text/javascript">
function validate() {
var t1 = Page_ClientValidate("vgpEmpInfo");
var t2 = Page_ClientValidate("vgpPanelA");
if (!t1 || !t2) return false;
return true;
}
</script>
But this only validates and displays the last validation group called, in this case Panel A.

So you are looking to do it all on the client then, not the server? The server would be easier as you could call Page.Validate("group"), and that would work for all the validation summaries.
Page_ClientValidate I didn't realize that would hide all the groups... but what you could try to do is call Page_ClientValidate for all. Now I'm not sure, but I think that it might just hide the <ul> representing the list, but I'm not 100% sure, so you may be able to just show all the <ul>'s representing each summary.... otherwise, you'd have to look at validatorValidate client method. Never done this, but seems like this might work, though the latter is going to be a real pain because you have to examine custom attributes on the validator span, and process accordingly.
HTH.

Related

Asp.net webforms autosave

I understand this may be an elementary question, but I'm new to Asp.net webforms, so please bear with me.
I have a lengthy form on a page that I would like to autosave when users type in a field, or make a selection. The problem is, all I've been able to find online is autosaves that work on a timer. I'd prefer that it saves as the user makes their edits. Also I would like just the individual form element being edited to be sent to the server to avoid sending the entire page back each time.
I've read that I should use a webservice to accomplish this, but since I want to autosave individual items and not the whole form on a timer, how would I set up a webservice to accomplish this? I'm new to webservices I'd like to know what to read up on. Any links are appreciated.
Also, how is the autosave functionality effected when using asp.net validation controls? I've looked around but can't tell if the entire page needs to be valid to make a trip to the server, or if just a single valid item can be sent itself.
Thanks for any help!
If you set AutoPostBack=True on the field, and you add an OnChange event for it (this will vary depending on the type of field the user is interacting with), you can execute a save. Don't call Page.Validate in the methods where you're doing these updates. Call it when you hit the Submit button.
This could cause a LOT of round trips to the server, and it's a lot of code to write and debug.
The Timer approach is one call to one method on a repetitive basis. If you can I'd recommend going with a timer, but sometimes that's not an option.
Generally speaking this is what you'll want to setup on the client-side. Ideally, you will end up with lots of tiny requests which do not require much power on the back-end. This however depends on lots of variables including the database engine you're using.
$(document).ready(function () {
$("input").blur(OnFieldChanged);
});
function OnFieldChanged()
{
var $this = $(this);
var isValid = ValidateField($this);
if (isValid)
{
SaveField($this);
}
}
function SaveField($field)
{
if ($this.val() === $this.prop("oldVal")) return;
var data = {
id: $("idfield").val()
};
data[$field.attr("id")] = $field.val();
$.post({..}).done(function() {
NotifySaved($this);
$this.prop("oldVal", $this.val());
});
}
function ValidateField($field)
{
// Validate the field with your method of choice, manually call Microsoft's client-side validate function or switch to jquery validate.
return true;
}

Lightswitch HTML databinding to a details collection

I have a simple master/details relationship where one order can have multiple revenue allocations. The order has a collection that contains these.
I want to sum a property in my revenue allocation objects and ensure that it adds up to my order total. However, if I databind on the count property of the allocations collection this gets called when you first add an empty object and not when that object has been populated. So an empty allocation is added at the time the "Add allocation" screen is created and the databind function called. That of course means that when the save button on the "Add allocation" screen is clicked, the databind function isn't called again.
Anyone got any ideas? I basically want my databind function to be called when the save button is clicked in the "add screen" and not before.
This is the HTML client - NOT Silverlight
I'm pretty sure that the solution would be to use an OData query to get your aggregate data within the databinding function of the save button - or perhaps a separate button (e.g. "Tally Order Totals"). Exactly how you do that? A bit too hard for me to answer right now, but start with a new button TallyOrderTotals and a new data field for your total. Edit the post_render event for TallyOrderTotals and lookup the allocations in the javascript in which you data bind the value of the new data field.
Somewhere you will need a piece of code that looks something like this:
myapp.activeDataWorkSpace.<datasource>.RevenueAllocations
.filter("OrderID eq " + msls._toODataString(<orderID>, ":String"))
.execute()
.then(function (result) {
// assign the result somewhere
}
I'm not saying that's something you can cut-and-paste - but definitely look at the msls.js documentation and see what you can do with querying your data inside the event context.
One quick point however - if you only need to calculate that total as a verification step, consider doing it in the SaveExecuting() event on the server side. This will allow you to throw an exception back up the tree to your HTML page which the msls.js script should render on the client side.
Hope that helps. :)

Asp.Net / Ajax updating update panel automatically how to?

I have an Asp.net page which requires certain sections to be partially updated automatically at an interval of 5 seconds.
I was planning to use the good old Timer control with the AJAX Update Panel for this purpose, but after a bit of reading on this control i found out that it may have some problems especially if,
1) The time difference between the async event performed ( 4 seconds ) by the update panel and the Timer's tick interval ( which is 5 seconds ) are quite small, the update panel will be held up in the async operation all the time.
2) Also, the fact that timer control doesn't work very well with Firefox.
I just wanted to get your opinion as to whether if i should go ahead with the timer and update panel approach, write some custom javascript that does the partial page update or some other strategy altogether.
Personally, I tend to think that the DIY approach is better -- easier to debug and easier to write.
You can use a javascript setInterval for a timer, and every time the function is called, you can initiate an ajax request to your asp.net code-behind to fetch whatever data needs to be updated.
For example, let's say you simply need to, every 5 seconds, update the current time on a page. Let's assume you have a span of ID currentTime on your page, something like:
<asp:Label id="CurrentTime" runat="server" CSSClass="currentTimeLabel" />
In your initial PageLoad event, you set the time:
protected void PageLoad(...)
{
CurrentTime.Text = DateTime.Now.ToString();
}
Now you need to define some javascript on your page that will, every 5 seconds, call the code-behind and get the new date/time value.
Doing this with something like jQuery is very simple:
$(document).ready(function() {
setInterval(5000, updateTime);
});
function updateTime() {
url: "myPage.aspx/SomePageMethod",
success: function(data) {
$(".currentTimeLabel").text(data);
});
}
In ASP.NET, getting the PageMethod to work is the trickiest part (for me, anyway). You need to create a public function in your code-behind with a 'WebMethod' attribute. Something like this:
[WebMethod]
public static string GetCurrentTime()
{
return DateTime.Now.ToSTring();
}
I didn't test any of this code, but the basic premise is sound and should work fine.
Now, this may seem more complicated than using an UpdatePanel, but I find it easier when I know what code is actually running on my page.
If you need to update a series of controls instead of just one control, you can use a more complicated web method that returns xml or json data, and then parse that using javascript.

custom validator against remote object

I have a need to validate a field against our database to verify unique-ness. The problem I seem to be having is that the validators doValidation() exits before we've heard back from database.
How can I have the validator wait to return its payload until after we've heard from the DB?
Or perhaps a better question might be (since I think the first question is impossible), how can I set this up differently, so that I don't need to wait, or so that the wait doesn't cause the validation to automaticallly return valid?
If you're using a remote object, you can specify the method call inside your remote declaration and assign a function to the result call. The result call only runs once the remote server returns something, so it won't be run before your validation.
Do your validation call in said result function call (which you will have to create) and you should be good. Your code should go something like this:
<s:RemoteObject id="employeeService"
destination="ColdFusion"
source="f4iaw100.remoteData.employeeData"
endpoint="http://adobetes.com/flex2gateway/"
result="employeeService_resultHandler(event)"/>
**<s:method name="dataCheckCall" result="dataCheckResult(event)"/>**
<s:RemoteObject />
And in your script:
function protected dataCheckResult(event:ResultEvent):void {
**doValidate();**
}
Edit: As soon as you call "dataCheckCall" the method will start running. If, for whatever reason, you want to call this WITHIN your validator, you can do so, and then dataCheckResult will run whenever it returns with it's payload (pretend doValidate is called elsewhere). I've left a message below as well.
You are trying to fit an asynchronous process (fetching data from a DB) into a synchronous process (checking all the validators in turn).
This won't work...
You'll need to either roll your own validator framework, or use a different method of determining the legality of your controls.
P.S. The MX validators are rubbish anyway!
What I've managed to do, seems to work, mostly. I don't like it, but it at least performs the validation against the remote source.
What I've done, then, is to use an 'keyUp' event handler to spin off the database lookup portion. In the meanwhile, I set up a string variable to act as some kind of a Flag, which'll be marked as 'processing'. When the response event fires, I'll examine its contents, and either clear the flag, or set it to some kind of other error.
Then, I have created a new 'EmptyStringValidator' will check the contents of this flag, and do its job accordingly.
Its indirect, but, so far, seems to work.

Detect when ALL HTML page rendering has taken place

I am working with a pretty complicated .aspx page that is full of controls (Telerik, Ajax, etc.) that all expand, collapse, show, hide, etc. when the page is loaded. Since this rendering happens on the client-side and can take different lengths of time based on the users machine specs, is there a way to detect when all (or some) rendering has taken place (jQuery?) so I can then act on specific elements, knowing they are fully rendered?
JavaScript is single threaded. The time passed to setTimeout is a minimum, but not a maximum, so if you pass something like 10(ms), you essentially are saying "execute this code after all the currently running code is finished."
So, if all the controls use $(document).ready() to do their thing, all you need is:
$(document).ready(function() {
setTimeout(function() {
doStuff();
},10);
});
doStuff will be called after all the functions passed to $(document).ready have run. However, this isn't foolproof. If the controls have their own way of detecting whether the document has loaded, or do their own setTimeout(), you're in trouble. The problem is that JavaScript does not guarantee the execution order of setTimeouts. Sometimes your code may run last, other times it may run before the setTimeouts used for the animation.
One last idea: if all the animation is done using jQuery, then the effects run in a single queue. In doStuff you could add an animation of some sort with a callback and be reasonably certain that the callback would run last.
Whenever I had to wait for multiple things to be ready before proceeding, I would create an array with true/false values. Every mandatory part of the page got an event which, when it is called, updates the specific entry in the array to true. Also, it called a general function which returned true if all values in an array was true, otherwise false.
If that function finally returned true, I would proceed with the execution. It is especially useful if you have to wait for an AJAX call to end but don't want to use async = true. It also is useful if you want to start loading multiple things at once instead of one after another, since they all report ready-state to the same array.
It does however use global variables so you might need to do some optimizations. You might not want to do this approach either if you have a grudge against global variables.
You should place your code inside the jQuery $(document).ready() function. This will ensure that all elements are loaded before the code runs.
http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
I think the doc you need is:
http://docs.jquery.com/Events/load
"I can then act on specific elements, knowing they are fully rendered?"
You can use the load method (linked above) to attach to any element. So if you had a div with an id of "lastElement", you could write
$('div#lastElement).load(runThisFunction);

Resources