ICodeFactory Labs

Dynamically adding ASP.NET validators and ASP.NET ajax validation callout extenders using Javascript

by Lacio 13. May 2010 01:33

Have you ever encountered a problem where you generated some content dynamically without the help of the server and server side code, but still needed to perform some basic validation on those contents?

That is exactly what this post deals with – validating content which is taken from dynamically generated input fields and adding the validation callout extender to it. 

Since I did not find any suitable solutions online, I decided to do it myself. Turned out the solution is not so hard at all, and after a small analysis on the page source of pages with regular validation, I got an idea on how to do it.

The first thing to notice is that after the aspx page is parsed, the output of a validator control (of any type) is a SPAN tag. Sort of. The tag has some unconventional attributes, off course depending on the type of the validator used, but we will get to that later. Besides this, a reference to the span is kept in an array called Page_Validators, which is an array consisting of all the validators present on the page.

So let’s go step by step.

First create the span tag and place it in the DOM where you would place the validator control. Lets say we have an input field and we place a RequiredFieldValidator next to it, like in the code below:

 

               // Get the table:
                var tblEditItems = $get('tblEditItems');
                // Get the number of rows currently in the table:
                var rowsCount = tblEditItems.rows.length;
                // Insert a new row at the end of the table:
                var row = tblEditItems.insertRow(rowsCount);

                // Insert a table cell:
                var cellName = row.insertCell(0);
                // Create an input field for the name:
                var elName = document.createElement('input');
                elName.type = 'text';
                elName.size = 10;
                elName.id = 'txtProductName' + globalControlCounter;
                cellName.appendChild(elName);

                // Add the span that will represent the validotor
                // (in this case the required field validator):
                var elNameValidator = document.createElement('span');
                elNameValidator.style.color = "Red";
                elNameValidator.style.display = "none";
                elNameValidator.id = elName.id + "Validator";
                elNameValidator.controltovalidate = elName.id;
                elNameValidator.errormessage = "<b>Field is incorrect</b>
                                     <br /> <span>Name is a required field.</span>";
                elNameValidator.validationGroup = "EditItems";
                elNameValidator.initialvalue = "";
                elNameValidator.evaluationfunction =
                                              RequiredFieldValidatorEvaluateIsValid;

 

The next step is to add the validator to the array of existing validators:

 

                // Push the new validator inside the page validators array:
                Page_Validators.push(elNameValidator);

 

After this is done, we can add the validator callout extender control, that will add some nice pop out effects displaying the error message itself:

 

                // Now lets bind the validator callout that will popup
                // up when the field is not valid:
                $create(AjaxControlToolkit.ValidatorCalloutBehavior, {
                    "closeImageUrl": "/image/close.png",
                    "highlightCssClass": "highlight",
                    "id": elNameValidator.id + "ValidatorCalloutExtender",
                    "warningIconImageUrl": "../images/attention.png"
                }, null, null, $get(elNameValidator.id));

 

The last step that needs to be taken and is essential for this to work is to add some dummy validator and dummy validator callout extender to the page. This is needed, as otherwise the necessary javascript libraries will not be included on the page (either this, or including the libraries by hand, whichever solution you prefer).

 

Now, the triggering of the validators is up to you – I used triggering when the user clicks some submit action. Since the action does not cause a postback, I needed some client side validation check. If you have the same problem, you can check out this simple solution located on this post.

 

As you can see, it is really easy to create the validation and add the validator callout extenders, with just a bit of knowledge in javascript. I recommend experimenting with different types of validators, as they all attach different attributes to the DOM element. If you have any questions or suggestions, feel free to post them to the comments section, I will try my best to help.

Currently rated 1.5 by 92 people

  • Currently 1.532607/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

.NET | ASP.NET | ICF.Labs

How to trigger an ASP.NET validator from JavaScript?

by Lacio 7. October 2009 04:40

Have you ever been in a situation when You were not able to perform server side validation and were not able to trigger the validators in the standardized way. By this I mean that you had a button that was doing a submit, but without causing any postback, and doing it all through JavaScript. In my case, I had a pagemethod that was doing a save for some entity we needed. So because of the nature of this operation, I needed to do a validation – and off course I used different kinds of validators – from range to required field and custom validators. So what is the problem then – the problem is that the JavaScript hides the form for the insert and the validation messages get lost, and along the way either a false insert or an exception is thrown – some fields might even be potential security breaches without proper validation. So I wandered around trying to find a way to perform regular validation, the way it is supposed to be done. I found a nice, elegant way to do it and even make it reusable on all the pages that need JavaScript validation and have the same problems as stated above.

 

An example of how validation works:

 

blogpic

 

So the solution is to write a small JavaScript function that will invoke all the validators that belong to a certain group. Below is the JavaScript function.

 

function ValidateEntry(validationGroup) {

  var isValidEntry = true;

  if (typeof (Page_Validators) != 'undefined') {

    for (var i = 0; i < Page_Validators.length; i++) {

      if (Page_Validators[i].validationGroup == validationGroup) {

        // call validator function

        var func = Page_Validators[i].evaluationfunction;

        Page_Validators[i].isvalid = func(Page_Validators[i]);

        if (!Page_Validators[i].isvalid) {

          isValidEntry = false;

          Page_Validators[i].style.visibility = '';

        }

      }

    }

  }

  return isValidEntry

}

 

