LIDOR SYSTEMS

Advanced User Interface Controls and Components

IntegralUI Web

Native Angular and AngularJS UI Components


TreeGrid / DropDown Editor



This sample demonstrates how to create custom editor using a template in AngularJS. This editor will appear as a dropdown checked list whenever a cell is clicked. In this case, the editor is applied to the cells in Genre column.

To create a custom editor is simple, at first create a HTML content which will determine the editor appearance and behavior. Then apply a refrence of this template to the column's editorTemplate field. Next, set that editor will appear in a dropdown window, below the editing cell.

In our example, editor consist of a checked list and two buttons. In the list at first check items are shown, followed by sorted unchecked items. This improves the selection process. Whenever the Ok button is clicked, the cell value is updated. Each cell can contain multiple values, based on which items are checked. This is all customizable.

When column has a custom editor set, whenever a cell is hovered, an editor mark will appear on the right side. Currenty there are two types of custom editors: 'incell' and 'dropdown'. The appearance of this mark depends on editor type. In case of a dropdown editor, it is a an icon of arrow pointing downwards.

Note   You can also check out the InCell Editor.

In this sample, the following column fields, methods and events are used:

  • editorType - determines the type of the editor, in this case is 'dropdown'
  • editorTemplate - holds a reference to a template by which editor is created
  • closeEditor - closes the currently opened editor
  • beforeEdit - occurs before editing process starts
  • afterEdit - occurs after editing process ends

<!DOCTYPE html>

<html>

<head>

<link rel="stylesheet" href="css/integralui.css" />

<link rel="stylesheet" href="css/integralui.checkbox.css" />

<link rel="stylesheet" href="css/integralui.treegrid.css" />

<link rel="stylesheet" href="css/themes/theme-flat-blue.css" />

<script type="text/javascript" src="external/angular.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.lists.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.checkbox.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.treegrid.min.js"></script>

</head>

<body>

<div ng-app="appModule" ng-controller="appCtrl">

<script type="text/ng-template" id="dropdown-editor.html">

<div class="cell-editor" ng-model="editCell">

<ul class="checked-list">

<li ng-repeat="item in genres">

<iui-checkbox class="check-item" checked="item.checked">{{item.text}}</iui-checkbox>

</li>

</ul>

<div class="editor-panel">

<button class="inline-button" ng-click="onOk(editCell)">Ok</button>

<button class="inline-button" ng-click="onCancel(editCell)">Cancel</button>

</div>

</div>

</script>

<iui-treegrid name="{{gridName}}" columns="columns" rows="rows" show-footer="false" before-edit="onBeforeEdit(e)" after-edit="onAfterEdit(e)" tabindex="0"></iui-treegrid>

</div>

</body>

</html>

angular

.module("appModule", ["integralui"])

