If a range filter action had an empty from/to field, the range filter could still be applied. This was confusing, as an invalid filter range caused all records to display, even though a filter appeared to have been applied (by the highlighted state of the filter button).
Change the state of the "Apply" button, disabling it if the radio button for a range filter action is selected but the range is incomplete (from or to field is empty). When a non-range filter is selected, the "Apply" button always enable the "Apply" button. [YOCTO #8738] Signed-off-by: Elliot Smith <[email protected]> --- bitbake/lib/toaster/toastergui/static/js/table.js | 77 ++++++++++++++++------ .../toastergui/templates/toastertable-filter.html | 4 +- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/bitbake/lib/toaster/toastergui/static/js/table.js b/bitbake/lib/toaster/toastergui/static/js/table.js index 9384386..87cac60 100644 --- a/bitbake/lib/toaster/toastergui/static/js/table.js +++ b/bitbake/lib/toaster/toastergui/static/js/table.js @@ -397,6 +397,8 @@ function tableInit(ctx){ * filterActionData: (object) * filterActionData.count: (number) The number of items this filter will * show when selected + * + * NB this triggers a filtervalue event each time its radio button is checked */ function createActionRadio(filterName, filterActionData) { var hasNoRecords = (Number(filterActionData.count) == 0); @@ -420,7 +422,17 @@ function tableInit(ctx){ '</label>' + '</div>'; - return $(actionStr); + var action = $(actionStr); + + // fire the filtervalue event from this action when the radio button + // is active so that the apply button can be enabled + action.find('[type="radio"]').change(function () { + if ($(this).is(':checked')) { + action.trigger('filtervalue', 'on'); + } + }); + + return action; } /** @@ -437,6 +449,8 @@ function tableInit(ctx){ * datetime format * filterActionData.min: (string) minimum date for the pickers, ISO 8601 * datetime + * + * NB this triggers a filtervalue event each time its radio button is checked */ function createActionDateRange(filterName, filterValue, filterActionData) { var action = $('<div class="radio">' + @@ -492,9 +506,26 @@ function tableInit(ctx){ inputTo.val(selectedTo); // set filter_value based on date pickers when - // one of their values changes + // one of their values changes; if either from or to are unset, + // the new value is null; + // this triggers a 'filter_value-change' event on the action's element, + // which is used to determine the disabled/enabled state of the "Apply" + // button var changeHandler = function () { - value.val(inputFrom.val() + ',' + inputTo.val()); + var fromValue = inputFrom.val(); + var toValue = inputTo.val(); + + var newValue = undefined; + if (fromValue !== '' && toValue !== '') { + newValue = fromValue + ',' + toValue; + } + + value.val(newValue); + + // if this action is selected, fire an event for the new range + if (radio.is(':checked')) { + action.trigger('filtervalue', newValue); + } }; inputFrom.change(changeHandler); @@ -503,6 +534,10 @@ function tableInit(ctx){ // check the associated radio button on clicking a date picker var checkRadio = function () { radio.prop('checked', 'checked'); + + // checking the radio button this way doesn't cause the "change" + // event to fire, so we manually call the changeHandler + changeHandler(); }; inputFrom.focus(checkRadio); @@ -518,23 +553,9 @@ function tableInit(ctx){ inputFrom.datepicker('option', 'maxDate', inputTo.val()); }); - // if the radio button is checked and one or both of the datepickers are - // empty, populate them with today's date - radio.change(function () { - var now = new Date(); - - if (inputFrom.val() === '') { - inputFrom.datepicker('setDate', now); - } - - if (inputTo.val() === '') { - inputTo.datepicker('setDate', now); - } - - // setting the date like this doesn't fire the changeHandler to - // update the filter_value, so do that manually instead - changeHandler() - }); + // checking the radio input causes the "Apply" button disabled state to + // change, depending on which from/to dates are supplied + radio.change(changeHandler); return action; } @@ -589,6 +610,16 @@ function tableInit(ctx){ queryset on the table */ var filterActionRadios = $('#filter-actions-' + ctx.tableName); + var filterApplyBtn = $('[data-role="filter-apply"]'); + + var setApplyButtonState = function (e, filterActionValue) { + if (filterActionValue !== undefined) { + filterApplyBtn.removeAttr('disabled'); + } + else { + filterApplyBtn.attr('disabled', 'disabled'); + } + }; $('#filter-modal-title-' + ctx.tableName).text(filterData.title); @@ -624,10 +655,14 @@ function tableInit(ctx){ if ((tableParams.filter && tableParams.filter === radioInput.val()) || filterActionData.action_name == 'all') { - radioInput.attr("checked", "checked"); + radioInput.prop("checked", "checked"); } filterActionRadios.append(action); + + // if the action's filter_value changes but is falsy, disable + // the "Apply" button + action.on('filtervalue', setApplyButtonState); } } diff --git a/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html b/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html index 7c8dc49..4d28793 100644 --- a/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html +++ b/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html @@ -10,7 +10,9 @@ <span id="filter-actions-{{table_name}}"></span> </div> <div class="modal-footer"> - <button class="btn btn-primary" type="submit">Apply</button> + <button class="btn btn-primary" type="submit" data-role="filter-apply"> + Apply + </button> </div> </form> </div> -- Elliot Smith Software Engineer Intel OTC --------------------------------------------------------------------- Intel Corporation (UK) Limited Registered No. 1134945 (England) Registered Office: Pipers Way, Swindon SN3 1RJ VAT No: 860 2173 47 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -- _______________________________________________ toaster mailing list [email protected] https://lists.yoctoproject.org/listinfo/toaster
