| DHTMLX Documentation

## Custom excell creation - simple way

### The purpose of excells

Excell stands for EXtended CELL and represents the cell editor in the grid.
The way the data will be stored|shown|edited in the grid is controlled by the column type.
Each column type refers to the related excell object:
ro => eXcell_ro
ed => eXcell_ed
...
While API allows to attach events and update settings to control some aspects of data rendering, the full control can be achieved only by customizing (or creating new one) excells.
In most cases it is enough to redefine some single method of excell to change the related behavior - the full list of excell methods is provided here.

### Creating read-only excells (formatters)

Read-они only excells are pretty simple. They are only used to describe the way how the incoming data needs to be rendered.

> function eXcell_ro(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> }
> this.edit = function(){} //read-only cell doesn't have edit method
> this.isDisabled = function(){ return true; } // the cell is read-only, that's why it is always in the disabled state
> this.setValue=function(val){
> this.setCValue(val); //actual data processing may be placed here, for now we just set value as it is
> }
> }
> eXcell_ro.prototype = new eXcell; // nest all other methods from base class

While this snippet contains about 10 lines of code, most of it may be copy-pasted. There are only two places that need to be adjusted according to your needs:

- Name of the column;
- Data processing formula.

For example, the following code will create an excell which will render the cell value as button with a label:

> function eXcell_button(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> }
> this.edit = function(){} //read-only cell doesn't have edit method
> this.isDisabled = function(){ return true; } // the cell is read-only, that's why it is always in the disabled state
> this.setValue=function(val){
> this.setCValue("<input type='button' value='"+val+"'>",val);
> }
> }
> eXcell_button.prototype = new eXcell; // nest all other methods from base class

As you can see, the above mentioned snippet differs from the previous one only in two places but now you can automatically convert the incoming data into a button just by defining the column type:

> grid.setColTypes("button,ro");

You can use any kind of HTML in the process of cell code generation, which allows you to place complex elements inside the grid and style them as necessary. The code mentioned below creates a complex excell type, which will open new window with details on pressing the button:

> function eXcell_details(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> }
> this.edit = function(){} //read-only cell doesn't have edit method
> this.isDisabled = function(){ return true; } // the cell is read-only, that's why it is always in the disabled state
> this.setValue=function(val){

> var row_id=this.cell.parentNode.idd; //get related row id

> this.setCValue(val+"<input type='button' onclick='window.open(\"details.php?for=\"+row_id)'>",val);
> }
> }
> eXcell_button.prototype = new eXcell; // nest all other methods from base class

### Creating editable excells

The editable excells use the same approach, but with a few additional methods.
Lets analyze the simplest case:

> function eXcell_button(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> eXcell_ed.call(this); //use methods of "ed" excell
> }
> this.setValue=function(val){
> this.setCValue("<input type='button' value='"+val+"'>",val);
> }
> this.getValue=function(){
> return this.cell.firstChild.value; // get button label
> }
> }
> eXcell_button.prototype = new eXcell; // nest all other methods from base class

As result - 3 new methods were added:

- getValue - returns the current cell value; it may be used by normal API, and it is necessary for normal edit operation;
- edit - ( not declared explictly, nested from ed excell ) called when the grid is switched to the edit state;
- detach - ( not declared explictly, nested from ed excell ) called when the grid is switched back to the normal state;

In spite of the fact that we have twice as much rows in this example as we had for read-only excell creation, basically we have only one row which needs to be customized. Both edit and detach events are fully reused from the already existing excell.
Editable button creation is pretty useless use case, so lets change it into something more usable:

> function eXcell_myprice(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> eXcell_ed.call(this); //use methods of "ed" excell
> }
> this.setValue=function(val){
> this.setCValue("<span>"+val+"</span><span> USD</span>",val);
> }
> this.getValue=function(){
> return this.cell.childNodes[0].innerHTML; // get value
> }
> }
> eXcell_button.prototype = new eXcell; // nest all other methods from base class

As you can see, only the text marked in bold was changed, and now, instead of a useless button we have the value formated with some postfix. This value can be correctly editable as Integer value.
In the most complex cases you may need to create an excell with custom editor. In such situation lets see the sample code of excell which can be used for hour selecting, instead of the simple text input. In addition to the default input, cell editor will have an additional time selector:

> function eXcell_mytime(cell){ //excell name is defined here
> if (cell){ //default pattern, just copy it
> this.cell = cell;
> this.grid = this.cell.parentNode.grid;
> }
> this.setValue=function(val){
> this.setCValue(val);
> }
> this.getValue=function(){
> return this.cell.innerHTML; // get value
> }
> this.edit=function(){
> this.val = this.getValue(); //save current value
> this.cell.innerHTML="<input type='text' style='width:50px;'><select style='width:50px;'><option value='AM'>AM<option value='PM'>PM</select>"; // editor's html
> this.cell.firstChild.value=parseInt(val); //set the first part of data
> if (val.indexOf("PM")!=-1) this.cell.childNodes[1].value="PM";
> this.cell.childNodes[0].onclick=function(e){ (e||event).cancelBubble=true; } //block onclick event
> this.cell.childNodes[1].onclick=function(e){ (e||event).cancelBubble=true; } //block onclick event
> }
> this.detach=function(){
> this.setValue(this.cell.childNodes[0].value+" "+this.cell.childNodes[1].value); //set the new value
> return this.val!=this.getValue(); // compare the new and the old values
> }
> }
> eXcell_button.prototype = new eXcell; // nest all other methods from base class

As you can see this sample contains some additional code, but there is still nothing really complex.
HTML code of editor is defined inside "edit" method, thus the editor is filled with current values.
Values from the editor are combined to get a new cell value inside "detach" method.
© DHTMLX, 2008