Jello framework

In this tutorial, you will learn how to develop custom controls and then bind data elements to them. A custom control is a JavaScript 'class' that implements the JelloControl Interface. The control code should be saved in a JavaScript file which has the same name as the control, as described in the Reference Guide.



1. Writing a simple custom Check-box control

The first example is for a simple check-box control that is based on three images (for 'true', 'false', and 'not-set') and an onClick event handler.

<project-folder>/war/demo/custom/checkbox.js :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function checkbox( containerId, settings, fieldDef ) {
  this.container =  $('#' + containerId);
  
  var that = this;
  
  function onClick(evt) {
     value = that.getValue();
     if(value === true)
       value = false;
     else 
       value = true;
     that.setValue( value );
    that.listener(evt, that, value );
  }
  
  this.render = function(onReady) {
    this.container.empty();
    this.container.append($("<img src='/demo/custom/none.png' style='height:20px;cursor: pointer;'/>"));
    this.container.find("img").click( onClick );
    onReady(this);
  }
  
  this.getValue = function() {
    var img = this.container.find("img");
    if(img.prop("src").indexOf("true") >0)
      return true;
    else if(img.prop("src").indexOf("false") >0)
      return false;
    else 
      return undefined;
  }
  
  this.setValue = function( value ) {
    var image = "false";
    if(value === undefined)
      image = "none";
    else if(value === true)
      image = "true";

    var src = "/demo/custom/" + image + ".png";
    this.container.find("img").prop("src", src);
  }
  
  this.change = function(listener) {
    this.listener = listener;
  }
  
  this.setDisabled = function(state) {
    if(state) {
      this.container.find("img").unbind( "click" );
      this.container.find("img").css("cursor", "");
    }
    else {
      this.container.find("img").click( onClick );
      this.container.find("img").css("cursor", "pointer");
    }
  }
}

1.1 Save above code in a file called checkbox.js under your project at <project-folder>/war/demo/custom/checkbox.js

1.2 Copy the three images true false not-set to this folder as well.

custom control file

1.3 Add @Control annotation to a Boolean element on your entity:

1
2
@Control(src="/demo/custom/checkbox")
public Boolean available;


2. Using a 3rd party Rating control

This example shows how to re-use a 3rd party control. In this case we simply wrap a JQuery rating control plug-in (copyright goes to JQuery Raty) with a wrapper that implements the JelloControl Interface.

Note how we asynchronously load the 3rd party resources (js and css files)

<project-folder>/war/demo/custom/ratingControl.js :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function ratingControl( containerId, settings, fieldDef ) {
  
  var css = "/demo/custom/raty/lib/jquery.raty.css";
  if ($('head link[href="' + css + '"]').length == 0) {
    $('head').append('<link rel="stylesheet" href="'+css+'" type="text/css" />');
  }
  
  this.container =  $('#' + containerId);
  this.settings = settings;
  this.disabled = false;
  var that = this;
  
  this.render = function(onReady) {
    require(['/demo/custom/raty/lib/jquery.raty.js'], function() {
      $.fn.raty.defaults.path = '/demo/custom/raty/demo/images';
			 
      that.settings.click = function(score, evt) {	 
        var currentScore = that.container.raty('score');
        if(currentScore != score && that.listener) {
          that.listener( evt, that, score);	
        }
      }	
      that.container.raty(that.settings);
			
      onReady(that);
    });	   
  }
  
  this.getValue = function() {
    return this.container.raty('score');
  }
  
  this.setValue = function( value ) {
    this.container.raty('score', value);
  }
  
  this.change = function(listener) {
    this.listener = listener;
  }
  
  this.setDisabled = function(state) {
    this.container.raty('readOnly', state);    
  }
}

2.1 Save above code in a file called ratingControl.js under you project at <project-folder>/war/demo/custom/ratingControl.js

2.2 Add @Control annotation to an Integer element on your entity

1
2
@Control(src="/demo/custom/ratingControl", settings= {"width:150px"})
public Integer rating;

custom control file


JelloTableView makes use of the width property but with this parameter, you can pass any custom property to be handled by the custom control. Check JQuery Raty documentation and try different settings.

1
2
3
4
5
6
@Control(src="/demo/custom/ratingControl", settings= {
   "width:180px", 
   "number:10", 
   "starOff : off.png", 
   "starOn  : on.png"
})
custom control file



Last updated December 30, 2015.