diff --git a/app/assets/javascripts/repositories/index.js b/app/assets/javascripts/repositories/index.js index ececb0678..7c67ccb0d 100644 --- a/app/assets/javascripts/repositories/index.js +++ b/app/assets/javascripts/repositories/index.js @@ -1,13 +1,15 @@ -/* global DataTableHelpers */ +/* global DataTableHelpers DataTableCheckboxes */ (function() { 'use strict'; var REPOSITORIES_TABLE; + var CHECKBOX_SELECTOR; function initRepositoriesDataTable(tableContainer, archived = false) { var tableTemplate = archived ? $('#archivedRepositoriesListTable').html() : $('#activeRepositoriesListTable').html(); $.get($(tableTemplate).data('source'), function(data) { if (REPOSITORIES_TABLE) REPOSITORIES_TABLE.destroy(); + CHECKBOX_SELECTOR = null; $('.content-body').html(tableTemplate); REPOSITORIES_TABLE = $(tableContainer).DataTable({ aaData: data, @@ -35,14 +37,23 @@ return `${value}`; } }], - - fnInitComplete: function() { - var dataTableWrapper = $(tableContainer).closest('.dataTables_wrapper'); + fnInitComplete: function(e) { + var dataTableWrapper = $(e.nTableWrapper); + CHECKBOX_SELECTOR = new DataTableCheckboxes(dataTableWrapper, { + checkboxSelector: '.repository-row-selector', + selectAllSelector: '.select-all-checkbox' + }); DataTableHelpers.initLengthApearance(dataTableWrapper); DataTableHelpers.initSearchField(dataTableWrapper); $('.content-body .toolbar').html($('#repositoriesListButtons').html()); dataTableWrapper.find('.main-actions, .pagination-row').removeClass('hidden'); $('.create-new-repository').initializeModal('#create-repo-modal'); + }, + drawCallback: function() { + if (CHECKBOX_SELECTOR) CHECKBOX_SELECTOR.checkSelectAllStatus(); + }, + rowCallback: function(row) { + if (CHECKBOX_SELECTOR) CHECKBOX_SELECTOR.checkRowStatus(row); } }); }); diff --git a/app/assets/javascripts/sitewide/datatable_helpers.js b/app/assets/javascripts/sitewide/datatable_helpers.js index 57f346f89..ba0dccdd2 100644 --- a/app/assets/javascripts/sitewide/datatable_helpers.js +++ b/app/assets/javascripts/sitewide/datatable_helpers.js @@ -35,3 +35,93 @@ var DataTableHelpers = (function() { } }; }()); + +class DataTableCheckboxes { + + /* config = { + checkboxSelector: selector for checkboxes, + selectAllSelector: selector for select all checkbox + }*/ + + constructor(tableWrapper, config) { + this.selectedRows = []; + this.tableWrapper = $(tableWrapper); + this.config = config; + + this.#initCheckboxes(); + this.#initSelectAllCheckbox(); + } + + checkRowStatus = (row) => { + var checkbox = $(row).find(this.config.checkboxSelector); + if (this.selectedRows.includes(row.id)) { + $(row).addClass('selected'); + checkbox.attr('checked', true); + } else { + $(row).removeClass('selected'); + checkbox.attr('checked', false); + } + } + + checkSelectAllStatus = () => { + var checkboxes = this.tableWrapper.find(this.config.checkboxSelector); + var selectedCheckboxes = this.tableWrapper.find(this.config.checkboxSelector + ':checked'); + var selectAllCheckbox = this.tableWrapper.find(this.config.selectAllSelector); + selectAllCheckbox.prop('indeterminate', false); + if (selectedCheckboxes.length === 0) { + selectAllCheckbox.prop('checked', false); + } else if (selectedCheckboxes.length === checkboxes.length) { + selectAllCheckbox.prop('checked', true); + } else { + selectAllCheckbox.prop('indeterminate', true); + } + } + + clearSelection = () => { + var rows = this.tableWrapper.find('tbody tr'); + this.selectedRows = []; + $.each(rows, (i, row) => { + $(row).removeClass('selected'); + $(row).find(this.config.checkboxSelector).attr('checked', false); + }); + this.checkSelectAllStatus(); + } + + // private methods + + #initCheckboxes = () => { + this.tableWrapper.on('click', '.table tbody tr', (e) => { + var checkbox = $(e.currentTarget).find(this.config.checkboxSelector); + checkbox.prop('checked', !checkbox.prop('checked')); + this.#selectRow(e.currentTarget); + }).on('click', this.config.checkboxSelector, (e) => { + this.#selectRow($(e.currentTarget).closest('tr')[0]); + e.stopPropagation(); + }); + } + + #selectRow = (row) => { + var id = row.id; + if (this.selectedRows.includes(id)) { + this.selectedRows.splice(this.selectedRows.indexOf(id), 1); + } else { + this.selectedRows.push(id); + } + $(row).toggleClass('selected'); + this.checkSelectAllStatus(); + } + + #initSelectAllCheckbox = () => { + this.tableWrapper.on('click', this.config.selectAllSelector, (e) => { + var selectAllCheckbox = $(e.currentTarget); + var rows = this.tableWrapper.find('tbody tr'); + $.each(rows, (i, row) => { + var checkbox = $(row).find(this.config.checkboxSelector); + if (checkbox.prop('checked') === selectAllCheckbox.prop('checked')) return; + + checkbox.prop('checked', !checkbox.prop('checked')); + this.#selectRow(row); + }); + }); + } +} diff --git a/app/helpers/repositories_datatable_helper.rb b/app/helpers/repositories_datatable_helper.rb index 616997266..50a6af526 100644 --- a/app/helpers/repositories_datatable_helper.rb +++ b/app/helpers/repositories_datatable_helper.rb @@ -8,7 +8,7 @@ module RepositoriesDatatableHelper repositories = repositories.includes(:repository_rows, :team, :created_by, :archived_by) repositories.each do |repository| result.push( - 'DT_RepositoryId': repository.id, + 'DT_RowId': repository.id, '1': escape_input(repository.name), '2': repository.repository_rows.size, '3': repository.shared_with?(team), diff --git a/app/views/repositories/index.html.erb b/app/views/repositories/index.html.erb index c6ef599df..a45fba012 100644 --- a/app/views/repositories/index.html.erb +++ b/app/views/repositories/index.html.erb @@ -32,7 +32,7 @@