1) Added labels and titles after parsing and validating all the pgAdmin4 web pages for accessibility. Fixes #4770

2) Fixed an issue where Save Password control disappears after clicking on it while creating a server. Fixes #5116
This commit is contained in:
Pradip Parkale 2020-01-31 14:21:35 +05:30 committed by Akshay Joshi
parent 0da23b837d
commit 210bbfdbe1
13 changed files with 346 additions and 29 deletions

View File

@ -13,6 +13,9 @@ New features
| `Issue #3452 <https://redmine.postgresql.org/issues/3452>`_ - Added a Schema Diff tool to compare two schemas and generate a diff script.
| `Issue #4762 <https://redmine.postgresql.org/issues/4762>`_ - Allow screen-reader to read label & description of non-textable elements.
| `Issue #4763 <https://redmine.postgresql.org/issues/4763>`_ - Allow screen-reader to identify the alert errors.
| `Issue #4770 <https://redmine.postgresql.org/issues/4770>`_ - Added labels and titles after parsing and validating all the pgAdmin4 web pages for accessibility.
| `Issue #4993 <https://redmine.postgresql.org/issues/4993>`_ - Set input controls as read-only instead of disabled will allow tab navigation in the properties tab and also allow screen readers to read it.
Housekeeping
************
@ -30,11 +33,11 @@ Bug fixes
| `Issue #4410 <https://redmine.postgresql.org/issues/4410>`_ - Fixed an issue while editing char[] or character varying[] column from View/Edit data throwing an error.
| `Issue #4511 <https://redmine.postgresql.org/issues/4511>`_ - Fixed an issue where Grant wizard unable to handle multiple objects when the query string parameter exceeds its limit.
| `Issue #4827 <https://redmine.postgresql.org/issues/4827>`_ - Fix column resizable issue in the file explorer dialog.
| `Issue #4993 <https://redmine.postgresql.org/issues/4993>`_ - Set input controls as read-only instead of disabled will allow tab navigation in the properties tab and also allow screen readers to read it.
| `Issue #5000 <https://redmine.postgresql.org/issues/5000>`_ - Logout the pgAdmin session when no user activity of mouse move, click or keypress.
| `Issue #5025 <https://redmine.postgresql.org/issues/5025>`_ - Fix an issue where setting STORAGE_DIR to empty should show all the volumes on Windows in server mode.
| `Issue #5065 <https://redmine.postgresql.org/issues/5065>`_ - Updated the incorrect icon used for the cast node on refresh.
| `Issue #5066 <https://redmine.postgresql.org/issues/5066>`_ - Fix an issue where refreshing a package results in the change in the object completely.
| `Issue #5074 <https://redmine.postgresql.org/issues/5074>`_ - Fix an issue where select, insert and update scripts on tables throwing an error.
| `Issue #5076 <https://redmine.postgresql.org/issues/5076>`_ - Ensure Postfix starts in the container, now it runs as non-root by default.
| `Issue #5107 <https://redmine.postgresql.org/issues/5107>`_ - Set proper focus on tab navigation for file manager dialog.
| `Issue #5107 <https://redmine.postgresql.org/issues/5107>`_ - Set proper focus on tab navigation for file manager dialog.
| `Issue #5116 <https://redmine.postgresql.org/issues/5116>`_ - Fixed an issue where Save Password control disappears after clicking on it while creating a server.

View File

