Friday, 17 August 2007

Validate Controls in a Repeater

I have a list of prices of tickets that people can book online.

This list is created dynamically from a database Products table and displayed using an ASP.Net Repeater control.

The issue is how to restrict input into the Quantity field for each ticket type to only allow numbers.

First i found an article on the Code Project which uses JScript function to handle a key press event and then check the contents of the textbox against a regular expression - but i thought i could find an easier i didn't understand how the javascript was working.

Then I started searching for JavaScript functions that would do the validation on the client side. Of course, I would employ server side validation as well in the event that JavaScript was disabled. However, after an hour or so reading about JavaScript events and browser incompatibilites regarding the naming of event properties (see this article: Introduction to events) I decided that I would look into the .Net abilities first and then deal with client side stuff at a later date. After all, server side validation is priority one for this project.

Then i found this solution: which uses a CustomValidator controls and javascript - but i guessed that this might have some issues regarding compatibility between browsers.

After a quick search on the web, I found this post velocity reviews which explained that you have to include a range validator for each textbox control in the repeater - therefore, its best to place it in the ItemTemplate.

The next issue is that i think it would be best to have Validation Summary control to display a one message for all the textboxes that may have invalid input. However, ASP.Net doesn't expose a property of the ValidationSummary control to allow to customise the message that the control displays.

So I had a go at using a RangeValidator within the ItemTemplate and placing a ValidationSummary before the repeater control and setting the HeaderText="Please enter only numbers in the marked (*) fields".

The result after entering poor input:

The problems with this:

1. The ValidationSummary control was displaying the ErrorMessage of each RangeValidator control in a list (as its intended to do), creating a meaningless list of *'s at the top of the repeater. All i want is one error message at the top saying correct the fields marked with an '*'.

2. Also, for the Zoo Guide item, it has been marked as invalid even though it contains only numbers as i set the MaximumValue="999" attribute of the RangeValidator in order to avoid an error i was getting (The value '' of the MaximumValue property of 'rngvTxtQty' cannot be converted to type 'Integer'.)

3. Lack of client side validation: it would be much better to simply not allow alphabetic characters into the text boxes. This would avoid the nasty looking '£NaN' labels...which are occurring due to client side total calculation functions i have in place, which are evaluating to Not a Number.

I solved two of these issues:

1. After a little more searching, i came across this post, which explained that RangeValidator control has both a Text and ErrorMessage property. The Text property will be displayed in a simliar fashion to the ErrorMessage property, however, it is not displayed by the ValidationSummary control. So, i left ErrorMessage undefined and set Text to "*".

2. Set the MaximumLength of the txtQty to '3'.

Here is the result:

3. This issue will have to wait a while till i get my head around the client side validation. Stay tuned!


I thought i had this licked...but no.

The range validator still allowed spaces to be entered which broke my code in my classes when i attempted to Convert.ToInt32(txtBoxQuantity.Text).

So i was left with two options:

1. Employ a validator that didn't allow spaces in the text boxes.
2. Strip out the spaces from the input or do something in the code-behind to avoid attempting to convert a space character into an integer.

I decided to attack the problem via option 1 above as it made more sense to me that the code-behind, specifically the Convert.ToInt32 method should expect a correctly formatted parameter.

After having no luck searching for a solution to the spaces problem, I put the issue on hold on moved on to the next requirement:

In order for this booking to take place, users had to order a minimum of 15 paying tickets.

This requirement presents (at least) two challenges:

1. Looping through the textbox controls and adding up the values.
Sounds simple enough but as i found when developing the on-the-fly total calcualtions, the id of the textbox controls are not unique on the server side and are generated on the fly by .Net on the client side. This isn't so complex if all i wanted was the total number of tickets but i need to...

2. Associate each quantity text box against the price label in order to determine whether the value in the quantity field is a paying ticket or not.

No comments:

Post a Comment