[PATCH] [Wok] Changes in wok.list.js widget to allow multiple selection

From: Samuel Guimarães <sguimaraes943@gmail.com> This patch updates wok.list.js widget to allow multiple selection in Debug Reports and Repositories in Gingerbase. Another patch was sent to Ginger Dev List covering the changes necessary. This patch also includes changes in Wok SCSS and CSS aiming accessibility and responsive design. Samuel Guimarães (1): Changes in wok.list.js widget to allow multiple selection ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-) -- 1.9.3

From: Samuel Guimarães <sguimaraes943@gmail.com> This commit enables multiple selection with wok.list.js widget. It also features some enhancements for mobile and keyboard navigation. Signed-off-by: Samuel Guimarães <sguimaraes943@gmail.com> --- ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-) diff --git a/ui/css/bootstrap.custom.css b/ui/css/bootstrap.custom.css index 13869da..c69939c 100644 --- a/ui/css/bootstrap.custom.css +++ b/ui/css/bootstrap.custom.css @@ -2996,7 +2996,7 @@ fieldset[disabled] .btn-link:focus { } .btn-xs, .btn-group-xs > .btn { - padding: 1px 5px; + padding: 2px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; @@ -3460,9 +3460,9 @@ tbody.collapse.in { display: table-cell; } -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { +.input-group-addon:not(:first-child, :first-child, :first-child):not(:last-child, :last-child, :last-child), +.input-group-btn:not(:first-child, :first-child, :first-child):not(:last-child, :last-child, :last-child), +.input-group .form-control:not(:first-child, :first-child, :first-child):not(:last-child, :last-child, :last-child) { border-radius: 0; } diff --git a/ui/css/src/modules/_buttons.scss b/ui/css/src/modules/_buttons.scss index 85d9531..077a21f 100644 --- a/ui/css/src/modules/_buttons.scss +++ b/ui/css/src/modules/_buttons.scss @@ -23,6 +23,14 @@ font-size: 13pt; } +.btn-xs, .btn-group-xs > .btn { + font-size: 10.5pt; +} + +.btn-sm, .btn-group-sm > .btn { + font-size: 11.5pt; +} + .btn-login { @include button-variant($btn-login-color, $btn-login-bg, $btn-login-border); } \ No newline at end of file diff --git a/ui/css/src/modules/_wok-forms.scss b/ui/css/src/modules/_wok-forms.scss index d426a60..c3f722a 100644 --- a/ui/css/src/modules/_wok-forms.scss +++ b/ui/css/src/modules/_wok-forms.scss @@ -75,6 +75,7 @@ input[type=checkbox].wok-checkbox + label:before { input[type=checkbox].wok-checkbox:checked + label:before { content: "\f14a"; letter-spacing: 8px; + margin-right: 0.9px // Sub-pixel unit for Chrome and Firefox anti-alias } input[type=radio].wok-radio + label:before { diff --git a/ui/css/src/modules/_wok-grid.scss b/ui/css/src/modules/_wok-grid.scss index 730d224..1f8093e 100644 --- a/ui/css/src/modules/_wok-grid.scss +++ b/ui/css/src/modules/_wok-grid.scss @@ -36,23 +36,17 @@ top: 37px !important; } -.wok-list-cell { - position: relative; - padding-left: 45px; +.wok-list-content { + border-top: 1px solid $table-first-row-border-color; } -.wok-repository-status { - position: absolute; - left: 6px; - top: 0; -} - -.wok-repository-status .fa { - font-size: 23px; - color: $fa-green; +.wok-list-cell { + position: relative; + padding-left: 10px; } -.wok-list-name, .wok-list-description { +.wok-list-name, +.wok-list-description { display: block; } @@ -67,47 +61,235 @@ overflow: hidden; } -.wok-list-content tbody tr, .wok-list-content tbody tr * { +.wok-list-item-status { + float: left; + margin-top: 12px; + margin-right: 8px; + margin-bottom: 6px; + height: 25px; +} + +.wok-list-item-status > .fa { + font-size: 23px; + color: $fa-green; +} + +.wok-list-item-status.disabled > .fa:before { + display: block; + width: 19px; + height: 23px; + padding: 0; + border: 0; + content: ""; +} + +.wok-list-cell.disabled span { + color: $gray-light; +} + +.wok-list-action-button-container { + padding-bottom: 16px; +} + +.wok-list-loading-icon-inline { + background: transparent url('#{$wok-icon-path}/spin5.svg') no-repeat 50% 50%; + @include animation(spin 3s infinite linear); + height: 16px; + width: 16px; + background-size: 100%; + display: none; + position: absolute; +} + +.generating .wok-list-description { + padding-left: 24px; +} + +.generating .wok-list-loading-icon-inline { + display: block; + position: absolute; + top: 27px; + left: 34px; +} + +.wok-list > ul { + list-style: none; + padding: 0; +} + +.wok-list > ul > li, +.wok-list > ul > li * { @include user-select(none); } -.wok-list-content tbody tr:hover { +.wok-list > ul > li, +.wok-list > ul > li > label { + width: 100%; +} + +.wok-list > ul > li { + border-top: 1px solid $table-border-color; + background: $table-bg; + position: relative; + @include transition(background .1s ease-in-out); +} + +.wok-list > ul > li:first-child { + border: 0; +} + +.wok-list > ul > li:nth-of-type(even) { + background: $table-bg-accent; +} + +.wok-list > ul > li.selected { + background: $table-bg-hover; +} + +.wok-list > ul > li > label { + cursor: pointer !important; + text-decoration: none; + margin-bottom: 0; + padding-bottom: 5px; +} + +.wok-list > ul > li > label:hover { text-decoration: underline; - cursor: pointer; } -.wok-list-content tbody tr.generating:hover { +.wok-list > ul > li.generating > label:hover { text-decoration: none; cursor: default; } -.wok-list-content tbody tr.selected { - background: #ddd; +.wok-list > ul > li > input[type=checkbox] { + left: -15px; } -span.wok-repository-status.disabled { - display: none; +.wok-list > ul > li > input[type=checkbox].wok-checkbox + label:before { + float: left; + height: 30px; + margin-top: 13px; } -.wok-list-cell.disabled span { - color: #999; +// Mobile first + +.wok-list-action-button-container { + background: $body-bg; + z-index: 1; + position: relative; + @include box-shadow(0 20px 20px -20px rgba(0,0,0,.4)); } -.wok-single-button { - padding-bottom: 16px; - margin-top: -11px; +.mobile-action { + width: 100%; } -.generating .wok-list-description { - padding-left: 24px; +.mobile-action .btn { + width: 100%; + height: 40px; + border-radius: 0; } -.generating .wok-list-loading-icon-inline { - background: transparent url('#{$wok-icon-path}/spin5.svg') no-repeat 50% 50%; - @include animation(spin 3s infinite linear); - height: 16px; - width: 16px; - background-size: 100%; - display: block; - position: absolute; +.mobile-action > .btn { + border-radius: $border-radius-base; } + +.mobile-action.open > .btn { + border-radius: $border-radius-base $border-radius-base 0 0; +} + +.mobile-action .btn span.mobile-action-label { + font-weight: 600; +} + +.mobile-action .btn span.mobile-action-count { + font-weight: 300; +} + +.mobile-action .btn span.mobile-action-count strong { + font-weight: 600; + font-size: 11pt; +} + +.mobile-action .dropdown-menu { + width: 100%; + border: 0; + box-shadow: none; + background: transparent; + padding: 0; + margin: 0; + border-radius: 0; +} + +.mobile-action.open .dropdown-menu .btn { + border-radius: 0; +} + +.mobile-action.open .dropdown-menu li:last-child .btn { + border-radius: 0 0 $border-radius-base $border-radius-base; +} + +.mobile-action .dropdown-menu li > .btn.disabled, +.mobile-action .dropdown-menu li > .btn[disabled] { + opacity: 1; + background: #585758; + border-color: #585758; + color: #ddd; +} + +// Reset Mobile styles to mimic desktop when min-width is bigger than 768px wide + +@media (min-width: $screen-md-min) { + + .wok-list-action-button-container { + @include box-shadow(none); + } + + .wok-list-action-button-container .dropdown-toggle { + display: none; + } + + .wok-list-action-button-container .mobile-action { + position: static; + height: 40px; + } + + .wok-list-action-button-container .mobile-action .btn { + width: auto; + } + + .wok-list-action-button-container .mobile-action li:first-child .btn { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + + + .wok-list-action-button-container .mobile-action li:last-child .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 !important; + border-top-right-radius: $border-radius-base !important; + border-bottom-right-radius: $border-radius-base; + } + + .wok-list-action-button-container > .dropdown.mobile-action > .dropdown-menu { + display: block; + vertical-align: middle; + position: absolute; + top: 0; + } + + .wok-list-action-button-container > .dropdown.mobile-action > .dropdown-menu > li { + display: inline-block; + } + + .wok-list > ul > li > input[type=checkbox].wok-checkbox + label:before { + display: none; // Hide checkbox on desktop + } + + .wok-list > ul > li > input[type=checkbox].wok-checkbox:focus + label { + outline: auto 5px $input-border-focus; // Accessibility + outline: auto 5px -webkit-focus-ring-color; // Set default webkit focus ring color for webkit browsers + } + +} \ No newline at end of file diff --git a/ui/css/src/modules/_wok-variables.scss b/ui/css/src/modules/_wok-variables.scss index 9f53cb2..c58feba 100644 --- a/ui/css/src/modules/_wok-variables.scss +++ b/ui/css/src/modules/_wok-variables.scss @@ -164,8 +164,8 @@ $padding-large-horizontal: 16px !default; $padding-small-vertical: 5px !default; $padding-small-horizontal: 10px !default; -$padding-xs-vertical: 1px !default; -$padding-xs-horizontal: 5px !default; +$padding-xs-vertical: 2px !default; +$padding-xs-horizontal: 10px !default; $line-height-large: 1.3333333 !default; // extra decimals for Win 8.1 Chrome $line-height-small: 1.5 !default; diff --git a/ui/css/wok.css b/ui/css/wok.css index 615cdea..9d3a535 100644 --- a/ui/css/wok.css +++ b/ui/css/wok.css @@ -336,6 +336,14 @@ body { font-size: 13pt; } +.btn-xs, .btn-group-xs > .btn { + font-size: 10.5pt; +} + +.btn-sm, .btn-group-sm > .btn { + font-size: 11.5pt; +} + .btn-login { color: #fff; background-color: #008abf; @@ -676,23 +684,17 @@ fieldset[disabled] .btn-login.active { top: 37px !important; } -.wok-list-cell { - position: relative; - padding-left: 45px; +.wok-list-content { + border-top: 1px solid #e3e3e3; } -.wok-repository-status { - position: absolute; - left: 6px; - top: 0; -} - -.wok-repository-status .fa { - font-size: 23px; - color: #a8d46f; +.wok-list-cell { + position: relative; + padding-left: 10px; } -.wok-list-name, .wok-list-description { +.wok-list-name, +.wok-list-description { display: block; } @@ -707,54 +709,230 @@ fieldset[disabled] .btn-login.active { overflow: hidden; } -.wok-list-content tbody tr, .wok-list-content tbody tr * { +.wok-list-item-status { + float: left; + margin-top: 12px; + margin-right: 8px; + margin-bottom: 6px; + height: 25px; +} + +.wok-list-item-status > .fa { + font-size: 23px; + color: #a8d46f; +} + +.wok-list-item-status.disabled > .fa:before { + display: block; + width: 19px; + height: 23px; + padding: 0; + border: 0; + content: ""; +} + +.wok-list-cell.disabled span { + color: #999; +} + +.wok-list-action-button-container { + padding-bottom: 16px; +} + +.wok-list-loading-icon-inline { + background: transparent url("/images/theme-default/spin5.svg") no-repeat 50% 50%; + -webkit-animation: spin 3s infinite linear; + -o-animation: spin 3s infinite linear; + animation: spin 3s infinite linear; + height: 16px; + width: 16px; + background-size: 100%; + display: none; + position: absolute; +} + +.generating .wok-list-description { + padding-left: 24px; +} + +.generating .wok-list-loading-icon-inline { + display: block; + position: absolute; + top: 27px; + left: 34px; +} + +.wok-list > ul { + list-style: none; + padding: 0; +} + +.wok-list > ul > li, +.wok-list > ul > li * { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } -.wok-list-content tbody tr:hover { +.wok-list > ul > li, +.wok-list > ul > li > label { + width: 100%; +} + +.wok-list > ul > li { + border-top: 1px solid #eee; + background: #fff; + position: relative; + -webkit-transition: background 0.1s ease-in-out; + -o-transition: background 0.1s ease-in-out; + transition: background 0.1s ease-in-out; +} + +.wok-list > ul > li:first-child { + border: 0; +} + +.wok-list > ul > li:nth-of-type(even) { + background: #fcfcfc; +} + +.wok-list > ul > li.selected { + background: #ddd; +} + +.wok-list > ul > li > label { + cursor: pointer !important; + text-decoration: none; + margin-bottom: 0; + padding-bottom: 5px; +} + +.wok-list > ul > li > label:hover { text-decoration: underline; - cursor: pointer; } -.wok-list-content tbody tr.generating:hover { +.wok-list > ul > li.generating > label:hover { text-decoration: none; cursor: default; } -.wok-list-content tbody tr.selected { - background: #ddd; +.wok-list > ul > li > input[type=checkbox] { + left: -15px; } -span.wok-repository-status.disabled { - display: none; +.wok-list > ul > li > input[type=checkbox].wok-checkbox + label:before { + float: left; + height: 30px; + margin-top: 13px; } -.wok-list-cell.disabled span { - color: #999; +.wok-list-action-button-container { + background: #fff; + z-index: 1; + position: relative; + -webkit-box-shadow: 0 20px 20px -20px rgba(0, 0, 0, 0.4); + box-shadow: 0 20px 20px -20px rgba(0, 0, 0, 0.4); } -.wok-single-button { - padding-bottom: 16px; - margin-top: -11px; +.mobile-action { + width: 100%; } -.generating .wok-list-description { - padding-left: 24px; +.mobile-action .btn { + width: 100%; + height: 40px; + border-radius: 0; } -.generating .wok-list-loading-icon-inline { - background: transparent url("/images/theme-default/spin5.svg") no-repeat 50% 50%; - -webkit-animation: spin 3s infinite linear; - -o-animation: spin 3s infinite linear; - animation: spin 3s infinite linear; - height: 16px; - width: 16px; - background-size: 100%; - display: block; - position: absolute; +.mobile-action > .btn { + border-radius: 3px; +} + +.mobile-action.open > .btn { + border-radius: 3px 3px 0 0; +} + +.mobile-action .btn span.mobile-action-label { + font-weight: 600; +} + +.mobile-action .btn span.mobile-action-count { + font-weight: 300; +} + +.mobile-action .btn span.mobile-action-count strong { + font-weight: 600; + font-size: 11pt; +} + +.mobile-action .dropdown-menu { + width: 100%; + border: 0; + box-shadow: none; + background: transparent; + padding: 0; + margin: 0; + border-radius: 0; +} + +.mobile-action.open .dropdown-menu .btn { + border-radius: 0; +} + +.mobile-action.open .dropdown-menu li:last-child .btn { + border-radius: 0 0 3px 3px; +} + +.mobile-action .dropdown-menu li > .btn.disabled, +.mobile-action .dropdown-menu li > .btn[disabled] { + opacity: 1; + background: #585758; + border-color: #585758; + color: #ddd; +} + +@media (min-width: 992px) { + .wok-list-action-button-container { + -webkit-box-shadow: none; + box-shadow: none; + } + .wok-list-action-button-container .dropdown-toggle { + display: none; + } + .wok-list-action-button-container .mobile-action { + position: static; + height: 40px; + } + .wok-list-action-button-container .mobile-action .btn { + width: auto; + } + .wok-list-action-button-container .mobile-action li:first-child .btn { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + .wok-list-action-button-container .mobile-action li:last-child .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 !important; + border-top-right-radius: 3px !important; + border-bottom-right-radius: 3px; + } + .wok-list-action-button-container > .dropdown.mobile-action > .dropdown-menu { + display: block; + vertical-align: middle; + position: absolute; + top: 0; + } + .wok-list-action-button-container > .dropdown.mobile-action > .dropdown-menu > li { + display: inline-block; + } + .wok-list > ul > li > input[type=checkbox].wok-checkbox + label:before { + display: none; + } + .wok-list > ul > li > input[type=checkbox].wok-checkbox:focus + label { + outline: auto 5px #66afe9; + outline: auto 5px -webkit-focus-ring-color; + } } .grid-control { @@ -948,6 +1126,7 @@ input[type=checkbox].wok-checkbox + label:before { input[type=checkbox].wok-checkbox:checked + label:before { content: "\f14a"; letter-spacing: 8px; + margin-right: 0.9px; } input[type=radio].wok-radio + label:before { @@ -1105,7 +1284,7 @@ input[type=radio].wok-radio + label { /* * Project Wok * -* Copyright IBM Corp, 2015-2016 +* Copyright IBM Corp, 2016 * * Code derived from Project Kimchi * diff --git a/ui/js/src/wok.list.js b/ui/js/src/wok.list.js index 7d8e27c..f40b2e2 100644 --- a/ui/js/src/wok.list.js +++ b/ui/js/src/wok.list.js @@ -24,6 +24,7 @@ wok.widget.List = function(opts) { wok.widget.List.prototype = (function() { "use strict"; + var htmlStr = [ '<div id="{id}-section" class="panel panel-default">', '<div class="panel-heading">', @@ -39,13 +40,19 @@ wok.widget.List.prototype = (function() { '</button></p>', '</div>', '</div>', - '<div id="{id}-btn-group" class="btn-group wok-single-button hidden">', - + '<div id="{id}-action-group" class="wok-list-action-button-container">', + '<div class="dropdown mobile-action">', + '<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">', + '<span class="mobile-action-label">Actions</span>', // TODO: Replace with i18n string + '</button>', + '<ul class="dropdown-menu" role="menu">', + '</ul>', + '</div>', '</div>', '<div id="{id}" class="row clearfix">', '<div class="wok-list-content">', - '<table class="wok-list-table table table-striped" id="list">', - '</table>', + '<div class="wok-list" id="list">', + '</div>', '</div>', '</div>', '<div class="wok-list-mask hidden">', @@ -80,112 +87,95 @@ wok.widget.List.prototype = (function() { return (result); }; - - var fillButton = function(btnContainer){ - var addOrGenerateBtn = this.opts.toolbarButtons[0]; - var singleBtnHTML = [ - '<a class="btn btn-primary" href="#"', (addOrGenerateBtn.id ? (' id="' + addOrGenerateBtn.id + '"') : ''),' role="button">', - addOrGenerateBtn.class ? ('<i class="' + addOrGenerateBtn.class) + '"></i> ' : '', - addOrGenerateBtn.label, - '</a>' - ].join(''); - var singleBtn = $(singleBtnHTML).appendTo(btnContainer); - $(singleBtn).click(function(e) { - e.preventDefault(); - }); - addOrGenerateBtn.onClick && singleBtn.on('click', addOrGenerateBtn.onClick); + var fillButtons = function(btnContainer){ + var toolbarButtons = this.opts.toolbarButtons; + $.each(toolbarButtons, function(i, button) { + var btnHTML = [ + '<li class="', + (button.critical === true ? 'critical' : ''), + ,'">', + '<btn data-dismiss="modal"', + (button.id ? (' id="' + button.id + '"') : ''), + ' class="btn btn-primary"', + (button.disabled === true ? ' disabled="disabled"' : ''), + '">', + button.class ? ('<i class="' + button.class) + '"></i> ' : ' ', + button.label, + '</btn>', + '</li>' + ].join(''); + var btnNode = $(btnHTML).appendTo(btnContainer); + button.onClick && btnNode.on('click', button.onClick); + }); }; var fillBody = function(container, fields) { - - var toolbarButtons = this.opts.toolbarButtons; - var actionDropdownHtml; var data = this.data; - var tbody = ($('tbody', container).length && $('tbody', container)) || $('<tbody></tbody>').appendTo(container); + var tbody = ($('ul', container).length && $('ul', container)) || $('<ul></ul>').appendTo(container); tbody.empty(); if (typeof data !== 'undefined' && data.length > 0) { $.each(data, function(i, row) { - var rowNode = $('<tr></tr>').appendTo(tbody); + var rowNode = $('<li></li>').appendTo(tbody); var columnNodeHTML; var columnData = ''; var state = ''; var styleClass = ''; - if (toolbarButtons) { - actionDropdownHtml = [ - '<td>', - '<div class="dropdown menu-flat">', - '<button id="wok-dropdown-button-', i, '" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">', - '<span class="edit-alt"></span>Actions<span class="caret"></span>', - '</button>', - '<ul class="dropdown-menu" role="menu" aria-labelledby="action-dropdown-menu-', i, '">', - '</ul>', - '</div>', - '</td>' - ].join(''); - } + var checkboxName = $('ul', container).parent().parent().parent().attr('id') + '-check' || $(container).parent().parent().parent().attr('id') + '-check'; $.each(fields, function(fi, field) { var value = getValue(field.name, row); if (field.type === 'status' && field.name === 'enabled') { styleClass = (value === true ? '' : ' disabled'); state = [ - '<span class="wok-repository-status ', + '<span class="wok-list-item-status ', value === true ? 'enabled' : 'disabled', - '"><i class="fa fa-power-off"></i></span>' + '"><i class="fa fa-power-off"></i><span class="sr-only">', + value === true ? 'Enabled' : 'Disabled', + '</span></span>' ].join(''); } - columnData += (field.type === 'name') ? ('<span class="wok-list-name">' + value.toString() + '</span>') : (field.type !== 'status' ? '<span class="wok-list-loading-icon-inline"></span><span class="wok-list-description">' + value.toString() + '</span>' : ''); - - }); - columnNodeHTML = [ - '<td>', - '<div class="wok-list-cell', styleClass, '">', state, - columnData, - '</div>', - '</td>' - ].join(''); - $(columnNodeHTML).appendTo(rowNode); - - var actionMenuNode = $(actionDropdownHtml).appendTo(rowNode); - - $.each(toolbarButtons, function(i, button) { - var btnHTML = [ - '<li role="presentation"', button.critical === true ? ' class="critical"' : '', '>', - '<a role="menuitem" tabindex="-1" data-dismiss="modal"', (button.id ? (' id="' + button.id + '"') : ''), (button.disabled === true ? ' class="disabled"' : ''), - '>', - button.class ? ('<i class="' + button.class) + '"></i>' : '', - button.label, - '</a></li>' + columnData += (field.type === 'name') ? ('<span role="status" class="wok-list-loading-icon-inline"></span><span class="wok-list-name '+field.cssClass+'" title="'+field.label+'">'+value.toString()+'</span>') : (field.type !== 'status' ? '<span class="wok-list-description '+field.cssClass+'" title="'+field.label+'">' + value.toString() + '</span>' : ''); + columnNodeHTML = [ + '<input class="wok-checkbox" type="checkbox" name="'+checkboxName+'" id="wok-list-',i+1,'-check" />', + '<label for="wok-list-',i+1,'-check" class="wok-list-cell', styleClass, '">', + state, + columnData, + '</div>', + '</label>' ].join(''); - var btnNode = $(btnHTML).appendTo($('.dropdown-menu', rowNode)); - button.onClick && btnNode.on('click', button.onClick); }); + $(columnNodeHTML).appendTo(rowNode); }); } }; - var stylingRow = function(row, className, add) { - var index = $(row).index() + 1; - $('tr', this.bodyContainer) - .removeClass(className); - if (add === false) { - return; - } - $('tr:nth-child(' + index + ')', this.bodyContainer) - .addClass(className); + var stylingRow = function(grid, className) { + $('li',grid.bodyContainer).removeClass(className); + $.each(grid.selectedIndex, function(){ + var nth = this + 1; + $('li:nth-child('+nth+')',grid.bodyContainer).addClass(className); + }); }; var setBodyListeners = function() { - if (this['opts']['rowSelection'] != 'disabled') { - - $('tr', this.bodyContainer).on('click', { + if (this['opts']['rowSelection'] !== 'disabled') { + $('li:not(.generating) input[type="checkbox"]', this.bodyContainer).on('change', { grid: this - }, function(event) { + },function(event) { var grid = event.data.grid; - if (!$(this).hasClass('generating')) { - grid.selectedIndex = $(this).index(); - stylingRow.call(grid, this, 'selected'); - grid['opts']['onRowSelected'] && grid['opts']['onRowSelected'](); + grid.selectedIndex = []; + $("li :checkbox:checked", this.bodyContainer).map(function() { + return $(this).parent().index(); + }).each(function() { + grid.selectedIndex.push(this); + }); + if ($('.mobile-action-count',grid.buttonActionContainer).length) { + $('.mobile-action-count',grid.buttonActionContainer).remove(); } + if(grid.selectedIndex.length){ + $(grid.buttonActionContainer).append('<span class="mobile-action-count"> ( <strong>'+grid.selectedIndex.length+' item(s)</strong> selected )</span>'); + } + stylingRow.call(grid, grid, 'selected'); + grid['opts']['onRowSelected'] && grid['opts']['onRowSelected'](); }); } }; @@ -197,7 +187,13 @@ wok.widget.List.prototype = (function() { }; var getSelected = function() { - return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null; + var selectedItems = []; + for (var i = 0; i < this.selectedIndex.length; i++ ){ + var value = this.selectedIndex[i]; + selectedItems.push(this.data[value]); + } + // return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null; + return selectedItems; }; var showMessage = function(msg) { @@ -255,11 +251,17 @@ wok.widget.List.prototype = (function() { titleNode = $('<h3 class="panel-title">' + title + '</h3>').appendTo(titleContainer); } - var bodyContainer = $('.wok-list-table.table.table-striped', domNode); + var bodyContainer = $('.wok-list', domNode); this.bodyContainer = bodyContainer; - var singleButtonContainer = $('.wok-single-button', domNode); - this.singleButtonContainer = singleButtonContainer; + var selectButtonContainer = $('.wok-list-action-button-container', domNode); + this.selectButtonContainer = selectButtonContainer; + + var buttonActionGroupContainer = $('.wok-list-action-button-container .dropdown-menu', domNode); + this.buttonActionGroupContainer = buttonActionGroupContainer; + + var buttonActionContainer = $('.mobile-action .dropdown-toggle.btn', domNode); + this.buttonActionContainer = buttonActionContainer; var gridBody = $('.wok-list-content', domNode); this.gridBody = gridBody; @@ -270,8 +272,7 @@ wok.widget.List.prototype = (function() { var messageNode = $('.wok-list-message', domNode); this.messageNode = messageNode; - - fillButton.call(this,this.singleButtonContainer); + fillButtons.call(this,this.buttonActionGroupContainer); $('.retry-button', domNode).on('click', { grid: this @@ -279,7 +280,6 @@ wok.widget.List.prototype = (function() { event.data.grid.reload(); }); - }; return { @@ -299,4 +299,4 @@ wok.widget.List.prototype = (function() { reload: reload, showMessage: showMessage }; -})(); +})(); \ No newline at end of file -- 1.9.3

Tested-by: Socorro Stoppler <socorro@linux.vnet.ibm.com> On 04/25/2016 12:29 PM, sguimaraes943@gmail.com wrote:
From: Samuel Guimarães <sguimaraes943@gmail.com>
This patch updates wok.list.js widget to allow multiple selection in Debug Reports and Repositories in Gingerbase. Another patch was sent to Ginger Dev List covering the changes necessary. This patch also includes changes in Wok SCSS and CSS aiming accessibility and responsive design.
Samuel Guimarães (1): Changes in wok.list.js widget to allow multiple selection
ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-)

Hi Samuel, I don't like the idea to have only the color as reference to know which element is selected. Based on the accessibility issues open, the color must not be the unique reference to user decide on what to do. Said that, my suggestion is, in addition to color, add a check icon or something like that. Regards, Aline Manera On 04/25/2016 04:29 PM, sguimaraes943@gmail.com wrote:
From: Samuel Guimarães <sguimaraes943@gmail.com>
This patch updates wok.list.js widget to allow multiple selection in Debug Reports and Repositories in Gingerbase. Another patch was sent to Ginger Dev List covering the changes necessary. This patch also includes changes in Wok SCSS and CSS aiming accessibility and responsive design.
Samuel Guimarães (1): Changes in wok.list.js widget to allow multiple selection
ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-)

Ok, I'll add other WAI-ARIA attributes to make clear to screen reader software how many items are selected in the desktop version (the screen readers already tell the user if an item is selected or not, each items is wrapped inside label element with a for attribute set to an unique checkbox id) As for visual feedback, should we display the checkbox like in low screen mode? Samuel 2016-04-25 18:39 GMT-03:00 Aline Manera <alinefm@linux.vnet.ibm.com>:
Hi Samuel,
I don't like the idea to have only the color as reference to know which element is selected. Based on the accessibility issues open, the color must not be the unique reference to user decide on what to do. Said that, my suggestion is, in addition to color, add a check icon or something like that.
Regards, Aline Manera
On 04/25/2016 04:29 PM, sguimaraes943@gmail.com wrote:
From: Samuel Guimarães <sguimaraes943@gmail.com>
This patch updates wok.list.js widget to allow multiple selection in Debug Reports and Repositories in Gingerbase. Another patch was sent to Ginger Dev List covering the changes necessary. This patch also includes changes in Wok SCSS and CSS aiming accessibility and responsive design.
Samuel Guimarães (1): Changes in wok.list.js widget to allow multiple selection
ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-)