So how does this work? The function returns a boolean value that suggests whether the validation is correct. The function goes through all the page validators, and selects the ones which belong to the specified validation group – this way we ensure only validators needed to be invoked are actually checked.

 

Later, we just call the ValidateEntry JavaScript function before calling the method that does the persisting – in my example, before calling a pagemethod that calls some server side method that does an insert in the db. The example is below:

 

First we have the controls that have the validators on them:

<td>

  <asp:TextBox MaxLength="50" ID="txtNewName" runat="server"

    Width="495px" ValidationGroup="NewEntityValidationGroup">

  </asp:TextBox>

</td>

<td>

  <asp:RequiredFieldValidator ID="valNewName" Text="*" ValidationGroup="NewEntityValidationGroup" runat="server" ControlToValidate="txtNewName">

  </asp:RequiredFieldValidator>

</td>

<td>

  <asp:TextBox ID="txtNewDescription" TextMode="multiLine" runat="server" Height="100px" Width="495px" ValidationGroup="NewEntityValidationGroup">

  </asp:TextBox>

</td>

<td>

  <asp:RequiredFieldValidator ID="valNewDescription" Text="*" ValidationGroup="NewEntityValidationGroup" runat="server" ControlToValidate="txtNewDescription">

  </asp:RequiredFieldValidator>

</td>

Then we have the pagemethod call with the call to the validation function (ValidateEntry):

 

function AddNewEntity() {

  if (ValidateEntry("NewEntityValidationGroup")) {

    var entityName = $get('<%=txtNewName.ClientID %>');

    var entityDescription=get('<%=txtNewDescription.ClientID %>');

    PageMethods.AddEntity(entityName.value, entityDescription.value, AddEntitySuccess, OnFailure);

  }

}

 

Lets analyze the function above – before we do any processing, we check all the validators, and only if the function returns true, we continue with the field value retrieval and call the pagemethod.

 

The best practice to use this type of validation would be to extract it to a new file and include the JavaScript file wherever it is needed.

 

If you want to incorporate this into your solution, feel free to go ahead and use the JavaScript function above, it is easy to integrate –just copy it to your solution, either to the page itself or to a JavaScript file and then just call it.

Currently rated 3.5 by 11 people

  • Currently 3.454545/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET 3.5 ListView control - Is it perhaps too early?

by Lacio 3. July 2009 04:50

The ListView control was introduced with asp.net 3.5 as an alternative to the existing data bound controls. It offers much more possibilities than the other controls, plus it generates clean html code, that will display just the way you tell it to. It offers all the possibilities of the other controls combined - selection, sorting etc. Despite all of this sounding quite nicely, it still has some unresolved issues that might hinder its usage in the early stages.

 

Being accustomed to using drag&drop and free naming techniques, the first strange thing that popped to my mind the first time I used the control was the need to name the itemplaceholder exactly "itemPlaceholder". That was strange at first, but only later  have I realised that this was a clever method to transform any control running on client side into a potential place holder for the item templates defined by the ListView control. However, I still found it strange that the name has to be hard coded, otherwise the control won't work. Why couldn't they add a property that holds the name of the itemplaceholder, instead of explicitly being forced to name it like that.

 

After coping with this annoying issue all in the name of being able to use a great new control that is still better then any of the other ones - it enables selected item template - which beats the repeater - and it generates the html you tell it to generate - unlike the datalist control, which is really messed up here, I found another really strange issue. I am not sure if anyone has encountered this problem, I did some short googling on the issue, and haven't found any spot-on fixes. Either people are not using the control, or I have a very specific version of the .net framework and it just won't obey commands from my keyboard :).

 

The issue happens when raising the SelectedIndexChanged event - first of all, it requires the SelectedIndexChanging event to even work. If you don't specify the indexChanging event, the compiler will report an issue. If you manage to get it started however, you are about to hit another unpleasent surprise. If you expect it to run normally, it won't - when having the select command the index will always be lagging by one step - The selected index will always be the next to last item you selected. The way to fix this is by set the selected index in the method raised by the SelectedIndexChanging event. This way, when you get to the selectedIndexChanged event, you will have the correct index and it will show it selected on the page.

 

Doing some research has revealed that it is the least used control of them all. For me personally, once you learn how to tame it, it becomes a very powerfull tool to display data. I believe that with the coming of the new version of asp.net the control will mature a bit
and become a regular feature on sites worldwide.

Currently rated 1.9 by 21 people

  • Currently 1.857143/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

.NET | ICF.Labs | State of Mind


Contact

Development and Sales
ICodeFactory d.o.o.
Trg Marije Trandafil 24/2
21000 Novi Sad
Serbia, Europe
Phone: +381 (0)21 41 77 08
info[at]icodefactory[dot]com

Headquarter
T.C. Bagljaš, Lok. 11
23000 Zrenjanin
Serbia, Europe

Working hours
Monday - Friday
8am - 4pm (GMT+1)