mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Improvised Select2Cell, and SwitchCell.
Removed the use of separate editor for both of these cell types. There were two instance of select2 were getting created in the Select2Cell, one in the Select2Cell itself, and another in Select2CellEditor. And, loosing the focus mysteriously, and making the scrollbar in the property dialog non-responsive. Also, modified the NodeAjaxOptionsCell to use the above logic, and removed its own version of render function to make it consitent across the system. This patch [changes sent by Murtuza] also includes improvisation in the DeleteCell, and ObjectCell, which will honour now 'canRemoveRow', and ''canEditRow' respective properties of Column.
This commit is contained in:
@@ -314,10 +314,16 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
|
||||
allowClear: true,
|
||||
placeholder: 'Select from the list',
|
||||
width: 'style'
|
||||
}
|
||||
},
|
||||
opt: {
|
||||
label: null,
|
||||
value: null,
|
||||
image: null,
|
||||
selected: false
|
||||
}
|
||||
}),
|
||||
template: _.template(
|
||||
'<option <% if (image) { %> data-image=<%= image %> <% } %> value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- text %></option>'
|
||||
'<option <% if (image) { %> data-image=<%= image %> <% } %> value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- label %></option>'
|
||||
),
|
||||
initialize: function () {
|
||||
Backgrid.Extension.Select2Cell.prototype.initialize.apply(this, arguments);
|
||||
@@ -390,81 +396,6 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
|
||||
}
|
||||
column.set('options_cached', true);
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
/*
|
||||
* Let SelectCell render it, we will do our magic on the
|
||||
* select control in it.
|
||||
*/
|
||||
|
||||
var col = _.defaults(this.column.toJSON(), this.defaults),
|
||||
model = this.model, column = this.column,
|
||||
editable = Backgrid.callByNeed(col.editable, column, model),
|
||||
optionValues = _.clone(this.optionValues ||
|
||||
_.isFunction(this.column.get('options')) ?
|
||||
(this.column.get('options'))(this) :
|
||||
this.column.get('options')),
|
||||
select2_opts = _.defaults({}, col.select2, this.defaults.select2),
|
||||
evalF = function(f, col, m) {
|
||||
return (_.isFunction(f) ? !!f.apply(col, [m]) : !!f);
|
||||
};
|
||||
|
||||
this.$el.empty();
|
||||
|
||||
if (!_.isArray(optionValues)) throw new TypeError("optionValues must be an array");
|
||||
|
||||
/*
|
||||
* Add empty option as Select2 requires any empty '<option><option>' for
|
||||
* some of its functionality to work.
|
||||
*/
|
||||
optionValues.unshift({'label':null, 'value':null, 'image':null});
|
||||
|
||||
var optionText = null,
|
||||
optionValue = null,
|
||||
model = this.model,
|
||||
selectedValues = model.get(this.column.get("name"));
|
||||
|
||||
delete this.$select;
|
||||
|
||||
this.$select = $("<select>", {tabIndex: -1}).appendTo(this.$el);
|
||||
|
||||
for (var i = 0; i < optionValues.length; i++) {
|
||||
var op = optionValues[i];
|
||||
|
||||
optionText = op['label'];
|
||||
optionValue = op['value'];
|
||||
optionImage = op['image'];
|
||||
|
||||
this.$select.append(
|
||||
this.template({
|
||||
text: optionText,
|
||||
value: optionValue,
|
||||
image: optionImage,
|
||||
selected: (selectedValues == optionValue) ||
|
||||
(_.indexOf(selectedValues, optionValue) > -1)
|
||||
}));
|
||||
}
|
||||
|
||||
// Initialize select2 control.
|
||||
this.$select.select2(
|
||||
_.defaults(
|
||||
{'disabled': !editable}, col.select2, this.defaults.select2
|
||||
));
|
||||
|
||||
/*
|
||||
* If select2 options do not have any disabled property on this cell
|
||||
* and schema has disabled property then we need to apply it
|
||||
*/
|
||||
if(!_.has(select2_opts, 'disabled') && (col && col.disabled)) {
|
||||
_.extend(select2_opts, {
|
||||
disabled: evalF(col.disabled, col, this.model)
|
||||
});
|
||||
}
|
||||
this.$el.find("select").select2(select2_opts);
|
||||
|
||||
this.delegateEvents();
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -191,19 +191,33 @@
|
||||
},
|
||||
enterEditMode: function () {
|
||||
// Notify that we are about to enter in edit mode for current cell.
|
||||
this.model.trigger("enteringEditMode", [this]);
|
||||
// We will check if this row is editable first
|
||||
var canEditRow = (!_.isUndefined(this.column.get('canEditRow')) &&
|
||||
_.isFunction(this.column.get('canEditRow'))) ?
|
||||
Backgrid.callByNeed(this.column.get('canEditRow'),
|
||||
this.column, this.model) : true;
|
||||
if (canEditRow) {
|
||||
// Notify that we are about to enter in edit mode for current cell.
|
||||
this.model.trigger("enteringEditMode", [this]);
|
||||
|
||||
Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
|
||||
/* Make sure - we listen to the click event */
|
||||
this.delegateEvents();
|
||||
var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
|
||||
if (editable) {
|
||||
this.$el.html(
|
||||
"<i class='fa fa-pencil-square subnode-edit-in-process'></i>"
|
||||
);
|
||||
this.model.trigger(
|
||||
"pg-sub-node:opened", this.model, this
|
||||
);
|
||||
Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
|
||||
/* Make sure - we listen to the click event */
|
||||
this.delegateEvents();
|
||||
var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
|
||||
|
||||
if (editable) {
|
||||
this.$el.html(
|
||||
"<i class='fa fa-pencil-square subnode-edit-in-process'></i>"
|
||||
);
|
||||
this.model.trigger(
|
||||
"pg-sub-node:opened", this.model, this
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Alertify.alert("This object is not editable by user",
|
||||
function(){
|
||||
return true;
|
||||
});
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
@@ -247,7 +261,13 @@
|
||||
deleteRow: function (e) {
|
||||
e.preventDefault();
|
||||
that = this;
|
||||
Alertify.confirm(
|
||||
// We will check if row is deletable or not
|
||||
var canDeleteRow = (!_.isUndefined(this.column.get('canDeleteRow')) &&
|
||||
_.isFunction(this.column.get('canDeleteRow')) ) ?
|
||||
Backgrid.callByNeed(this.column.get('canDeleteRow'),
|
||||
this.column, this.model) : true;
|
||||
if (canDeleteRow) {
|
||||
Alertify.confirm(
|
||||
'Delete Row',
|
||||
'Are you sure you wish to delete this row?',
|
||||
function(evt) {
|
||||
@@ -257,6 +277,13 @@
|
||||
return true;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
Alertify.alert("This object can not be deleted",
|
||||
function(){
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
initialize: function () {
|
||||
Backgrid.Cell.prototype.initialize.apply(this, arguments);
|
||||
@@ -293,10 +320,26 @@
|
||||
size: 'mini'
|
||||
}, $.fn.bootstrapSwitch.defaults)
|
||||
},
|
||||
|
||||
className: 'switch-cell',
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.BooleanCell.prototype.initialize.apply(this, arguments);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
},
|
||||
|
||||
enterEditMode: function() {
|
||||
this.$el.addClass('editor');
|
||||
},
|
||||
|
||||
exitEditMode: function() {
|
||||
this.$el.removeClass('editor');
|
||||
},
|
||||
|
||||
events: {
|
||||
'switchChange.bootstrapSwitch': 'onChange'
|
||||
},
|
||||
|
||||
onChange: function () {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
@@ -305,6 +348,7 @@
|
||||
// on bootstrap change we also need to change model's value
|
||||
model.set(column.get("name"), val);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var col = _.defaults(this.column.toJSON(), this.defaults),
|
||||
attributes = this.model.toJSON(),
|
||||
@@ -317,7 +361,10 @@
|
||||
),
|
||||
editable = Backgrid.callByNeed(col.editable, column, model);
|
||||
|
||||
this.undelegateEvents();
|
||||
|
||||
this.$el.empty();
|
||||
|
||||
this.$el.append(
|
||||
$("<input>", {
|
||||
tabIndex: -1,
|
||||
@@ -338,134 +385,37 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
Select2CellEditor the cell editor renders a Select2 input
|
||||
box as its editor.
|
||||
*/
|
||||
var Select2CellEditor = Backgrid.Select2CellEditor =
|
||||
Backgrid.SelectCellEditor.extend({
|
||||
/** @property */
|
||||
events: {
|
||||
"change": "onSave"
|
||||
},
|
||||
|
||||
/** @property */
|
||||
setSelect2Options: function (options) {
|
||||
this.select2Options = _.extend(options || {});
|
||||
},
|
||||
|
||||
/** @property */
|
||||
// This option will prevent Select2 list to pop up
|
||||
// when user press tab on select2
|
||||
select2Options: {
|
||||
openOnEnter: false
|
||||
},
|
||||
|
||||
/** @property {function(Object, ?Object=): string} template */
|
||||
template: _.template([
|
||||
'<option value="<%- value %>" ',
|
||||
'<%= selected ? \'selected="selected"\' : "" %>>',
|
||||
'<%- text %></option>'].join(''),
|
||||
null,{
|
||||
variable: null
|
||||
}),
|
||||
|
||||
initialize: function () {
|
||||
Backgrid.SelectCellEditor.prototype.initialize.apply(this, arguments);
|
||||
this.close = _.bind(this.close, this);
|
||||
},
|
||||
/**
|
||||
Renders a `select2` select box instead of the default `<select>` HTML
|
||||
element using the supplied options from #select2Options.
|
||||
*/
|
||||
render: function () {
|
||||
var self =this,
|
||||
col = _.defaults(this.column.toJSON(), this.defaults),
|
||||
model = this.model, column = this.column,
|
||||
editable = Backgrid.callByNeed(col.editable, column, model),
|
||||
optionValues = Backgrid.callByNeed(col.options, column, this);
|
||||
|
||||
this.$el.empty();
|
||||
|
||||
if (!_.isArray(optionValues))
|
||||
throw new TypeError("optionValues must be an array");
|
||||
|
||||
/*
|
||||
* Add empty option as Select2 requires any empty '<option><option>' for
|
||||
* some of its functionality to work.
|
||||
*/
|
||||
|
||||
var optionText = null,
|
||||
optionValue = null,
|
||||
model = this.model,
|
||||
selectedValues = model.get(this.column.get("name"));
|
||||
|
||||
for (var i = 0; i < optionValues.length; i++) {
|
||||
var optionValue = optionValues[i];
|
||||
|
||||
if (_.isArray(optionValue) || _.isObject(optionValue)) {
|
||||
optionText = optionValue[0] || optionValue.label;
|
||||
optionValue = optionValue[1] || optionValue.value;
|
||||
|
||||
this.$el.append(
|
||||
this.template({
|
||||
text: optionText,
|
||||
value: optionValue,
|
||||
selected: (selectedValues == optionValue) ||
|
||||
(_.indexOf(selectedValues, optionValue) > -1)
|
||||
}));
|
||||
} else {
|
||||
throw new TypeError(
|
||||
"optionValues elements must be a name-value pair."
|
||||
);
|
||||
}
|
||||
}
|
||||
// Initialize select2 control.
|
||||
this.$el.select2(
|
||||
_.defaults(
|
||||
{'disabled': !editable}, col.select2, this.select2Options
|
||||
));
|
||||
|
||||
setTimeout(function(){
|
||||
model.set(column.get("name"), self.$el.val());
|
||||
},10);
|
||||
|
||||
this.delegateEvents();
|
||||
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
Attach event handlers to the select2 box and focus it.
|
||||
*/
|
||||
postRender: function () {
|
||||
var self = this;
|
||||
self.$el.on("blur", function (e) {
|
||||
self.close(e);
|
||||
}).select2("focus");
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
this.$el.select2("destroy");
|
||||
return Backgrid.SelectCellEditor.prototype.remove.apply(this, arguments);
|
||||
},
|
||||
onSave: function (e) {
|
||||
var model = this.model;
|
||||
var column = this.column;
|
||||
model.set(column.get("name"), this.$el.val());
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Select2Cell for backgrid.
|
||||
*/
|
||||
var Select2Cell = Backgrid.Extension.Select2Cell =
|
||||
Backgrid.SelectCell.extend({
|
||||
className: "select2-cell",
|
||||
|
||||
/** @property */
|
||||
editor: Select2CellEditor,
|
||||
editor: null,
|
||||
|
||||
defaults: _.defaults({
|
||||
select2: {}
|
||||
select2: {},
|
||||
opt: {
|
||||
text: null,
|
||||
value: null,
|
||||
selected: false
|
||||
}
|
||||
}, Backgrid.SelectCell.prototype.defaults),
|
||||
|
||||
enterEditMode: function() {
|
||||
this.$el.addClass('editor');
|
||||
this.$select.select2('focus');
|
||||
this.$select.on('blur', this.exitEditMode);
|
||||
},
|
||||
|
||||
exitEditMode: function() {
|
||||
this.$select.off('blur', this.exitEditMode);
|
||||
this.$el.removeClass('editor');
|
||||
this.$select.select2('blur');
|
||||
},
|
||||
|
||||
events: {
|
||||
"change": "onSave",
|
||||
"select2:unselect": "onSave"
|
||||
@@ -479,11 +429,26 @@
|
||||
variable: null
|
||||
}),
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.SelectCell.prototype.initialize.apply(this, arguments);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var col = _.defaults(this.column.toJSON(), this.defaults),
|
||||
model = this.model, column = this.column,
|
||||
editable = Backgrid.callByNeed(col.editable, column, model),
|
||||
optionValues = _.clone(this.optionValues || this.column.get('options'));
|
||||
optionValues = _.clone(this.optionValues ||
|
||||
_.isFunction(this.column.get('options')) ?
|
||||
(this.column.get('options'))(this) :
|
||||
this.column.get('options'));
|
||||
|
||||
this.undelegateEvents();
|
||||
|
||||
if (this.$select) {
|
||||
this.$select.select2('destroy');
|
||||
this.$select.off('change', this.onSave);
|
||||
}
|
||||
|
||||
this.$el.empty();
|
||||
|
||||
@@ -494,7 +459,7 @@
|
||||
* Add empty option as Select2 requires any empty '<option><option>' for
|
||||
* some of its functionality to work.
|
||||
*/
|
||||
optionValues.unshift([null, null]);
|
||||
optionValues.unshift(this.defaults.opt);
|
||||
|
||||
var optionText = null,
|
||||
optionValue = null,
|
||||
@@ -503,33 +468,48 @@
|
||||
|
||||
delete this.$select;
|
||||
|
||||
this.$select = $("<select>", {tabIndex: -1}).appendTo(this.$el);
|
||||
selectedValues = model.get(this.column.get("name")),
|
||||
self = this,
|
||||
$select = self.$select = $('<select></select>').appendTo(this.$el);
|
||||
|
||||
for (var i = 0; i < optionValues.length; i++) {
|
||||
var optionValue = optionValues[i];
|
||||
var opt = optionValues[i];
|
||||
|
||||
if (_.isArray(optionValue)) {
|
||||
optionText = optionValue[0];
|
||||
optionValue = optionValue[1];
|
||||
if (_.isArray(opt)) {
|
||||
optionText = opt[0];
|
||||
optionValue = opt[1];
|
||||
|
||||
this.$select.append(
|
||||
this.template({
|
||||
text: optionText,
|
||||
value: optionValue,
|
||||
selected: (selectedValues == optionValue) ||
|
||||
(_.indexOf(selectedValues, optionValue) > -1)
|
||||
$select.append(
|
||||
self.template({
|
||||
text: optionText,
|
||||
value: optionValue,
|
||||
selected: (selectedValues == optionValue) ||
|
||||
(_.indexOf(selectedValues, optionValue) > -1)
|
||||
}));
|
||||
} else {
|
||||
throw new TypeError("optionValues elements must be a name-value pair.");
|
||||
} else {
|
||||
opt = _.defaults(opt, {
|
||||
selected: ((selectedValues == opt.value) ||
|
||||
(_.indexOf(selectedValues, opt.value) > -1))
|
||||
}, self.defaults.opt);
|
||||
$select.append(self.template(opt));
|
||||
}
|
||||
}
|
||||
|
||||
var select2_opts = _.extend(
|
||||
{openOnEnter: false},
|
||||
col.select2, this.defaults.select2
|
||||
);
|
||||
|
||||
if(col && _.has(col.disabled)) {
|
||||
_.extend(select2_opts, {
|
||||
disabled: evalF(col.disabled, col, model)
|
||||
});
|
||||
} else {
|
||||
_.extend(select2_opts, {disabled: !editable});
|
||||
}
|
||||
|
||||
// Initialize select2 control.
|
||||
this.$select.select2(
|
||||
_.defaults(
|
||||
{'disabled': !editable},
|
||||
col.select2,
|
||||
this.defaults.select2
|
||||
));
|
||||
this.$select.select2(select2_opts).on('change', self.onSave);
|
||||
|
||||
this.delegateEvents();
|
||||
|
||||
@@ -542,8 +522,16 @@
|
||||
onSave: function (e) {
|
||||
var model = this.model;
|
||||
var column = this.column;
|
||||
|
||||
model.set(column.get("name"), this.$select.val());
|
||||
}
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
this.$select.off('change', this.onSave);
|
||||
this.$select.select2('destroy');
|
||||
this.$el.empty();
|
||||
Backgrid.SelectCell.prototype.remove.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user