Download Free Demos

Loading Data

The Scheduler .NET library provides the DHTMLX.Scheduler.Data.SchedulerAjaxData class. It takes and renders a collection of data objects in JSON format supported by the scheduler (the collection must implement the IEnumerable interface).

Code samples included in the documentation (as well as the samples included in the package), use LINQ to SQL to access a database.

For each LINQ to SQL designer file added to the solution, Visual Studio automatically generates a LINQ to SQL DataContext class. The DataContext class used in the code samples is called DHXSchedulerDataContext.

Tip! A sample DB structure you can find here.

Ajax Loading

By default, data is loaded to scheduler in the JSON format. And generally, to render a collection of objects you need to use the SchedulerAjaxData class.

In MVC you should apply the following technique:

public ContentResult Data()
{
    var events = (new DHXSchedulerDataContext()).Events;
    return (new SchedulerAjaxData(events));
}

where

  • 'Events' is the name of mapping data table
  • SchedulerAjaxData is implicitly converted to type ContentResult

In case you use WebForms, apply another technique:

public void ProcessRequest (HttpContext context) {
    context.Response.ContentType = "text/json";
    var events = (new DHXSchedulerDataContext()).Events;
    context.Response.Write(new SchedulerAjaxData(events).ToString());
}

where

  • The response content type should be specified explicitly
  • SchedulerAjaxData is explicitly converted to a string as well

Big datasets

By default, Scheduler loads all data at once. It may become problematic when you are using big event collections. In such situations, you can use dynamic loading and load data by parts, necessary to fill the viewable area of Scheduler.

To enable dynamic loading, you need to call the EnableDynamicLoading() method:

public ActionResult Index(){
  ...          
  scheduler.EnableDynamicLoading(SchedulerDataLoader.DynamicalLoadingMode.Day);
  ...
}

The enumeration SchedulerDataLoader.DynamicalLoadingMode has 3 possible values:

  • year
  • month
  • week
  • day

For example, if you set the 'month' mode, Scheduler will request data just for the current month and load remaining ones on demand.

Generated requests look like this:

Data?from=DATEHERE&to=DATEHERE

where DATEHERE is a valid date value of the yyyy-MM-dd format.

The received data can be parsed as follows:

var dateFrom = DateTime.ParseExact(this.Request.QueryString["from"], "yyyy-MM-dd", CultureInfo.InvariantCulture);
var dateTo = DateTime.ParseExact(this.Request.QueryString["to"], "yyyy-MM-dd", CultureInfo.InvariantCulture);

Static Loading

There are 2 ways to load data statically:

1 . Via method parse():

public ActionResult Index() {
   var sched = new DHXScheduler(this);
   var context = new DHXSchedulerDataContext();           
   sched.Data.Parse(context.Events);
   sched.EnableDataprocessor = true;
   return View(sched);
}

Added items are stored in the inner object of the DHXSchedulerDataStore class - scheduler.Data.Pull.

You can get a certain item by its index using:

var item = scheduler.Data.Pull[0];

Via helper DHTMLX:

<%= HttpHelper.DHTMLX().Scheduler(Model.scheduler, Model.data); %>

Data to Load

Data for loading can be presented by:

  • Model object
var context = new DHXSchedulerDataContext();
var data = new SchedulerAjaxData(context.Events);
return data.Render();

where 'Events' is the name of mapping data table

  • Data Collection
var items = new List<object>(){
       new { id = "1", text = "first event", start_date = "03.06.2011", end_date = "04.06.2011" },
       new { id = "2", text = "second event", start_date = "05.06.2011", end_date = "06.06.2011" },
       new { id = "3", text = "third event", start_date = "07.06.2011", end_date = "08.06.2011" }
};
 
var data = new SchedulerAjaxData(items);
return data.Render();

Data requirements

To be correctly processed, data for events must fit with some requirements.

Mandatory properties

Your data item must contain the following properties:

  • id - (int, string, etc.) the event id
  • start_date (DateTime or string) - the date when a task is scheduled to begin. The default format - "%m/%d/%Y %H:%i"
  • end_date (DateTime or string) - the date when a task is scheduled to be completed. The default format - "%m/%d/%Y %H:%i"
  • text (string ) - the text of a task

