DHTMLX Docs & Samples Explorer

Global Data Storage

The article tells you about dhtmlXDataStore, the component which is basically designed to perform a function of data store. But at the same time, it's a full-fledged dhtmlx component with its own API.

Classic use-case

  • Storing data that's used by several components on a page. You can use more than one DataStore. They can be linked or not.

Description

  • Has no graphical representation and used just to store data.
    We can compare dhtmlXDataStore with database table or view. UI components can be filled from it. You also can establish relationships between different DataStores like you can do between tables in database.
  • Any data manipulation is made directly in dhtmlXDataStore object (not in a component that represents this data): sort, filter, delete, add, update.
    For example, you need to delete record - you do not need to think if it should be deleted from grid or whatever other place - just delete it from DataStore and it will be removed from other components as well without your direct intervention.
  • Controls relations between components.
    If you link grid and form to the same DataStore, details of record selected in grid will be shown in the form automatically. No additional coding is necessary.

Included files

To use the functionality of dhtmlXDataStore, you need to include one file:

<script type="text/javascript" src="../codebase/datastore.js"></script>

Object Constructor

You have 2 ways to initialize and fill the DataStore:

  • Create and then fill with script:

    var myDataStore = new dhtmlXDataStore();
    myDataStore.parse([
    		{id:"1", name:"Accounts Department"},
    		{id:"2", name:"Customer Service"},
    		{id:"3", name:"Developing Department"}
    ]);
  • Specify the path to a data file in the constructor (fill from server):

    var data = new dhtmlXDataStore({
    		url:"data/data.json",
    		datatype:"json"
    });

Supported data formats

Data scheme

Data scheme allows to set a default scheme for data records of dhtmlXDataStore. So, in cases when you add an empty record to dhtmlXDataStore (data.add({})), the record will be populated with the values set by the scheme.

data.scheme({
	name:"Unknown",
        gender:"male",
        age:25,
        department: "Unknown"
});
data.add({});//will add { name:"Unknown", gender:"male", age:25, department:"Unknown"} record

Also, there are 2 special keys you can use in a scheme:

  • $init - called during initial object creation

    Let's assume, you want to populate combo with data from some column of db (e.g. column 'name' with the names of departments). To make combo recognize the names of departments as options, combo should get data as sets of 'text' and 'value' parameters. In this situation the $init key comes in useful:

    myDataStore.data.scheme({
      $init:function(obj){
          obj.value = obj.name;// 'name' is the name of the column from the db
          obj.text = obj.name;
      }
    }); 
  • $update - called each time after data changing

    myDataStore.data.scheme({
      $update:function(){ 
            obj.text = obj.name + " " + obj.number;
      }
    });

Binding components to dhtmlXDataStore

Components, bound to dhtmlXDataStore will keep their data synchronized with the data stored in dhtmlXDataStore. They will also be bound with each other (e.g. grid and form).

Methods used for data binding

  • sync() - copies all the data from store (used for multirecords components like grid).
  • bind() - copies just a single record related to some item (used for single record component like form).
  • and dataFeed() - helps to reload data from the server (instead of the master component).

Binding cases

  • binding components to dhtmlXDataStore:

    var list1 = new dhtmlXDataStore({ url:"../data/data1.json", datatype:"json" });
    grid.sync(list1);
  • binding 2 DataStores:

    var list1 = new dhtmlXDataStore({ url:"../data/data1.json", datatype:"json" });
    var list2 = new dhtmlXDataStore({ url:"../data/data2.json", datatype:"json" });
     
    list2.bind(list1, function(data, filter){
    		return data.value == filter.value;
    });
  • binding DataStore to server-side:

    var list1 = new dhtmlXDataStore({ url:"../data/data1.json", datatype:"json" });
    var list2 = new dhtmlXDataStore({ dataFeed:"../data/json.php", datatype:"json" });
     
    list2.bind(list1, function(data, filter){
    		filter.Package = "Filter by "+data.Package;
    });
    grid1.sync(list1);
    grid2.sync(list2);

See also Data Binding in Code Samples.

API reference

Example

You probably find it hard to think of situations where this “invisible store” would be useful.
So, let's consider as example some company. It has some number of departments. Each department contains its employees.


Full code of the example

The goal

Let's assume we want to present on a page the following:

  • All company's staff.
  • Some element allowing to filter staff by a department.
  • Details of the selected employee.

Chosen Components

Clearly, we need several components to achieve this.
The final set of components can very, but we've chosen the following:

  • dhtmlxCombo - allows to filter employees by a department.
  • dhtmlxGrid - contains department's employees.
  • dhtmlxForm - contains employee's details.
  • dhtmlxlayout - allows to group elements on a page.

Implementation

This stage we divided into 4 steps:

  1. Components initialization (without data loading, just creating instances and their configuration):

    var layout = new dhtmlXLayoutObject(...);
    var myGrid = layout.cells("c").attachGrid();
    var myForm = layout.cells("b").attachForm();
    var myCombo = new dhtmlXCombo(...);
  2. Creating 2 dhtmlXDataStore objects (one with deparments' names and the second with employees details):

    var employees = new dhtmlXDataStore(); 
    var departments = new dhtmlXDataStore();
  3. Loading data to components ( through sync() method, so-called synchronization dhtmlxDataStore with the representative component):

    myCombo.sync(departments);// to load data to the combo
    myGrid.sync(employees); // to load data to the grid
  4. Linking represantative components (through bind() command):

    myGrid.bind(myCombo, function(data, filter){   // to link the grid with the combo 
    		return myGrid.cells(data, 2).getValue() == filter.text;
    	});
    myForm.bind(myGrid);// to link the form with the grid


As you can see we needed just 4 commands to load data and link the components (steps 3 and 4), that proves the stated above: dhtmlXDataStore is realy a handy way to store data while dealing with several components.