From 77259b5d1fffff59aa5ad71e9e3a14a8084e838b Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 15 May 2014 12:29:17 +0100 Subject: Rework of my pull request #18: * Implement "go to next" buttons in pyfile UI * Improve filter on main UI to persist over page reloads * Hide totals table footer if hiding any rows, as values will be inaccurate * Implement live filtering of index table rows * Upgrade to jQuery 1.11.1 --- coverage/htmlfiles/coverage_html.js | 142 ++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'coverage/htmlfiles/coverage_html.js') diff --git a/coverage/htmlfiles/coverage_html.js b/coverage/htmlfiles/coverage_html.js index b24006d..d7423c8 100644 --- a/coverage/htmlfiles/coverage_html.js +++ b/coverage/htmlfiles/coverage_html.js @@ -35,6 +35,146 @@ coverage.wire_up_help_panel = function () { }); }; +// Create the events for the filter box. +coverage.wire_up_filter = function () { + $("#filter").on("keyup change", $.debounce(150, function (event) { + var filter_value = $(this).val(); + + if (filter_value === "") { + // Filter box is empty, remove all filtering + $("table.index tr").removeClass("hidden"); + + // Hide placeholder, show table + if ($("#no_rows").length > 0) { + $("#no_rows").hide(); + } + $("table.index").show(); + + } else { + // Filter table items by value + var hide = $([]); + var show = $([]); + + // - Compile elements to hide / show + $.each($("table.index tr td.name a"), function () { + var element = $(this).parents("tr"); + + if ($(this).text().indexOf(filter_value) === -1) { + // hide + hide = hide.add(element); + + } else { + // show + show = show.add(element); + } + }); + + // - Perform DOM manipulation + hide.addClass("hidden"); + show.removeClass("hidden"); + + // - Show placeholder if no rows will be displayed + if ($("#no_rows").length > 0) { + if (show.length === 0) { + // Show placeholder, hide table + $("#no_rows").show(); + $("table.index").hide(); + + } else { + // Hide placeholder, show table + $("#no_rows").hide(); + $("table.index").show(); + } + } + + // Hide totals table footer if hiding any rows, as values will be inaccurate + if (hide.length > 0) { + // Hide footer + $("table.index tfoot tr").addClass("hidden"); + + } else { + // Show footer + $("table.index tfoot tr").removeClass("hidden"); + } + } + })); + + // Trigger change event on setup, to force filter on page refresh (filter value may still be present) + $("#filter").trigger("change"); +}; + +// Create the events for the next buttons. +coverage.wire_up_next_buttons = function () { + // Define next button handler. + function next_handler(event) { + event.preventDefault(); + + // Define selector based on clicked button. + var button_id = $(this).attr("id"); + var selector; + + if (button_id == "next_run") { + selector = ".run"; + + } else if (button_id == "next_missing") { + selector = ".mis"; + + } else if (button_id == "next_excluded") { + selector = ".exc"; + + } else { + return false; + } + + // Go to first line, or next in sequence? + var target; + var previous_target = $(this).data("target"); + + if (previous_target === undefined) { + // First click, get first matching line. + target = $("p[id^='t']" + selector).first(); + + } else { + // Get next matching (non-contiguous) line. + var old_target = previous_target; + target = old_target.nextAll("p[id^='t']" + selector).first(); + + while ((parseInt(target.attr("id").match(/\d+/)[0]) - parseInt(old_target.attr("id").match(/\d+/)[0])) === 1) { + old_target = target; + target = old_target.nextAll("p[id^='t']" + selector).first(); + } + } + + // Set highlight styling and arrow indicator. + $("p[id^='n'].highlight").removeClass("highlight"); + $("p[id^='n'] span.indicator").remove(); + + $("p#n" + target.attr("id").match(/\d+/)[0]) + .prepend( + $("") + .addClass("indicator") + .html("◊") + ) + .addClass("highlight") + + // Scroll to line. + $("html, body").animate({ + scrollTop: (target.position().top - ($("#header").outerHeight() + 100)) + }, 100); + + // Save target reference in button element for next click. + $(this).data("target", target); + + return false; + } + + + // Wire up buttons to handler. + $("#header .stats button") + .off("click.next") + .on("click.next", next_handler); +}; + // Loaded on index.html coverage.index_ready = function ($) { // Look for a cookie containing previous sort settings: @@ -95,6 +235,7 @@ coverage.index_ready = function ($) { coverage.assign_shortkeys(); coverage.wire_up_help_panel(); + coverage.wire_up_filter(); // Watch for page unload events so we can save the final sort settings: $(window).unload(function () { @@ -129,6 +270,7 @@ coverage.pyfile_ready = function ($) { coverage.assign_shortkeys(); coverage.wire_up_help_panel(); + coverage.wire_up_next_buttons(); }; coverage.toggle_lines = function (btn, cls) { -- cgit v1.2.1 From d163c1028f7c997ca1d9d9e89631a5d5fb58c4c4 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 15 May 2014 13:06:53 +0100 Subject: * Respond to pull request #18 comments --- coverage/htmlfiles/coverage_html.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'coverage/htmlfiles/coverage_html.js') diff --git a/coverage/htmlfiles/coverage_html.js b/coverage/htmlfiles/coverage_html.js index d7423c8..2800dd4 100644 --- a/coverage/htmlfiles/coverage_html.js +++ b/coverage/htmlfiles/coverage_html.js @@ -50,12 +50,13 @@ coverage.wire_up_filter = function () { } $("table.index").show(); - } else { + } + else { // Filter table items by value var hide = $([]); var show = $([]); - // - Compile elements to hide / show + // Compile elements to hide / show $.each($("table.index tr td.name a"), function () { var element = $(this).parents("tr"); @@ -63,24 +64,26 @@ coverage.wire_up_filter = function () { // hide hide = hide.add(element); - } else { + } + else { // show show = show.add(element); } }); - // - Perform DOM manipulation + // Perform DOM manipulation hide.addClass("hidden"); show.removeClass("hidden"); - // - Show placeholder if no rows will be displayed + // Show placeholder if no rows will be displayed if ($("#no_rows").length > 0) { if (show.length === 0) { // Show placeholder, hide table $("#no_rows").show(); $("table.index").hide(); - } else { + } + else { // Hide placeholder, show table $("#no_rows").hide(); $("table.index").show(); @@ -92,7 +95,8 @@ coverage.wire_up_filter = function () { // Hide footer $("table.index tfoot tr").addClass("hidden"); - } else { + } + else { // Show footer $("table.index tfoot tr").removeClass("hidden"); } @@ -115,14 +119,14 @@ coverage.wire_up_next_buttons = function () { if (button_id == "next_run") { selector = ".run"; - - } else if (button_id == "next_missing") { + } + else if (button_id == "next_missing") { selector = ".mis"; - - } else if (button_id == "next_excluded") { + } + else if (button_id == "next_excluded") { selector = ".exc"; - - } else { + } + else { return false; } @@ -133,8 +137,8 @@ coverage.wire_up_next_buttons = function () { if (previous_target === undefined) { // First click, get first matching line. target = $("p[id^='t']" + selector).first(); - - } else { + } + else { // Get next matching (non-contiguous) line. var old_target = previous_target; target = old_target.nextAll("p[id^='t']" + selector).first(); -- cgit v1.2.1 From a35a7dda343ce5377e8f0e7be38e37f5ae17b378 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Thu, 15 May 2014 13:35:28 +0100 Subject: * Do not try to jump to line if we can't find a matching target. --- coverage/htmlfiles/coverage_html.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'coverage/htmlfiles/coverage_html.js') diff --git a/coverage/htmlfiles/coverage_html.js b/coverage/htmlfiles/coverage_html.js index 2800dd4..fdee551 100644 --- a/coverage/htmlfiles/coverage_html.js +++ b/coverage/htmlfiles/coverage_html.js @@ -149,25 +149,27 @@ coverage.wire_up_next_buttons = function () { } } - // Set highlight styling and arrow indicator. - $("p[id^='n'].highlight").removeClass("highlight"); - $("p[id^='n'] span.indicator").remove(); + if (target.length > 0) { + // Set highlight styling and arrow indicator. + $("p[id^='n'].highlight").removeClass("highlight"); + $("p[id^='n'] span.indicator").remove(); - $("p#n" + target.attr("id").match(/\d+/)[0]) - .prepend( + $("p#n" + target.attr("id").match(/\d+/)[0]) + .prepend( $("") .addClass("indicator") .html("◊") ) - .addClass("highlight") + .addClass("highlight"); - // Scroll to line. - $("html, body").animate({ - scrollTop: (target.position().top - ($("#header").outerHeight() + 100)) - }, 100); + // Scroll to line. + $("html, body").animate({ + scrollTop: (target.position().top - ($("#header").outerHeight() + 100)) + }, 100); - // Save target reference in button element for next click. - $(this).data("target", target); + // Save target reference in button element for next click. + $(this).data("target", target); + } return false; } -- cgit v1.2.1 From 3587bb6df97533fce78553c480c737bd79164520 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Mon, 22 Sep 2014 12:05:15 +0100 Subject: Address comments from pull request 34 (https://bitbucket.org/ned/coveragepy/pull-request/34/rework-of-my-pull-request-18/diff): * Remove fixed header and header buttons in file details page. * Add dynamically summing footer values. --- coverage/htmlfiles/coverage_html.js | 173 +++++++++++++++--------------------- 1 file changed, 73 insertions(+), 100 deletions(-) (limited to 'coverage/htmlfiles/coverage_html.js') diff --git a/coverage/htmlfiles/coverage_html.js b/coverage/htmlfiles/coverage_html.js index fdee551..88a0cd8 100644 --- a/coverage/htmlfiles/coverage_html.js +++ b/coverage/htmlfiles/coverage_html.js @@ -4,7 +4,7 @@ coverage = {}; -// Find all the elements with shortkey_* class, and use them to assign a shotrtcut key. +// Find all the elements with shortkey_* class, and use them to assign a shortcut key. coverage.assign_shortkeys = function () { $("*[class*='shortkey_']").each(function (i, e) { $.each($(e).attr("class").split(" "), function (i, c) { @@ -37,27 +37,50 @@ coverage.wire_up_help_panel = function () { // Create the events for the filter box. coverage.wire_up_filter = function () { + // Cache elements. + var table = $("table.index"); + var table_rows = table.find("tbody tr"); + var table_row_names = table_rows.find("td.name a"); + var table_cells = { + 2: table_rows.find('td:nth-child(2)'), + 3: table_rows.find('td:nth-child(3)'), + 4: table_rows.find('td:nth-child(4)'), + 5: table_rows.find('td:nth-child(5)') + }; + var no_rows = $("#no_rows"); + + // Create a duplicate table footer that we can modify with dynamic summed values. + var table_footer = $("table.index tfoot tr"); + var table_dynamic_footer = table_footer.clone(); + table_dynamic_footer.attr('class', 'total_dynamic hidden'); + table_footer.after(table_dynamic_footer); + + // Observe filter keyevents. $("#filter").on("keyup change", $.debounce(150, function (event) { var filter_value = $(this).val(); if (filter_value === "") { - // Filter box is empty, remove all filtering - $("table.index tr").removeClass("hidden"); + // Filter box is empty, remove all filtering. + table_rows.removeClass("hidden"); - // Hide placeholder, show table - if ($("#no_rows").length > 0) { - $("#no_rows").hide(); + // Show standard footer, hide dynamic footer. + table_footer.removeClass("hidden"); + table_dynamic_footer.addClass("hidden"); + + // Hide placeholder, show table. + if (no_rows.length > 0) { + no_rows.hide(); } - $("table.index").show(); + table.show(); } else { - // Filter table items by value + // Filter table items by value. var hide = $([]); var show = $([]); - // Compile elements to hide / show - $.each($("table.index tr td.name a"), function () { + // Compile elements to hide / show. + $.each(table_row_names, function () { var element = $(this).parents("tr"); if ($(this).text().indexOf(filter_value) === -1) { @@ -71,116 +94,67 @@ coverage.wire_up_filter = function () { } }); - // Perform DOM manipulation + // Perform DOM manipulation. hide.addClass("hidden"); show.removeClass("hidden"); - // Show placeholder if no rows will be displayed - if ($("#no_rows").length > 0) { + // Show placeholder if no rows will be displayed. + if (no_rows.length > 0) { if (show.length === 0) { - // Show placeholder, hide table - $("#no_rows").show(); - $("table.index").hide(); + // Show placeholder, hide table. + no_rows.show(); + table.hide(); } else { - // Hide placeholder, show table - $("#no_rows").hide(); - $("table.index").show(); + // Hide placeholder, show table. + no_rows.hide(); + table.show(); } } - // Hide totals table footer if hiding any rows, as values will be inaccurate + // Manage dynamic header: if (hide.length > 0) { - // Hide footer - $("table.index tfoot tr").addClass("hidden"); + // Calculate new dynamic sum values based on visible rows. + for (var column in table_cells) { + // Calculate summed value. + var tmp = 0; + $.each(table_cells[column].filter(':visible'), function () { + tmp += parseInt(this.innerHTML, 10); + }); + + // Get footer cell element. + var footer_cell = table_dynamic_footer.find('td:nth-child(' + column + ')'); + + // Set value into dynamic footer cell element. + if (column === '5') { + // Value of 5th "coverage" column is expressed as a percentage + footer_cell.text(parseInt((tmp / show.length), 10) + '%'); + + } else { + footer_cell.text(tmp); + } + } + + + // Hide standard footer, show dynamic footer. + table_footer.addClass("hidden"); + table_dynamic_footer.removeClass("hidden"); } else { - // Show footer - $("table.index tfoot tr").removeClass("hidden"); + // Show standard footer, hide dynamic footer. + table_footer.removeClass("hidden"); + table_dynamic_footer.addClass("hidden"); } } })); - // Trigger change event on setup, to force filter on page refresh (filter value may still be present) + // Trigger change event on setup, to force filter on page refresh + // (filter value may still be present). $("#filter").trigger("change"); }; -// Create the events for the next buttons. -coverage.wire_up_next_buttons = function () { - // Define next button handler. - function next_handler(event) { - event.preventDefault(); - - // Define selector based on clicked button. - var button_id = $(this).attr("id"); - var selector; - - if (button_id == "next_run") { - selector = ".run"; - } - else if (button_id == "next_missing") { - selector = ".mis"; - } - else if (button_id == "next_excluded") { - selector = ".exc"; - } - else { - return false; - } - - // Go to first line, or next in sequence? - var target; - var previous_target = $(this).data("target"); - - if (previous_target === undefined) { - // First click, get first matching line. - target = $("p[id^='t']" + selector).first(); - } - else { - // Get next matching (non-contiguous) line. - var old_target = previous_target; - target = old_target.nextAll("p[id^='t']" + selector).first(); - - while ((parseInt(target.attr("id").match(/\d+/)[0]) - parseInt(old_target.attr("id").match(/\d+/)[0])) === 1) { - old_target = target; - target = old_target.nextAll("p[id^='t']" + selector).first(); - } - } - - if (target.length > 0) { - // Set highlight styling and arrow indicator. - $("p[id^='n'].highlight").removeClass("highlight"); - $("p[id^='n'] span.indicator").remove(); - - $("p#n" + target.attr("id").match(/\d+/)[0]) - .prepend( - $("") - .addClass("indicator") - .html("◊") - ) - .addClass("highlight"); - - // Scroll to line. - $("html, body").animate({ - scrollTop: (target.position().top - ($("#header").outerHeight() + 100)) - }, 100); - - // Save target reference in button element for next click. - $(this).data("target", target); - } - - return false; - } - - - // Wire up buttons to handler. - $("#header .stats button") - .off("click.next") - .on("click.next", next_handler); -}; - // Loaded on index.html coverage.index_ready = function ($) { // Look for a cookie containing previous sort settings: @@ -276,7 +250,6 @@ coverage.pyfile_ready = function ($) { coverage.assign_shortkeys(); coverage.wire_up_help_panel(); - coverage.wire_up_next_buttons(); }; coverage.toggle_lines = function (btn, cls) { -- cgit v1.2.1