Format string

See available variations of the format string here.

Data format

In order to convert data into JSON, it shouldn't contain cross references.

Sample DB structure

A basic database for storing scheduler events can be created as in:

CREATE TABLE [Events](
  [id] int IDENTITY(1,1) NOT NULL,
  [text] nvarchar(256) NULL,
  [start_date] datetime NOT NULL,
  [end_date] datetime NOT NULL,
  PRIMARY KEY (id)
)

Custom names for data properties

Starting from version 3.0, you can use any names for the mandatory data properties. To use a custom name for a mandatory data property, use the [DHXJson(Alias = 'mandatory_name')] serialization attribute.

For example, you have the class with the following properties:

using DHTMLX.Scheduler;
public class DataItem
{
    public int EventId { get; set; }
    public string Description { get; set; }
    public DateTime start_date { get; set; }
    public DateTime end_date { get; set; }
}

To load data as it is without changing the names of members (i.e. EventId → id, Description → text), alter the code as in:

using DHTMLX.Scheduler;
public class DataItem
{
    [DHXJson(Alias = "id")]
    public int EventId { get; set; }
    [DHXJson(Alias = "text")]
    public string Description { get; set; }
 
    public DateTime start_date { get; set; }
    public DateTime end_date { get; set; }
}

Preventing data properties from sending to the client

Starting from version 3.0, you can exclude specific properties from ones that will be sent to the client. To do this, use the [DHXJson(Ignore = 'true')] serialization attribute as in:

// the 'RelatedEvents' property won't be sent to the client
public class DataItem
{
    public int id { get; set; }
    public string text { get; set; }
    public DateTime start_date { get; set; }
    public DateTime end_date { get; set; }
    [DHXJson(Ignore=true)]
    public List<CalendarEvent> RelatedEvents { get; set; }
}

Note, you can 'ignore' the mandatory properties: 'id', 'text', 'start_date', 'end_date'.

Custom render function

By default, the built-in serializer renders all public data properties. If you want to render a part of properties or your data objects don't fit the stated data requirements you need to specify a custom render function.

How can you set a custom render function for data?

In most code samples we use the following technique for loading data:

public ContentResult Data()
{
    var data = new SchedulerAjaxData((new DHXSchedulerDataContext()).Events);
    return data;
}

But in reality, the code above is just a short variant of the following one:

public ContentResult Data()
{
    var data = new SchedulerAjaxData((new DHXSchedulerDataContext()).Events);
    return Content( data.Render() );
}

The SchedulerAjaxData.Render() method has 2 overloads:

1 . public string Render()
2 . public string Render(Action <System.Text.StringBuilder, object> renderer)

  • renderer - a custom function that renders event objects.

The first overload is used during standard data loading. The second one allows specifying a custom render function (see a usage example below).

public ContentResult Data()
{
    var data = new SchedulerAjaxData((new DHXSchedulerDataContext()).Events);
    return Content( data.Render(eventRenderer) );
}
 
public void eventRenderer(System.Text.StringBuilder builder, object ev)
{
    var item = ev as Event;
    builder.Append(
        string.Format(":{0}, text:\"{1}\", start_date:\"{2:MM/dd/yyyy HH:mm}\", end_date:\"{3:MM/dd/yyyy HH:mm}\"",
        item.id,
        HttpUtility.JavaScriptStringEncode(item.text),
        item.start_date,
        item.end_date)
    );
}

While defining a custom function, please remember, that you need to escape characters that may break JSON (such as quotes, newlines, etc.). For this purpose you can use the HttpUtility.JavaScriptStringEncode utility (.Net 4.0+) as it's shown in the above code. If you use older version of .NET you should provide some custom solution.

Custom date format

If you set a custom value for the DHXScheduler.Config.xml_date configuration option in the Index() action, don't forget to set the same date format for the SchedulerAjaxData object.

public ActionResult Index(){
    ...          
    scheduler.Config.xml_date = "%d/%m/%Y %H:%i";
    ...
}
 
