define([
'dojo/_base/array',
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/mouse',
'dojo/on',
'dojo/query',
'dojo/topic',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'./_ResizeMixin',
'dijit/Tooltip',
'dijit/form/CheckBox',
'dgrid/Grid',
'dgrid/Editor',
'dgrid/extensions/DijitRegistry',
'dgrid/extensions/SingleQuery',
'dojo/i18n!../nls/laboratory',
'dojo/text!./templates/FeatureGrid.html',
// Widgets in template
'dijit/form/Form',
'dijit/form/RadioButton'
], function (arrayUtil, declare, lang, mouse, on, query, topic,
_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _ResizeMixin,
Tooltip, CheckBox, Grid, Editor, DijitRegistry, SingleQuery, i18n, template) {
function renderLabelCell (item, value, node) {
// Render the label cell, adding the doc link, tooltip icon, and config icon when appropriate
var cellHtml = '' + item.label + '';
// If configModule has not been defined there's no config widget to display
if (item.configLevel === 'grid' && item.configModule) {
cellHtml = cellHtml + ' ';
}
node.innerHTML = cellHtml;
}
var CustomGrid = declare([ Grid, SingleQuery, Editor, DijitRegistry ], {
gridTypeForm: null, // Passed from FeatureGrid when instantiated
showHeader: false,
columns: {
selected: {
label: '',
editor: CheckBox,
editorArgs: {
value: true
},
autoSave: true,
sortable: false
},
label: {
renderCell: renderLabelCell,
sortable: false
}
},
postCreate: function () {
this.inherited(arguments);
this.on('dgrid-datachange', lang.hitch(this, '_onDataChange'));
this.on('.featureLabel:click', lang.hitch(this, '_onFeatureLabelClick'));
this.on(on.selector('.field-label', mouse.enter), lang.hitch(this, '_showInfoTip'));
this.on(on.selector('.field-label', mouse.leave), lang.hitch(this, '_hideInfoTip'));
},
_onFeatureLabelClick: function (event) {
event.preventDefault();
// Since we are using Dijit checkbox editors, updating one's checked state will fire
// change handlers, which will route into _onDataChange below
var checkbox = this.cell(this.row(event), 'selected').element.widget;
if (!checkbox.get('disabled')) {
checkbox.set('checked', !checkbox.get('checked'));
}
},
_onDataChange: function (event) {
var store = this._store;
var selectedMid = event.cell.row.data.mid;
var otherRow;
// Let the ColumnConfigForm know that a feature is selected/deselected so it can show/hide its config
topic.publish('/feature/select', event.cell.row.data.mid, event.value);
// Enforce mutual exclusivity between CellSelection-Selection and Pagination-OnDemandGrid
switch (selectedMid) {
case 'dgrid/Selection':
if (event.value) {
otherRow = store.filter({ mid: 'dgrid/CellSelection', selected: true }).fetchSync()[0];
if (otherRow) {
otherRow.selected = false;
store.put(otherRow);
}
}
break;
case 'dgrid/CellSelection':
if (event.value) {
otherRow = store.filter({ mid: 'dgrid/Selection', selected: true }).fetchSync()[0];
if (otherRow) {
otherRow.selected = false;
store.put(otherRow);
}
}
break;
case 'dgrid/extensions/Pagination':
otherRow = store.filter({ mid: 'dgrid/OnDemandGrid' }).fetchSync()[0];
// If the user clicks to select Pagination...
if (event.value) {
// ...and OnDemandGrid was not selected, then we can assume gridType is array and we need to
// switch it to store-based (OnDemandGrid)
if (!otherRow.selected) {
this.gridTypeForm.set('value', { gridType: 'OnDemandGrid' });
}
else {
// ...but we actually want to deselect OnDemandGrid
otherRow.selected = false;
store.put(otherRow);
}
}
// If the user clicks to deselect Pagination then we want to select OnDemandGrid
else {
otherRow.selected = true;
store.put(otherRow);
}
break;
case 'dgrid/Selector':
// Fall through
case 'dgrid/Tree':
// Fall through
case 'dgrid/extensions/DnD':
// If the user selects a mixin or extension that requires a store,
// make sure a store-based config is active:
// 1. If OnDemandGrid or Pagination is already selected, a store is in use
// 2. Otherwise select OnDemandGrid
if (event.value) {
otherRow = store.filter({
mid: /(OnDemandGrid|Pagination)$/,
selected: true
}).fetchSync();
if (!otherRow.length) {
this.gridTypeForm.set('value', { gridType: 'OnDemandGrid' });
}
}
break;
}
},
insertRow: function (object) {
// This method ensures that the editor (checkbox) rendered for the Grid and OnDemandGrid rows
// is always disabled
var rowNode = this.inherited(arguments);
var cell = this.cell(rowNode, 'selected');
var mid = object.mid;
if (mid === 'dgrid/Grid' || mid === 'dgrid/OnDemandGrid') {
cell.element.widget.set('disabled', true);
}
return rowNode;
},
_showInfoTip: function (event) {
var row = this.row(event);
var info = row.data.info;
if (info) {
Tooltip.show(info, row.element);
}
},
_hideInfoTip: function (event) {
Tooltip.hide(this.row(event).element);
}
});
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _ResizeMixin ], {
className: 'featureGridContainer',
templateString: template,
i18n: i18n,
store: null,
featureType: null,
buildRendering: function () {
this.inherited(arguments);
this.grid = new CustomGrid({
className: 'featureGrid dgrid-autoheight',
_store: this.store,
collection: this.store.filter({ featureType: this.featureType }),
gridTypeForm: this.gridTypeForm
}, this.gridNode);
this._startupWidgets ? this._startupWidgets.push(this.grid) : this._startupWidgets = [this.grid];
},
postCreate: function () {
var self = this;
this.inherited(arguments);
this.own(
this.grid.on('.icon-gear:click', function (event) {
self.emit('configure-module', { mid: self.grid.row(event).data.mid });
})
);
},
_setGridModuleAttr: function (module) {
// 'module' should be either 'Grid' or 'OnDemandGrid'
var store = this.store;
var items;
if (module === 'OnDemandGrid') {
// Select OnDemandGrid, unless Pagination is already selected
items = store.filter({
mid: 'dgrid/extensions/Pagination',
selected: true
}).fetchSync();
if (!items.length) {
items = store.filter({ mid: 'dgrid/OnDemandGrid' }).fetchSync();
items[0].selected = true;
store.put(items[0]);
}
}
else {
// Deselect any modules that require a store
items = store.filter({
mid: /\/(OnDemandGrid|Selector|Tree|extensions\/(DnD|Pagination))$/,
selected: true
}).fetchSync();
arrayUtil.forEach(items, function (item) {
item.selected = false;
store.put(item);
});
}
},
_setFeatureTypeAttr: function (featureType){
this.grid.set('collection', this.store.filter({ featureType: featureType }));
}
});
});