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

ASP.NET AJAX 4.0 Templates Simple Demo - Step by Step

by Sergio 27. November 2009 02:59

This quick step by step tutorial is made with Visual Studio 2010 beta2
and ASP.NET AJAX 4.0 Preview 6.
It is possible that some properties and/or methods will be changed in future versions, but so far this is the way to use client side templates in ASP.NET AJAX 4.0.

 

Downloads

First you should download appropriate software:

  1. Microsoft .NET Framework 4.0
  2. Microsoft Visual Studio 2010
  3. ASP.NET Ajax Library

Project

For your first project you should use web site or web project visual studio templates, create new project and add appropriate scripts to a project.

For this example I’ve created a new web site and added all the AJAX scripts we need to a folder named “MicrosoftAJAX” (look at the picture).

 

WebSiteProjectFiles

 

Also I have created a simple demo xml web service to be used from client side to read data for our template.

 

   1:  <%@ WebService Language="C#" Class="DemoService" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:  using System.Web.Services;
   6:  using System.Web.Services.Protocols;
   7:   
   8:  [WebService(Namespace = "http://icodefactory.com/", 
   9:     Description="Demo web service used by client side templates")]
  10:  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  11:  // To allow this Web Service to be called from script, 
  12:  // using ASP.NET AJAX, uncomment the following line. 
  13:  [System.Web.Script.Services.ScriptService]
  14:  public class DemoService  : System.Web.Services.WebService {
  15:   
  16:      [WebMethod(Description="Returns Demo Contacts data")]
  17:      public Contact[] GetContacts() {
  18:          Contact[] contacts = new Contact[3] {
  19:              new Contact(){ Id=1, Name = "John", Lastname="Doe" },
  20:              new Contact(){ Id=2, Name = "Joan", Lastname="Smith" },
  21:              new Contact(){ Id=3, Name = "Brad", Lastname="Forbs" }
  22:          };
  23:          return contacts;
  24:      }
  25:      
  26:  }

 

Pay attention that you have to set the ScriptService attribute so your web service can be used from JavaScript.

 

Finally we have to add some simple html (yes, pure html) file and import appropriate scripts:

  • MicrosoftAjax.js
  • MicrosoftAjaxTemplates.js

for AJAX client side libraries and

  • DemoService.asmx/jsdebug

for access to the xml web service.

 

   1:  <script src="MicrosoftAJAX/MicrosoftAjax.debug.js" 
   2:          type="text/javascript"></script>
   3:  <script src="MicrosoftAJAX/MicrosoftAjaxTemplates.debug.js"
   4:          type="text/javascript"></script>
   5:   
   6:  <script src="DemoService.asmx/jsdebug" 
   7:          type="text/javascript"></script>

 

We also need some styling on the page. Class ‘sys-template’ is used to hide empty table before data is bound from the service by using AJAX DataView client side control.

 

   1:  <style type="text/css">
   2:          /*Used to hide empty table*/
   3:          .sys-template
   4:          {
   5:              display: none;
   6:          }
   7:          /* Style of table that shows data*/
   8:          .table_style
   9:          {
  10:              background-color: Olive;
  11:              padding: 5px 5px 5px 5px;
  12:          }
  13:      </style>

 

Now, time for JavaScript that should load the data from the xml web service, fill the DataView object and bind the data to the html template.

 

<script type="text/javascript">
        // ASP.NET Ajax client side control - DataView
        var contactsView;
        
        // Triggers on page load
        function pageLoad() {
            // Create Contacts DataView
            contactsView = 
                      $create(Sys.UI.DataView, {}, {}, {}, $get("contactsBody"));

            // Load Contacts from web service
            DemoService.GetContacts(ContactsLoaded);
        }
        
        function ContactsLoaded(contactsData) {
            // Display data in Contacts DataView
            contactsView.set_data(contactsData);
        }
    </script>

 

The pageLoad function creates the DataView client side object and calls the xml web service to populate the object with data.

On successful service call the data is bound to the html with a simple call to the set_data() function.

 