public ContentResult Data(){
    var events = (new DHXSchedulerDataContext()).Events;
    var data = new SchedulerAjaxData(events);
 
    data.DateFormat = "%d/%m/%Y %H:%i";
    return (data);
}

See available variations of the format string here.

Updating data from the server side

When you need to update data depending on the result of a server-side operation you should do 2 things:

1 .To set the flag sched.Data.DataProcessor. UpdateFieldsAfterSave to true (in the Index() action).

2 .To set new values for properties in the response through the UpdateField(string fieldName, object fieldValue) method of the AjaxSaveResponse class (in the Save() action).

For example, you want to show events in different colors: events before the current date in gray, others - in blue.

So, you set the flag:

public ActionResult Index() {
  var sched = new DHXScheduler(this);
   ...
  sched.Data.DataProcessor.UpdateFieldsAfterSave = true;
   ...
  return View(sched);
}

and assign the needed color:

public ContentResult Save(ColoredEvent changedEvent, FormCollection actionValues) {
  var action = new DataAction(actionValues);
  var color = "";
  if (changedEvent.start_date < DateTime.Now)
         color = "gray";
  else
         color = "blue";
  ...
 
  var result = new AjaxSaveResponse(action);
  result.UpdateField("textColor", color); // adds a new value
  return result;
}

Loading custom data

You can provide SchedulerAjaxData response with additional data, which can be later accessed on the client side. Additional items are added as named collections to the SchedulerAjaxData.ServerList dictionary:

var data = new SchedulerAjaxData();
data.Add(new List<object>{
    new { id = 1, text = "Event 1", start_date = new DateTime(2014, 12, 4, 10, 0, 0), end_date = new DateTime(2014, 12, 4, 12, 0, 0) },
    new { id = 2, text = "Event 2", start_date = new DateTime(2014, 12, 4, 13, 15, 0), end_date = new DateTime(2014, 12, 4, 14, 0, 0) },
    new { id = 3, text = "Event 3", start_date = new DateTime(2014, 12, 4, 13, 0, 0), end_date = new DateTime(2014, 12, 4, 13, 30, 0) },
});
 
data.ServerList.Add("dayoff", new List<object>{
    new { Date = new DateTime(2014, 11, 1)},
    new { Date = new DateTime(2014, 12, 14)}
});
 
return (ContentResult)data;

When such response is loaded to the page, the client-side component will fire the onOptionsLoad event, followed by the onXLE event.

The collection can be accessed on the client side using scheduler.serverList method (JavaScript):

var dayoff = scheduler.serverList("dayoff");

Note, for correct work, server list has to be initialized on the client side before loading. In order to do so, call scheduler.serverList("listName") before initialization of scheduler:

C#

var scheduler = new DHXScheduler();
scheduler.BeforeInit.Add("initServerLists();");

JS

function initServerLists(){
    scheduler.serverList("dayoff");
}

Loading sections of the Timeline and Units

Scheduler supports loading Timeline and Units options by default. It can be done by setting the ServerList property of Timeline or Units instance.

Initialization:

var scheduler = new DHXScheduler(this);
var timeline = new TimelineView("timeline", "section_id") { 
         RenderMode = TimelineView.RenderModes.Bar,
         X_Unit = TimelineView.XScaleUnits.Day,
         X_Size = 7,
         X_Date = "%d"
};
scheduler.Views.Add(timeline);
timeline.ServerList = "sections";

Loading options:

var data = new SchedulerAjaxData(events);
 
data.ServerList.Add("sections", new List<object>{
     new { key = "1", label = "Section 1" },
     new { key = "2", label = "Section 2" },
     new { key = "1", label = "Section 3" }
});

In this case no additional code is required. Timeline and Units views will fetch options from the lists with the names specified.

Handling errors

In case of network errors or invalid server response, the client side will fire the "onLoadError" event, which can be captured with a JavaScript code:

scheduler.attachEvent("onLoadError", function(resp){
    dhtmlx.message("The service is currently offline...");
});

See the event details here.

Was this article helpful?

Yes No