On 04/27/2016 11:27 AM, Samuel Guimarães wrote:
Ok,
I'll add other WAI-ARIA attributes to make clear to screen reader software how many items are selected in the desktop version (the screen readers already tell the user if an item is selected or not, each items is wrapped inside label element with a for attribute set to an unique checkbox id)
As for visual feedback, should we display the checkbox like in low screen mode?
Yeap! Sounds good to me!
Samuel
2016-04-25 18:39 GMT-03:00 Aline Manera <alinefm@linux.vnet.ibm.com <mailto:alinefm@linux.vnet.ibm.com>>:
Hi Samuel,
I don't like the idea to have only the color as reference to know which element is selected. Based on the accessibility issues open, the color must not be the unique reference to user decide on what to do. Said that, my suggestion is, in addition to color, add a check icon or something like that.
Regards, Aline Manera
On 04/25/2016 04:29 PM, sguimaraes943@gmail.com <mailto:sguimaraes943@gmail.com> wrote:
From: Samuel Guimarães <sguimaraes943@gmail.com <mailto:sguimaraes943@gmail.com>>
This patch updates wok.list.js widget to allow multiple selection in Debug Reports and Repositories in Gingerbase. Another patch was sent to Ginger Dev List covering the changes necessary. This patch also includes changes in Wok SCSS and CSS aiming accessibility and responsive design.
Samuel Guimarães (1): Changes in wok.list.js widget to allow multiple selection
ui/css/bootstrap.custom.css | 8 +- ui/css/src/modules/_buttons.scss | 8 + ui/css/src/modules/_wok-forms.scss | 1 + ui/css/src/modules/_wok-grid.scss | 254 +++++++++++++++++++++++++++----- ui/css/src/modules/_wok-variables.scss | 4 +- ui/css/wok.css | 257 ++++++++++++++++++++++++++++----- ui/js/src/wok.list.js | 174 +++++++++++----------- 7 files changed, 538 insertions(+), 168 deletions(-)
participants (4)
-
Aline Manera
-
Samuel Guimarães
-
sguimaraes943@gmail.com
-
Socorro Stoppler