@ -71,7 +71,7 @@ define('pgadmin.node.schema', [
var gridHeader = _.template([
'<div class="subnode-header">',
' <label class="control-label col-sm-4"><%-label%></label>',
' <span class="control-label col-sm-4"><%-label%></span>',
'</div>'].join('\n')),
gridBody = $('<div class="pgadmin-control-group backgrid form-group col-12 object subnode"></div>').append(
gridHeader(attributes)

View File

@ -89,7 +89,7 @@ define('pgadmin.node.role', [
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%>">',
' <select multiple="multiple" style="width:100%;" class="pgadmin-controls <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-JSON.stringify(value)%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%>>',
' <select title = <%=label%> multiple="multiple" style="width:100%;" class="pgadmin-controls <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-JSON.stringify(value)%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%>>',
' <% for (var i=0; i < options.length; i++) { %>',
' <% var option = options[i]; %>',
' <option value=<%-option.value%> data-icon=<%-option.image%> <%=value != null && _.indexOf(value, option.value) != -1 ? "selected" : ""%> <%=option.disabled ? "disabled=\'disabled\'" : ""%>><%-option.label%></option>',

View File

@ -337,8 +337,8 @@ function(gettext, _, $, Backbone, Backform, Backgrid, Alertify, pgAdmin, pgNode)
var self = this,
titleTmpl = _.template([
'<div class=\'subnode-header\'>',
'<label class=\'control-label\'><%-label%></label>',
'<button class=\'btn btn-sm-sq btn-secondary add fa fa-plus\' title=\'' + _('Add new row') + '\' <%=canAdd ? \'\' : \'disabled="disabled"\'%>></button>',
'<span class=\'control-label\'><%-label%></span>',
'<button class=\'btn btn-sm-sq btn-secondary add fa fa-plus\' title=\'' + _('Add new row') + '\' <%=canAdd ? \'\' : \'disabled="disabled"\'%>><span class="sr-only">Add new row</span></button>',
'</div>'].join('\n')),
$gridBody =
$('<div class=\'pgadmin-control-group backgrid form-group col-12 object subnode\'></div>').append(

View File

@ -226,7 +226,7 @@ define('pgadmin.browser', [
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div class="sql_textarea"><textarea id="sql-textarea" name="sql-textarea" title="'+gettext('SQL Code')+'"></textarea></div>',
content: '<label for="sql-textarea" class="sr-only">SQL Code</label><div class="sql_textarea"><textarea id="sql-textarea" name="sql-textarea" title="'+gettext('SQL Code')+'"></textarea></div>',
}),
// Dependencies of the object
'dependencies': new pgAdmin.Browser.Panel({

View File

@ -99,7 +99,7 @@ define([
'<button tabindex="0" type="<%= type %>" ',
'class="btn <%=extraClasses.join(\' \')%>"',
'<% if (disabled) { %> disabled="disabled"<% } %> title="<%-tooltip%>">',
'<span class="<%= icon %>" role="img"></span><% if (label != "") { %>&nbsp;<%-label%><% } %></button>',
'<span class="<%= icon %>" role="img"></span><% if (label != "") { %>&nbsp;<%-label%><% } %><span class="sr-only"><%-tooltip%></span></button>',
].join(' '));
if (location == 'header') {
btnGroup.appendTo(that.header);
@ -165,9 +165,9 @@ define([
// canDrop can be set to false for individual row from the server side to disable the checkbox
if ('canDrop' in model && model.canDrop === false)
this.$el.empty().append('<input tabindex="-1" type="checkbox" disabled="disabled"/>');
this.$el.empty().append('<input tabindex="-1" type="checkbox" title="Select" disabled="disabled"/>');
else
this.$el.empty().append('<input tabindex="-1" type="checkbox" />');
this.$el.empty().append('<input tabindex="-1" type="checkbox" title="Select" />');
this.delegateEvents();
return this;

View File

@ -208,7 +208,7 @@ define([
pgAdmin.Browser.MenuGroup = function(opts, items, prev, ctx) {
var template = _.template([
'<% if (above) { %><li class="dropdown-divider"></li><% } %>',
'<li class="dropdown-submenu">',
'<li class="dropdown-submenu" role="menuitem">',
' <a href="#" class="dropdown-item">',
' <% if (icon) { %><i class="<%= icon %>"></i><% } %>',
' <span><%= label %></span>',

View File

@ -4,7 +4,6 @@
@import '~bootstrap-datepicker/dist/css/bootstrap-datepicker3.css';
@import '~tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.css';
@import '~bootstrap4-toggle/css/bootstrap4-toggle.css';
@import '~backgrid-select-all/backgrid-select-all.css';
@import '~backgrid-filter/backgrid-filter.css';
@import '~slickgrid/css/select2.css';
@import '~jquery-contextmenu/dist/jquery.contextMenu.css';
@ -22,3 +21,4 @@
@import '~slickgrid/css/smoothness/jquery-ui-1.11.3.custom.css';
@import '../vendor/backgrid/backgrid.css';
@import '../vendor/backgrid/backgrid-select-all.css';

View File

@ -175,7 +175,7 @@ define([
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>" for="<%=cId%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%>">',
' <input class="<%=Backform.controlClassName%> uneditable-input" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> id="<%=cId%>" value="<%-value%>" />',
' <input id="<%=cId%>" class="<%=Backform.controlClassName%> uneditable-input" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> id="<%=cId%>" value="<%-value%>" />',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
@ -551,7 +551,7 @@ define([
extraToggleClasses: null,
},
template: _.template([
'<label class="<%=controlLabelClassName%>"><%=label%></label>',
'<span class="<%=controlLabelClassName%>"><%=label%></span>',
'<label class="sr-value sr-only" for="<%=cId%>"></label>',
'<div class="<%=controlsClassName%> <%=extraClasses.join(\' \')%>">',
' <input tabindex="-1" type="checkbox" aria-hidden="true" aria-label="Toggle button" data-style="quick" data-toggle="toggle"',
@ -1265,7 +1265,7 @@ define([
var self = this,
gridHeader = _.template([
'<div class="subnode-header">',
' <label class="control-label pg-el-sm-10" id="<%=cId%>"><%-label%></label>',
' <span class="control-label pg-el-sm-10" id="<%=cId%>"><%-label%></span>',
' <button aria-label="' + _('Add new row') + '" class="btn btn-sm-sq btn-secondary add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> title="' + _('Add new row') + '"><%-add_label%></button>',
'</div>',
].join('\n')),
@ -1726,8 +1726,9 @@ define([
helpMessage: null,
},
template: _.template([
'<label for="<%=cId%>" class="sr-only"><%=(label==""?"SQL":label)%></label>',
'<div class="<%=controlsClassName%>">',
' <textarea class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> <%=required ? "required" : ""%>><%-value%></textarea>',
' <textarea id="<%=cId%>" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> <%=required ? "required" : ""%>><%-value%></textarea>',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
@ -2140,7 +2141,7 @@ define([
' <label class="<%=Backform.controlLabelClassName%>" for="<%=cId%>"><%=label%></label>',
'<% }%>',
'<div class="<%=Backform.controlsClassName%>">',
' <select id="<%=cId%>" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
' <select title="<%=name%>" id="<%=cId%>" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
' name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "disabled" : ""%>',
' <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
' <%=select2.first_empty ? " <option></option>" : ""%>',
@ -2437,9 +2438,9 @@ define([
// Customize template to add new styles
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<label class="<%=Backform.controlLabelClassName%>" for="<%=cId%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%> sql_field_layout <%=extraClasses.join(\' \')%>">',
' <textarea ',
' <textarea id="<%=cId%>"',
' class="<%=Backform.controlClassName%> " name="<%=name%>"',
' maxlength="<%=maxlength%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%>',
' rows=<%=rows%>',
@ -2523,6 +2524,7 @@ define([
return (_.isFunction(f) ? !!f.apply(d, [m]) : !!f);
};
data.cId = data.cId || _.uniqueId('pgC_');
// Evaluate the disabled, visible option
var isDisabled = evalF(data.disabled, data, this.model),
isVisible = evalF(data.visible, data, this.model),
@ -2616,8 +2618,9 @@ define([
Backform.SqlCodeControl = Backform.SqlFieldControl.extend({
// Customize template to add new styles
template: _.template([
'<label class="sr-only" for="<%=cId%>"><%=(label==""?"Code":label)%></label>',
'<div class="pgadmin-controls pg-el-12 <%=extraClasses.join(\' \')%>">',
' <textarea ',
' <textarea id="<%=cId%>" ',
' class="<%=Backform.controlClassName%> " name="<%=name%>"',
' maxlength="<%=maxlength%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> ',
' rows=<%=rows%>',
@ -2797,9 +2800,9 @@ define([
}
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<label for="<%=cId%>" class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="input-group <%=Backform.controlsClassName%>">',
' <input type="text" class="<%=Backform.controlClassName%> datetimepicker-input <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-value%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> <%=required ? "required" : ""%> data-toggle="datetimepicker"/>',
' <input id="<%=cId%>" type="text" class="<%=Backform.controlClassName%> datetimepicker-input <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-value%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly aria-readonly=true" : ""%> <%=required ? "required" : ""%> data-toggle="datetimepicker"/>',
' <div class="input-group-append">',
' <span class="input-group-text fa fa-calendar"></span>',
' </div>',
@ -2834,6 +2837,9 @@ define([
visible: evalF(data.visible, this.model),
required: evalF(data.required, this.model),
});
data.cId = data.cId || _.uniqueId('pgC_');
if (!data.disabled) {
data.placeholder = data.placeholder || this.defaults.placeholder;
}
@ -3226,7 +3232,7 @@ define([
'<label class="<%=Backform.controlLabelClassName%>"><%=controlLabel%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <button class="btn btn-secondary btn-checkbox">',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=cId%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <%=label%>',
' </button>',
'</div>',

View File

@ -547,12 +547,12 @@
id: _.uniqueId('bf_')
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>" for="<%=id%>"><%=controlLabel%></label>',
'<label class="<%=Backform.controlLabelClassName%>" for="<%=cId%>"><%=controlLabel%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <div class="form-check">',
' <input type="<%=type%>" class="form-check-input <%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly" : ""%> <%=required ? "required" : ""%> />',
' <input type="<%=type%>" class="form-check-input <%=extraClasses.join(\' \')%>" id="<%=cId%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=readonly ? "readonly" : ""%> <%=required ? "required" : ""%> />',
' <% if (label && label.length) { %>',
' <label class="form-check-label" for="<%=id%>"><%=label%></label>',
' <label class="form-check-label" for="<%=cId%>"><%=label%></label>',
' <% } %>',
' </div>',
'</div>'
@ -579,8 +579,8 @@
' <% var option = options[i]; %>',
' <% var id = _.uniqueId("bf_"); %>',
' <div class="form-check">',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" value="<%-formatter.fromRaw(option.value)%>" <%=rawValue == option.value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=readonly ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <label class="form-check-label" for="<%=id%>"><%-option.label%></label>',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=cId%>" name="<%=name%>" value="<%-formatter.fromRaw(option.value)%>" <%=rawValue == option.value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=readonly ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <label class="form-check-label" for="<%=cId%>"><%-option.label%></label>',
' </div>',
' <% } %>',
' <% if (helpMessage && helpMessage.length) { %>',

View File

@ -0,0 +1,12 @@
/*
backgrid-select-all
http://github.com/wyuenho/backgrid
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
Licensed under the MIT @license.
*/
.backgrid .select-row-cell,
.backgrid .select-all-header-cell {
text-align: center;
}

View File

@ -0,0 +1,296 @@
/*
backgrid-select-all
http://github.com/wyuenho/backgrid
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
Licensed under the MIT @license.
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(["backbone", "backgrid", "underscore"], factory);
} else if (typeof exports == "object") {
// CommonJS
module.exports = factory(require("backbone"), require("backgrid"), require("underscore"));
}
// Browser
else factory(root.Backbone, root.Backgrid, root._);
}(this, function (Backbone, Backgrid, _) {
"use strict";
/**
Renders a checkbox for row selection.
@class Backgrid.Extension.SelectRowCell
@extends Backbone.View
*/
var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({
/** @property */
className: "select-row-cell",
/** @property */
tagName: "td",
/** @property */
events: {
"keydown input[type=checkbox]": "onKeydown",
"change input[type=checkbox]": "onChange",
"click input[type=checkbox]": "enterEditMode"
},
/**
Initializer. If the underlying model triggers a `select` event, this cell
will change its checked value according to the event's `selected` value.
@param {Object} options
@param {Backgrid.Column} options.column
@param {Backbone.Model} options.model
*/
initialize: function (options) {
this.column = options.column;
if (!(this.column instanceof Backgrid.Column)) {
this.column = new Backgrid.Column(this.column);
}
var column = this.column, model = this.model, $el = this.$el;
this.listenTo(column, "change:renderable", function (column, renderable) {
$el.toggleClass("renderable", renderable);
});
if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass("renderable");
this.listenTo(model, "backgrid:select", function (model, selected) {
this.checkbox().prop("checked", selected).change();
});
},
/**
Returns the checkbox.
*/
checkbox: function () {
return this.$el.find("input[type=checkbox]");
},
/**
Focuses the checkbox.
*/
enterEditMode: function () {
this.checkbox().focus();
},
/**
Unfocuses the checkbox.
*/
exitEditMode: function () {
this.checkbox().blur();
},
/**
Process keyboard navigation.
*/
onKeydown: function (e) {
var command = new Backgrid.Command(e);
if (command.passThru()) return true; // skip ahead to `change`
if (command.cancel()) {
e.stopPropagation();
this.checkbox().blur();
}
else if (command.save() || command.moveLeft() || command.moveRight() ||
command.moveUp() || command.moveDown()) {
e.preventDefault();
e.stopPropagation();
this.model.trigger("backgrid:edited", this.model, this.column, command);
}
},
/**
When the checkbox's value changes, this method will trigger a Backbone
`backgrid:selected` event with a reference of the model and the
checkbox's `checked` value.
*/
onChange: function () {
var checked = this.checkbox().prop("checked");
this.$el.parent().toggleClass("selected", checked);
this.model.trigger("backgrid:selected", this.model, checked);
},
/**
Renders a checkbox in a table cell.
*/
render: function () {
this.$el.empty().append('<label class="sr-only">Select all</label><input tabindex="-1" type="checkbox" title="Select all"/>');
this.delegateEvents();
return this;
}
});
/**
Renders a checkbox to select all rows on the current page.
@class Backgrid.Extension.SelectAllHeaderCell
@extends Backgrid.Extension.SelectRowCell
*/
var SelectAllHeaderCell = Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({
/** @property */
className: "select-all-header-cell",
/** @property */
tagName: "th",
/**
Initializer. When this cell's checkbox is checked, a Backbone
`backgrid:select` event will be triggered for each model for the current
page in the underlying collection. If a `SelectRowCell` instance exists
for the rows representing the models, they will check themselves. If any
of the SelectRowCell instances trigger a Backbone `backgrid:selected`
event with a `false` value, this cell will uncheck its checkbox. In the
event of a Backbone `backgrid:refresh` event, which is triggered when the
body refreshes its rows, which can happen under a number of conditions
such as paging or the columns were reset, this cell will still remember
the previously selected models and trigger a Backbone `backgrid:select`
event on them such that the SelectRowCells can recheck themselves upon
refreshing.
@param {Object} options
@param {Backgrid.Column} options.column
@param {Backbone.Collection} options.collection
*/
initialize: function (options) {
this.column = options.column;
if (!(this.column instanceof Backgrid.Column)) {
this.column = new Backgrid.Column(this.column);
}
var collection = this.collection;
var selectedModels = this.selectedModels = {};
this.listenTo(collection.fullCollection || collection,
"backgrid:selected", function (model, selected) {
if (selected) selectedModels[model.id || model.cid] = 1;
else {
delete selectedModels[model.id || model.cid];
this.checkbox().prop("checked", false);
}
if (_.keys(selectedModels).length === (collection.fullCollection|| collection).length) {
this.checkbox().prop("checked", true);
}
});
this.listenTo(collection.fullCollection || collection, "remove", function (model) {
delete selectedModels[model.id || model.cid];
if ((collection.fullCollection || collection).length === 0) {
this.checkbox().prop("checked", false);
}
});
this.listenTo(collection, "backgrid:refresh", function () {
if ((collection.fullCollection || collection).length === 0) {
this.checkbox().prop("checked", false);
}
else {
var checked = this.checkbox().prop("checked");
for (var i = 0; i < collection.length; i++) {
var model = collection.at(i);
if (checked || selectedModels[model.id || model.cid]) {
model.trigger("backgrid:select", model, true);
}
}
}
});
var column = this.column, $el = this.$el;
this.listenTo(column, "change:renderable", function (column, renderable) {
$el.toggleClass("renderable", renderable);
});
if (Backgrid.callByNeed(column.renderable(), column, collection)) $el.addClass("renderable");
},
/**
Propagates the checked value of this checkbox to all the models of the
underlying collection by triggering a Backbone `backgrid:select` event on
the models on the current page, passing each model and the current
`checked` value of the checkbox in each event.
A `backgrid:selected` event will also be triggered with the current
`checked` value on all the models regardless of whether they are on the
current page.
This method triggers a 'backgrid:select-all' event on the collection
afterwards.
*/
onChange: function () {
var checked = this.checkbox().prop("checked");
var collection = this.collection;
collection.each(function (model) {
model.trigger("backgrid:select", model, checked);
});
if (collection.fullCollection) {
collection.fullCollection.each(function (model) {
if (!collection.get(model.cid)) {
model.trigger("backgrid:selected", model, checked);
}
});
}
this.collection.trigger("backgrid:select-all", this.collection, checked);
}
});
/**
Convenient method to retrieve a list of selected models. This method only
exists when the `SelectAll` extension has been included. Selected models
are retained across pagination.
@member Backgrid.Grid
@return {Array.<Backbone.Model>}
*/
Backgrid.Grid.prototype.getSelectedModels = function () {
var selectAllHeaderCell;
var headerCells = this.header.row.cells;
for (var i = 0, l = headerCells.length; i < l; i++) {
var headerCell = headerCells[i];
if (headerCell instanceof SelectAllHeaderCell) {
selectAllHeaderCell = headerCell;
break;
}
}
var result = [];
if (selectAllHeaderCell) {
var selectedModels = selectAllHeaderCell.selectedModels;
var collection = this.collection.fullCollection || this.collection;
for (var modelId in selectedModels) {
result.push(collection.get(modelId));
}
}
return result;
};
/**
Convenient method to deselect the selected models. This method is only
available when the `SelectAll` extension has been included.
@member Backgrid.Grid
*/
Backgrid.Grid.prototype.clearSelectedModels = function () {
var selectedModels = this.getSelectedModels();
for (var i = 0, l = selectedModels.length; i < l; i++) {
var model = selectedModels[i];
model.trigger("backgrid:select", model, false);
}
};
}));

View File

@ -172,7 +172,7 @@ var webpackShimConfig = {
'bootstrap.toggle': path.join(__dirname, './node_modules/bootstrap4-toggle/js/bootstrap4-toggle'),
'select2': path.join(__dirname, './node_modules/select2/dist/js/select2.full'),
'backgrid.filter': path.join(__dirname, './node_modules/backgrid-filter/backgrid-filter'),
'backgrid.select.all': path.join(__dirname, './node_modules/backgrid-select-all/backgrid-select-all'),
'backgrid.select.all': path.join(__dirname, './pgadmin/static/vendor/backgrid/backgrid-select-all'),
'pgadmin.alertifyjs': path.join(__dirname, './pgadmin/static/js/alertify.pgadmin.defaults'),
'pgadmin.backform': path.join(__dirname, './pgadmin/static/js/backform.pgadmin'),
'pgadmin.backgrid': path.join(__dirname, './pgadmin/static/js/backgrid.pgadmin'),