This is how your template should look:

 

   1:  <table class="table_style" border="0" cellpadding="4" cellspacing="4">
   2:          <thead>
   3:              <tr>
   4:                  <th>
   5:                      Name
   6:                  </th>
   7:                  <th>
   8:                      Lastname
   9:                  </th>
  10:              </tr>
  11:          </thead>
  12:          <!-- tbody tag id is used to identify tag in DOM that are going to be
  13:               used by the DataView. Class is set to 'sys-template' in order to
  14:               hide empty table -->
  15:          <tbody id="contactsBody" class="sys-template">
  16:              <tr>
  17:                  <td>
  18:                      {{ Name }}
  19:                  </td>
  20:                  <td>
  21:                      {{ Lastname }}
  22:                  </td>
  23:              </tr>
  24:          </tbody>
  25:      </table>

 

<tbody> tag is used to become a template for the data in the DataView object.

DataView will change HTML with appropriate tags and generate table rows for every data row from the xml web service method call.

{{ Name }} and {{ Lastname }} parts will be replaced with actual data.

 

At the end you have your data.

 

DemoSite_Result

 

Hope this will help you start with the new templates. Web development is moving to client side and everyone should embrace the client side because of its many benefits, like responsiveness, bandwidth and UI patterns.

 

Demo Solution may be downloaded from our public download section.

Currently rated 1.8 by 31 people

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

Tags: , , ,

ASP.NET

FCKEditor with ASP.NET - Fix “The server did not send back a proper XML response error”.

by Sergio 7. July 2009 10:47

I like FCKEditor. Our company is using it on several projects, and it mainly works fine, it has a number of different functionalities and it integrates well.

Recently we integrated FCKEditor with an asp.net 3.5 web application. We wanted to allow the client to update some contents on the web site and upload/manipulate images, but we faced a strange exception that stated:

The server didn’t send back a proper XML response. Please contact your system administrator.
XML request error: Ok (200)

 

xmlrequesterror_image1

Response text looked scrambled and messy.

Our first reaction was to search for the same bug on net, but after a few days I did not find anything barely useful!

That’s about when I realized I’ll have to investigate it by myself.

First of all I supposed I should blame some response mime type or format, so I dived into the FCKEditor project source code and found a class named XmlResponseHandler.

This class is used to clear the response object, set the content encoding and content type.

It all looked well. It was time to put some break points and investigate what is going on there.

I monitored two methods: SetupResponse and SendResponse.

private static void SetupResponse( HttpResponse response )

{

// Cleans the response buffer.

response.ClearHeaders();

response.Clear();

// Prevent the browser from caching the result.

response.CacheControl = "no-cache";

// Set the response format.

response.ContentEncoding = System.Text.UTF8Encoding.UTF8;

response.Charset = "utf-8";

response.ContentType = "text/xml";

}

public void SendResponse()

{

SetupResponse();

Response.Write( Xml.OuterXml );

Response.End();

}

Let’s put some break points and check what is going on while looking for the xml response from the server.

code_with_break_points_image2

My attention was drawn to data.

xmldata_image3

SendResponse method has a well formed xml. Let’s go further through the code.

Oops!

The server didn’t send back a proper XML response. Please contact your system administrator.

XML request error: Ok (200)

 

The same error again. Good. That means it is not about the data. Response looks like it is scrambled or packed when it comes to the client side!

That is a clue. Let’s investigate an interesting property of the Response object. It is the Filter property.

Response.Filter is a stream that is used to process data before it is sent to browsers, so if you, for example like to convert all cases to upper this is the place for your custom stream.

I investigated that property and found its value interesting.

deflatestream_image4

There was a DeflateStream object. This means response is compressed by server and sent to client as a compressed stream. This is why I got and strange encoded characters as error.

Fix was easy. I added one line of code:

Response.Filter = null;

private static void SetupResponse( HttpResponse response )

{

// Cleans the response buffer.

response.ClearHeaders();

response.Clear();

response.Filter = null;

// Prevent the browser from caching the result.

response.CacheControl = "no-cache";

// Set the response format.

response.ContentEncoding = System.Text.UTF8Encoding.UTF8;

response.Charset = "utf-8";

response.ContentType = "text/xml";

}

Build the solution and run it again. It works.

It was simple fix, but a very hard one to find. What is most amazing for me is that it was not found by other members of the community so far. I hope this article will help. Does it?

Currently rated 4.0 by 11 people

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

Tags: ,

ASP.NET


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)