Validation

Client validation

The library provides support for client-side lightbox validation. There are different ways to implement it and which one to apply depends on the lightbox you use.

  • If you use a standard lightbox (like the one shown here), you should employ the built-in means such as DataProcessor.
  • If you use a server form (like the one shown here), you should employ external resources, e.g. Data Annotations.

Native lightboxes

Generally, to validate a standard lightbox you should use events provided by the scheduler API (see the full list here) and catch the input data to handle respectively to correctness.

The simplest validation can be achieved with the help of the onEventSave event. The event is invoked when the user clicks on the form 'save' button. Returning true from the event will save the changes, returning false will cancels further processing and leaves the lightbox opened.

Here is the client code you can put on the page right after scheduler initialization:

scheduler.attachEvent("onEventSave", function (id, data, is_new_event) {
     if (!data.text) {
          dhtmlx.message("Event text can't be empty!");
          return false;
     }
     return true;//returning true will save the changes
});

The solution above has a shortcoming - the event won't fire if the data in the lightbox was changed through an inline editor (such a possibility there is in the day and week views) or by dragging over the scheduler.

To prove this and catch all changes made in the scheduler (editing, creating, deleting etc.), you should use the scheduler.dataProcessor object or, to be accurate, one of its events - onBeforeUpdate (know more on the topic here). The event occurs before sending data to the server and after any change made in the scheduler (not only in the lightbox).

scheduler.dataProcessor.attachEvent("onBeforeUpdate", function (id, status, data) {
     if (!data.text) {
         dhtmlx.message("Event text cant be empty!");
         return false;
     }
     return true;
});

Note, when the field fails validation, changes aren't sent to the server but stay on the client and can be used for further processing.

Custom lightboxes

There are various solutions for validating server forms and we will consider one that uses Data Annotations (know more on the topic here). Note, the default lightbox applies its predefined logic that doesn't allow using the Data Annotation.

Generally, to perform validation with the Data Annotation Model Binder you should:

  1. Add references to the System.ComponentModel.DataAnnotations.dll assembly.
  2. Add the required validation attributes to the model class:

    using System.ComponentModel.DataAnnotations; 
    public class Event
     {
            [Required]
            public int id { get; set; }
            [Required, StringLength(256)]
            public string text { get; set; }
            [Required]
            public DateTime start_date { get; set; }
            [Required]
            public DateTime end_date { get; set; }
      }
  3. Finally, your form view with validation support should look like this:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SchedulerTest.Models.Event>" %>
    <html>
    <body>
     
    <% 
        Html.EnableClientValidation();
        Html.EnableUnobtrusiveJavaScript(); 
    %>
     
    <html>
    <head>
        <script src="/Scripts/jquery-1.8.0.min.js" type="text/javascript"></script>
        <script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
        <script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
    </head>
    <body>
        <% using (Html.BeginForm("Save", "JQueryValidation", FormMethod.Post, new { id = "schedulerForm" }))
           { %>   
            <div class="values">  
                <%= Html.LabelFor(m => Model.text) %> : <%= Html.EditorFor(m => Model.text) %> 
                     <%= Html.ValidationMessageFor(m => Model.text) %> <br />
                <%= Html.LabelFor(m => Model.email) %> : <%= Html.EditorFor(m => Model.email)%> 
                     <%= Html.ValidationMessageFor(m => Model.email)%> <br />
     
                From
                <%= Html.TextBox("start_date", Model.start_date, new { @readonly = "readonly" })%>
                To
                <%= Html.TextBox("end_date", Model.end_date, new { @readonly = "readonly" })%>
                <%= Html.Hidden("id", Model.id)%> 
            </div>
            <div style="text-align:center">
                    <input type="submit" name="actionType"  value="Save" />
                    <input type="button" onclick="lightbox.close()/* helper-method*/" value="Close" />
                    <input type="submit" name="actionType" value="Delete" />
            </div>
        <% } %>
        </body>
    </html>

    You should pinpoint 2 things:

    • Required jquery files and plugins to include are:

      <script src="/Scripts/jquery-1.8.0.min.js" type="text/javascript"></script>
      <script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
      <script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
    • Code to activate the unobtrusive validation on the page is:

      <% 
          Html.EnableClientValidation();
          Html.EnableUnobtrusiveJavaScript(); 
      %>

Note, validation errors occur on the client and don't even hit submit.

Auto-generated model classes

In case you use a model class which is generated automatically (e.g. LINQ to SQL or Entity Framework), you can't apply the validator attributes directly to your classes. As the class is auto-generated, any changes made in it will be overwritten the next time you make changes in the Designer.
That's why, if you need to use validators with such a class you should create a meta data class and apply vaildators to it instead of applying to your actual class.

For example, you want to make the text property in the Event class required property. Then, you can create the partial and meta data classes as sown below:

//Event class auto-generated by LINQ to SQL
 
using System.ComponentModel.DataAnnotations; 
 
[MetadataType(typeof(EventMetadata))]
public partial class Event
{
}
 
public class EventMetadata
{
    [Required]
    public string text { get; set; }
 
}

Server validation

For security reasons we strongly encourage you to repeat validation on the server.

How to check correctness of properties?

In the 'Save' action you can operate with the object of the changed event to check the value of any property and compliance this value with the requirements (validation rules). Read more in chapter 'Managing CRUD operations'.

public ContentResult Save(Event changedEvent, FormCollection actionValues)
{
   var changedEvent=(Event)DHXEventsHelper.Bind(typeof(Event), actionValues);
   ...
}

How to rollback changes on the client?

If some property failed validation, you can use the AjaxSaveResponse UpdateField(string propertyName, object propertyValue) method to return the last correct value. To get details on this method and the possibility to update a singular data property, read chapter 'Postprocessing data properties on the server'.


comments powered by Disqus