.controller("appCtrl", ["$scope", "IntegralUITreeGridService", "$timeout", function($scope, $gridService, $timeout){

$scope.gridName = "gridSample";

$scope.editCell = null;

 

$scope.columns = [

{ id: 1, headerText: "Title", width: 200},

{

id: 2,

editorType: 'checkbox',

editorSettings: {

style: {

general: 'checkbox',

box: {

general: 'checkbox-box',

checked: 'checkbox-checked',

indeterminate: 'checkbox-indeterminate',

unchecked: 'checkbox-unchecked'

}

},

threeState: true

},

contentAlignment: 'center',

width: 30,

fixedWidth: true

},

{ id: 3, headerText: "Year", headerAlignment: "center", contentAlignment: "center", width: 70 },

{

id: 4,

headerText: "Genre",

headerAlignment: "center",

contentAlignment: "center",

editorType: 'dropdown',

editorTemplate: "'dropdown-editor.html'",

width: 270

},

{ id: 5, headerText: "Ratings", headerAlignment: "center", contentAlignment: "center", width: 70 },

{ id: 6, headerText: "Released", headerAlignment: "center", contentAlignment: "center", width: 120 }

];

 

$scope.genres = [

{ text: "Action", checked: false },

{ text: "Adventure", checked: false },

{ text: "Animation", checked: false },

{ text: "Biography", checked: false },

{ text: "Comedy", checked: false },

{ text: "Crime", checked: false },

{ text: "Drama", checked: false },

{ text: "Fantasy", checked: false },

{ text: "Horror", checked: false },

{ text: "Mystery", checked: false },

{ text: "Sci-Fi", checked: false },

{ text: "Thriller", checked: false },

{ text: "Western", checked: false }

];

 

$scope.rows = [

{

id: 1,

text: "Inception",

cells: [{ cid: 1, text: "Inception" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2010" }, { cid: 4, text: "Action, Mystery, Sci-Fi" }, { cid: 5, text: "8.8" }, { cid: 6, text: "16 Jul 2010" } ]

},

{

id: 2,

text: "Gravity",

cells: [{ cid: 1, text: "Gravity" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Sci-Fi, Thriller" }, { cid: 5, text: "7.9" }, { cid: 6, text: "04 Oct 2013" } ]

},

{

id: 3,

text: "Django Unchained",

cells: [{ cid: 1, text: "Django Unchained" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2012" }, { cid: 4, text: "Western" }, { cid: 5, text: "8.5" }, { cid: 6, text: "25 Dec 2012" } ]

},

{

id: 4,

text: "Toy Story 3",

cells: [{ cid: 1, text: "Toy Story 3" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2010" }, { cid: 4, text: "Animation, Adventure, Comedy" }, { cid: 5, text: "8.4" }, { cid: 6, text: "18 Jun 2010" } ]

},

{

id: 5,

text: "The Wolf of Wall Street",

cells: [{ cid: 1, text: "The Wolf of Wall Street" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2013" }, { cid: 4, text: "Biography, Comedy, Crime" }, { cid: 5, text: "8.2" }, { cid: 6, text: "25 Dec 2013" } ]

},

{

id: 6,

text: "The Town",

cells: [{ cid: 1, text: "The Town" }, { cid: 2 }, { cid: 3, text: "2010" }, { cid: 4, text: "Crime, Drama, Thriller" }, { cid: 5, text: "7.6" }, { cid: 6, text: "17 Sep 2010" } ]

},

{

id: 7,

text: "Nightcrawler",

cells: [{ cid: 1, text: "Nightcrawler" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2014" }, { cid: 4, text: "Crime, Thriller" }, { cid: 5, text: "7.9" }, { cid: 6, text: "31 Oct 2014" } ]

},

{

id: 8,

text: "Locke",

cells: [{ cid: 1, text: "Locke" }, { cid: 2 }, { cid: 3, text: "2014" }, { cid: 4, text: "Drama" }, { cid: 5, text: "7.1" }, { cid: 6, text: "29 May 2014" } ]

},

{

id: 9,

text: "Prometheus",

cells: [{ cid: 1, text: "Prometheus" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2012" }, { cid: 4, text: "Adventure, Mystery, Sci-Fi " }, { cid: 5, text: "7.0" }, { cid: 6, text: "08 Jun 2012" } ]

},

{

id: 10,

text: "The Social Network",

cells: [{ cid: 1, text: "The Social Network" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2010" }, { cid: 4, text: "Biography, Drama" }, { cid: 5, text: "7.8" }, { cid: 6, text: "01 Oct 2010" } ]

},

{

id: 11,

text: "The Conjuring",

cells: [{ cid: 1, text: "The Conjuring" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Horror" }, { cid: 5, text: "7.5" }, { cid: 6, text: "19 Jul 2013" } ]

},

{

id: 12,

text: "Blue Jasmine",

cells: [{ cid: 1, text: "Blue Jasmine" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2013" }, { cid: 4, text: "Drama" }, { cid: 5, text: "7.3" }, { cid: 6, text: "23 Aug 2013" } ]

},

{

id: 13,

text: "Black Swan",

cells: [{ cid: 1, text: "Black Swan" }, { cid: 2 }, { cid: 3, text: "2010" }, { cid: 4, text: "Drama, Mystery, Thriller" }, { cid: 5, text: "8.0" }, { cid: 6, text: "17 Dec 2010" } ]

},

{

id: 14,

text: "Prisoners",

cells: [{ cid: 1, text: "Prisoners" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Crime, Drama, Mystery" }, { cid: 5, text: "8.1" }, { cid: 6, text: "20 Sep 2013" } ]

},

{

id: 15,

text: "The Avengers",

cells: [{ cid: 1, text: "The Avengers" }, { cid: 2 }, { cid: 3, text: "2012" }, { cid: 4, text: "Action, Adventure, Sci-Fi" }, { cid: 5, text: "8.2" }, { cid: 6, text: "04 May 2012" } ]

},

{

id: 16,

text: "Snowpiercer",

cells: [{ cid: 1, text: "Snowpiercer" }, { cid: 2 }, { cid: 3, text: "2014" }, { cid: 4, text: "Action, Mystery, Sci-Fi" }, { cid: 5, text: "7.0" }, { cid: 6, text: "11 Jul 2014" } ]

},

{

id: 17,

text: "The Dark Knight Rises",

cells: [{ cid: 1, text: "The Dark Knight Rises" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2012" }, { cid: 4, text: "Action, Thriller" }, { cid: 5, text: "8.5" }, { cid: 6, text: "20 Jul 2012" } ]

},

{

id: 18,

text: "American Hustle",

cells: [{ cid: 1, text: "American Hustle" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Crime, Drama" }, { cid: 5, text: "7.3" }, { cid: 6, text: "20 Dec 2013" } ]

},

{

id: 19,

text: "Dawn of the Planet of the Apes",

cells: [{ cid: 1, text: "Dawn of the Planet of the Apes" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2014" }, { cid: 4, text: "Action, Drama, Sci-Fi" }, { cid: 5, text: "7.7" }, { cid: 6, text: "11 Jul 2014" } ]

},

{

id: 20,

text: "Frozen",

cells: [{ cid: 1, text: "Frozen" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Animation, Adventure, Comedy" }, { cid: 5, text: "7.7" }, { cid: 6, text: "27 Nov 2013" } ]

},

{

id: 21,

text: "Edge of Tomorrow",

cells: [{ cid: 1, text: "Edge of Tomorrow" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2014" }, { cid: 4, text: "Action, Adventure, Mystery" }, { cid: 5, text: "7.9" }, { cid: 6, text: "06 Jun 2014" } ]

},

{

id: 22,

text: "Interstellar",

cells: [{ cid: 1, text: "Interstellar" }, { cid: 2 }, { cid: 3, text: "2014" }, { cid: 4, text: "Adventure, Drama, Sci-Fi" }, { cid: 5, text: "8.7" }, { cid: 6, text: "07 Nov 2014" } ]

},

{

id: 23,

text: "Rush",

cells: [{ cid: 1, text: "Rush" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Action, Biography, Drama" }, { cid: 5, text: "8.2" }, { cid: 6, text: "27 Sep 2013" } ]

},

{

id: 24,

text: "Shutter Island",

cells: [{ cid: 1, text: "Shutter Island" }, { cid: 2, value: 'checked' }, { cid: 3, text: "2010" }, { cid: 4, text: "Mystery, Thriller " }, { cid: 5, text: "8.1" }, { cid: 6, text: "19 Feb 2010" } ]

},

{

id: 25,

text: "This Is the End",

cells: [{ cid: 1, text: "This Is the End" }, { cid: 2 }, { cid: 3, text: "2013" }, { cid: 4, text: "Comedy, Fantasy" }, { cid: 5, text: "6.7" }, { cid: 6, text: "12 Jun 2013" } ]

}

];

 

var findGenre = function(text){

var found = null;

for (var i = 0; i < $scope.genres.length; i++){

if ($scope.genres[i].text == text){

found = $scope.genres[i];

break;

}

}

 

return found;

}

 

var initCellValues = function(){

for (var i = 0; i < $scope.rows.length; i++){

var cell = $scope.rows[i].cells[3];

cell.value = [];

 

var selGenres = cell.text.split(', ');

for (var j = 0; j < selGenres.length; j++){

var foundItem = findGenre(selGenres[j]);

if (foundItem)

cell.value.push(foundItem);

}

}

}

 

initCellValues();

 

var resetGenres = function(){

for (var i = 0; i < $scope.genres.length; i++)

$scope.genres[i].checked = false;

}

 

var sortComparer = function(firstItem, secondItem){

var x = firstItem.text != undefined ? firstItem.text : null;

var y = secondItem.text != undefined ? secondItem.text : null;

 

if (x < y)

return -1;

else if (x > y)

return 1;

 

return 0;

}

 

var showCheckedFirst = function(){

var checkedList = [];

var uncheckedList = [];

for (var i = 0; i < $scope.genres.length; i++){

if ($scope.genres[i].checked)

checkedList.push($scope.genres[i]);

else

uncheckedList.push($scope.genres[i]);

}

 

checkedList.sort(sortComparer);

uncheckedList.sort(sortComparer);

 

$scope.genres.length = 0;

for (var i = 0; i < checkedList.length; i++)

$scope.genres.push(checkedList[i]);

for (var i = 0; i < uncheckedList.length; i++)

$scope.genres.push(uncheckedList[i]);

}

 

$scope.onBeforeEdit = function(e){

if (e.cell){

$scope.editCell = e.cell;

 

var cellItems = e.cell.value;

if (cellItems){

resetGenres();

 

for (var i = 0; i < cellItems.length; i++)

cellItems[i].checked = true;

}

 

showCheckedFirst();

}

}

 

$scope.onAfterEdit = function(e){

$scope.editCell = null;

}

 

$scope.onOk = function(cell){

if (cell){

var list = [];

for (var i = 0; i < $scope.genres.length; i++){

if ($scope.genres[i].checked)

list.push($scope.genres[i]);

}

 

cell.text = '';

for (var i = 0; i < list.length; i++)

cell.text += list[i].text + ", ";

 

if (cell.text != '')

cell.text = cell.text.substring(0, cell.text.length - 2);

 

cell.value = list;

}

 

$gridService.closeEditor($scope.gridName, cell);

}

 

$scope.onCancel = function(cell){

resetGenres();

$gridService.closeEditor($scope.gridName, cell);

}

});

.iui-treegrid-column-header-cell, .iui-treegrid-column-footer-cell

{

padding: 2px 2px;

}

.iui-treegrid-row-cell-content

{

padding: 2px 2px;

}

.iui-treegrid-row-hovered

{

background-color: #efefef;

}

.iui-treegrid-row-cell-hovered

{

color: #000080;

}

.iui-treegrid-row-selected

{

background-color: #dedede;

color: #008000;

}

.checkbox

{

width: 16px;

margin: auto;

}

.checkbox-box

{

border: 0;

display: inline-block;

width: 16px;

height: 16px;

}

.checkbox-checked

{

background-image: url("../../../resources/checkbox/checkbox-checked.png");

}

.checkbox-indeterminate

{

background-image: url("../../../resources/checkbox/checkbox-indeterminate.png");

}

.checkbox-unchecked

{

background-image: url("../../../resources/checkbox/checkbox-unchecked.png");

}

 

/* Editor Template Inline */

.cell-editor

{

background: white;

font-size: 0.75em;

}

.checked-list

{

margin: 0;

overflow: auto;

padding: 1px;

margin: 0;

height: 135px;

}

.checked-list li

{

padding: 0;

margin: 0;

list-style-type: none;

border: thin solid transparent;

}

.checked-list li:hover

{

background: #197EC5;

color: white;

}

.check-item

{

display: inline-block;

margin: 2px;

vertical-align: middle;

}

.iui-checkbox

{

padding: 5px;

}

.iui-checkbox:hover

{

color: white;

}

.editor-panel

{

background: #e5e5e5;

border-top: thin solid gray;

margin: 0;

padding: 5px;

text-align: center;

}

.inline-button

{

background: #2455b0;

border: thin solid transparent;

color: white;

margin: 0 5px;

width: 100px;

height: 25px;

}

.inline-button:hover

{

background-color: #153268;

border: thin solid #0F244A;

}