aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--templates/web/base/alert/list-ajax.html2
-rw-r--r--templates/web/base/alert/list.html2
-rwxr-xr-xtemplates/web/base/around/display_location.html1
-rw-r--r--templates/web/base/js/translation_strings.html3
-rw-r--r--templates/web/base/report/_inspect.html7
-rw-r--r--templates/web/base/report/nearby.html2
-rw-r--r--templates/web/base/report/new/duplicate_suggestions.html42
-rw-r--r--templates/web/base/report/new/fill_in_details.html2
-rw-r--r--templates/web/base/report/new/form_report.html1
-rw-r--r--web/cobrands/fixmystreet/fixmystreet.js2
-rw-r--r--web/cobrands/fixmystreet/staff.js80
-rw-r--r--web/cobrands/sass/_base.scss71
-rw-r--r--web/js/duplicates.js206
-rw-r--r--web/js/map-OpenLayers.js8
15 files changed, 338 insertions, 94 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7d5d4bb6..abe507e60 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
## Releases
* Unreleased
+ - New features:
+ - (Optional) auto-suggestion of similar nearby problems,
+ while reporting, to discourage duplicate reports. #2386
- Front end improvements:
- Track map state in URL to make sharing links easier. #2242
- Admin improvements:
diff --git a/templates/web/base/alert/list-ajax.html b/templates/web/base/alert/list-ajax.html
index 639af6f07..5da71b58c 100644
--- a/templates/web/base/alert/list-ajax.html
+++ b/templates/web/base/alert/list-ajax.html
@@ -4,6 +4,6 @@
%]
[% END %]
-<div id="alerts">
+<div id="alerts" class="js-alert-list">
[% INCLUDE 'alert/_list.html' %]
</div>
diff --git a/templates/web/base/alert/list.html b/templates/web/base/alert/list.html
index 385cd7d32..14215b65d 100644
--- a/templates/web/base/alert/list.html
+++ b/templates/web/base/alert/list.html
@@ -32,7 +32,7 @@
</div>
[% END %]
-<form id="alerts" name="alerts" method="post" action="/alert/subscribe">
+<form id="alerts" class="js-alert-list" name="alerts" method="post" action="/alert/subscribe">
[% INCLUDE 'alert/_list.html' %]
diff --git a/templates/web/base/around/display_location.html b/templates/web/base/around/display_location.html
index 826e70632..6c71ad631 100755
--- a/templates/web/base/around/display_location.html
+++ b/templates/web/base/around/display_location.html
@@ -33,6 +33,7 @@
SET bodyclass = 'mappage';
SET rss = [ tprintf(loc('Recent local problems, %s', "%s is the site name"), site_name), rss_url ];
+ SET extra_js = [];
INCLUDE 'header.html',
title => loc('Viewing a location')
robots => 'noindex,nofollow';
diff --git a/templates/web/base/js/translation_strings.html b/templates/web/base/js/translation_strings.html
index af3073f91..9747773d9 100644
--- a/templates/web/base/js/translation_strings.html
+++ b/templates/web/base/js/translation_strings.html
@@ -41,6 +41,9 @@ fixmystreet.password_minimum_length = [% c.cobrand.password_minimum_length %];
how_to_send: '[% loc('How to send successful reports') | replace("'", "\\'") %]',
more_details: '[% loc('Details') | replace("'", "\\'") %]',
+ this_report: '[% loc('This report') | replace("'", "\\'") %]',
+ this_is_the_problem: '[% loc('This is the problem') | replace("'", "\\'") %]',
+
or: '[% loc(' or ') | replace("'", "\\'") %]',
geolocation_declined: '[% loc('You declined; please fill in the box above') | replace("'", "\\'") %]',
diff --git a/templates/web/base/report/_inspect.html b/templates/web/base/report/_inspect.html
index 76555cef8..fa79d9912 100644
--- a/templates/web/base/report/_inspect.html
+++ b/templates/web/base/report/_inspect.html
@@ -1,3 +1,6 @@
+[% extra_js = [
+ version('/js/duplicates.js'),
+] -%]
[% permissions = c.user.permissions(problem) %]
[% second_column = BLOCK -%]
<div id="side-inspect">
@@ -120,7 +123,7 @@
<p class="[% "hidden" IF problem.duplicate_of %]">[% loc('Which report is it a duplicate of?') %]</p>
<ul class="item-list item-list--inspect-duplicates">
[% IF problem.duplicate_of %]
- [% INCLUDE 'report/_item.html' item_extra_class = 'item-list__item--selected' problem = problem.duplicate_of %]
+ [% INCLUDE 'report/_item_expandable.html' item_extra_class = 'item-list__item--selected' problem = problem.duplicate_of %]
<li class="item-list__item"><a class="btn" href="#" id="js-change-duplicate-report">[% loc('Choose another') %]</a></li>
[% END %]
</ul>
@@ -129,7 +132,7 @@
<p><strong>[% loc('Duplicates') %]</strong></p>
<ul class="item-list item-list--inspect-duplicates">
[% FOR duplicate IN problem.duplicates %]
- [% INCLUDE 'report/_item.html' problem = duplicate %]
+ [% INCLUDE 'report/_item_expandable.html' problem = duplicate %]
[% END %]
</ul>
[% END %]
diff --git a/templates/web/base/report/nearby.html b/templates/web/base/report/nearby.html
index c64b10d7f..1e0d6cc79 100644
--- a/templates/web/base/report/nearby.html
+++ b/templates/web/base/report/nearby.html
@@ -1,3 +1,3 @@
[%~ FOREACH problem IN reports ~%]
- [%~ INCLUDE 'reports/_list-entry.html' ~%]
+ [%~ INCLUDE 'report/_item_expandable.html' ~%]
[%~ END ~%]
diff --git a/templates/web/base/report/new/duplicate_suggestions.html b/templates/web/base/report/new/duplicate_suggestions.html
new file mode 100644
index 000000000..582ba58e9
--- /dev/null
+++ b/templates/web/base/report/new/duplicate_suggestions.html
@@ -0,0 +1,42 @@
+[% IF c.cobrand.suggest_duplicates %]
+[% extra_js.push(
+ version('/js/duplicates.js'),
+) -%]
+<div id="js-duplicate-reports" class="duplicate-report-suggestions hidden">
+ <button class="duplicate-report-suggestions__close js-hide-duplicate-suggestions">[% loc('Close') %]</button>
+ <h2 class="form-section-heading">[% loc('Already been reported?') %]</h2>
+ <div class="form-section-description">
+ [% IF c.cobrand.is_council %]
+ <p>[% loc('There are similar problems nearby that we’re already aware of, is one of them yours?') %]</p>
+ [% ELSE %]
+ <p>[% loc('We’ve already reported these nearby problems to the council. Is one of them yours?') %]</p>
+ [% END %]
+ </div>
+
+ <ul class="item-list"></ul>
+ <button class="btn btn--block js-hide-duplicate-suggestions">[% loc('Continue – report a new problem') %]</button>
+</div>
+<div class="js-template-get-updates hidden">
+ <div id="alerts" class="get-updates js-alert-list">
+ <p id="rznvy_hint">
+ [% IF c.user_exists %]
+ [% loc('Would you like us to notify you when this problem is updated or fixed?') %]
+ [% ELSE %]
+ [% loc('If you let us know your email address, we’ll notify you when this problem is updated or fixed.') %]
+ [% END %]
+ </p>
+ <input type="hidden" name="id" disabled>
+ <input type="hidden" name="token" value="[% csrf_token %]" disabled>
+ <input type="hidden" name="type" value="updates" disabled>
+ [% IF c.user_exists %]
+ <input type="submit" value="[% loc('Get updates') %]" class="btn btn--block" id="alert_email_button">
+ [% ELSE %]
+ <label for="rznvy_input">[% loc('Your email') %]</label>
+ <div class="form-txt-submit-box">
+ <input type="email" class="form-control" name="rznvy" id="rznvy_input" aria-described-by="rznvy_hint" disabled>
+ <input type="submit" value="[% loc('Get updates') %]" class="btn" id="alert_email_button">
+ </div>
+ [% END %]
+ </div>
+</div>
+[% END %]
diff --git a/templates/web/base/report/new/fill_in_details.html b/templates/web/base/report/new/fill_in_details.html
index 8fa1253da..fa7aabce3 100644
--- a/templates/web/base/report/new/fill_in_details.html
+++ b/templates/web/base/report/new/fill_in_details.html
@@ -4,6 +4,8 @@
SET bodyclass = '';
SET bodyclass = 'mappage';
SET bodyclass = bodyclass _ " with-notes" IF sidebar_html;
+ SET extra_js = [];
+ PROCESS "report/photo-js.html";
PROCESS "maps/${map.type}.html" IF report.used_map;
INCLUDE 'header.html', title => loc('Reporting a problem');
%]
diff --git a/templates/web/base/report/new/form_report.html b/templates/web/base/report/new/form_report.html
index 39e29c723..a5b378641 100644
--- a/templates/web/base/report/new/form_report.html
+++ b/templates/web/base/report/new/form_report.html
@@ -7,6 +7,7 @@
[% PROCESS "report/new/category_wrapper.html" %]
[% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %]
+[% PROCESS "report/new/duplicate_suggestions.html" %]
<div class="js-hide-if-invalid-category">
[% TRY %][% PROCESS 'report/new/_form_labels.html' %][% CATCH file %][% END %]
diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js
index bbcf73055..d6d03eac3 100644
--- a/web/cobrands/fixmystreet/fixmystreet.js
+++ b/web/cobrands/fixmystreet/fixmystreet.js
@@ -974,7 +974,7 @@ $.extend(fixmystreet.set_up, {
e.preventDefault();
var form = $('<form/>').attr({ method:'post', action:"/alert/subscribe" });
form.append($('<input name="alert" value="Subscribe me to an email alert" type="hidden" />'));
- $('#alerts input[type=text], #alerts input[type=hidden], #alerts input[type=radio]:checked').each(function() {
+ $(this).closest('.js-alert-list').find('input[type=text], input[type=hidden], input[type=radio]:checked').each(function() {
var $v = $(this);
$('<input/>').attr({ name:$v.attr('name'), value:$v.val(), type:'hidden' }).appendTo(form);
});
diff --git a/web/cobrands/fixmystreet/staff.js b/web/cobrands/fixmystreet/staff.js
index fadf18356..a7e0c8896 100644
--- a/web/cobrands/fixmystreet/staff.js
+++ b/web/cobrands/fixmystreet/staff.js
@@ -1,84 +1,4 @@
fixmystreet.staff_set_up = {
- manage_duplicates: function() {
- // Deal with changes to report state by inspector/other staff, specifically
- // displaying nearby reports if it's changed to 'duplicate'.
- function refresh_duplicate_list() {
- var report_id = $("#report_inspect_form .js-report-id").text();
- var args = {
- filter_category: $("#report_inspect_form select#category").val(),
- latitude: $('input[name="latitude"]').val(),
- longitude: $('input[name="longitude"]').val()
- };
- $("#js-duplicate-reports ul").html('<li class="item-list__item">Loading...</li>');
- var nearby_url = '/report/'+report_id+'/nearby.json';
- $.getJSON(nearby_url, args, function(data) {
- var duplicate_of = $("#report_inspect_form [name=duplicate_of]").val();
- var $reports = $(data.reports_list)
- .not("[data-report-id="+report_id+"]")
- .slice(0, 5);
- $reports.filter("[data-report-id="+duplicate_of+"]").addClass("item-list--reports__item--selected");
-
- (function() {
- var timeout;
- $reports.on('mouseenter', function(){
- clearTimeout(timeout);
- fixmystreet.maps.markers_highlight(parseInt($(this).data('reportId'), 10));
- }).on('mouseleave', function(){
- timeout = setTimeout(fixmystreet.maps.markers_highlight, 50);
- });
- })();
-
- $("#js-duplicate-reports ul").empty().prepend($reports);
-
- $reports.find("a").click(function() {
- var report_id = $(this).closest("li").data('reportId');
- $("#report_inspect_form [name=duplicate_of]").val(report_id);
- $("#js-duplicate-reports ul li").removeClass("item-list--reports__item--selected");
- $(this).closest("li").addClass("item-list--reports__item--selected");
- return false;
- });
-
- show_nearby_pins(data, report_id);
- });
- }
-
- function show_nearby_pins(data, report_id) {
- var markers = fixmystreet.maps.markers_list( data.pins, true );
- // We're replacing all the features in the markers layer with the
- // possible duplicates, but the list of pins from the server doesn't
- // include the current report. So we need to extract the feature for
- // the current report and include it in the list of features we're
- // showing on the layer.
- var report_marker = fixmystreet.maps.get_marker_by_id(parseInt(report_id, 10));
- if (report_marker) {
- markers.unshift(report_marker);
- }
- fixmystreet.markers.removeAllFeatures();
- fixmystreet.markers.addFeatures( markers );
- }
-
- function state_change() {
- // The duplicate report list only makes sense when state is 'duplicate'
- if ($(this).val() !== "duplicate") {
- $("#js-duplicate-reports").addClass("hidden");
- return;
- } else {
- $("#js-duplicate-reports").removeClass("hidden");
- }
- // If this report is already marked as a duplicate of another, then
- // there's no need to refresh the list of duplicate reports
- var duplicate_of = $("#report_inspect_form [name=duplicate_of]").val();
- if (!!duplicate_of) {
- return;
- }
-
- refresh_duplicate_list();
- }
-
- $("#report_inspect_form").on("change.state", "select#state", state_change);
- $("#js-change-duplicate-report").click(refresh_duplicate_list);
- },
-
action_scheduled_raise_defect: function() {
$("#report_inspect_form").find('[name=state]').on('change', function() {
if ($(this).val() !== "action scheduled") {
diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss
index 6fc63d9f0..c3cf3cb1b 100644
--- a/web/cobrands/sass/_base.scss
+++ b/web/cobrands/sass/_base.scss
@@ -530,6 +530,53 @@ ul.error {
@include border-radius(0.25em);
}
+.duplicate-report-suggestions {
+ position: relative;
+
+ .item-list__item--expandable {
+ border-top: 1px solid #ddd;
+ }
+
+ .item-list {
+ margin: 0 -1em 1em -1em;
+ border-bottom: 1px solid #ddd;
+ }
+}
+
+.duplicate-report-suggestions__close {
+ position: absolute;
+ right: 0;
+ top: 0;
+ display: block;
+ width: 32px;
+ height: 0;
+ padding-top: 32px;
+ overflow: hidden;
+ border: none;
+ background: transparent;
+ opacity: 0.5;
+ line-height: 2em; // Make sure line box is taller than text, so text is pushed below hidden overflow.
+
+ &:hover,
+ &:focus {
+ opacity: 0.7;
+ }
+
+ // Doing some gymnastics so we can reuse the existing .btn--close icon.
+ &:before {
+ content: "";
+ display: block;
+ width: 16px;
+ height: 16px;
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ background-repeat: no-repeat;
+ background-size: 112px 16px;
+ @include svg-background-image('/cobrands/fixmystreet/images/button-icons');
+ background-position: -32px 0;
+ }
+}
/*** LAYOUT ***/
@@ -1256,17 +1303,23 @@ input.final-submit {
.item-list__item--expandable {
@include clearfix();
- border-top: 1px solid #fff;
- background-color: transparent;
margin: 0;
padding: 1em;
.js & {
cursor: pointer;
- &:hover, &.hovered {
+ &:hover,
+ &.hovered {
background-color: $itemlist_item_background_hover;
}
+
+ &.item-list__item--selected,
+ &.item-list__item--selected:hover,
+ &.item-list__item--selected.hovered {
+ cursor: default;
+ background-color: #fff;
+ }
}
h3 {
@@ -1296,7 +1349,7 @@ input.final-submit {
cursor: default;
&:hover {
- background-color: transparent;
+ background-color: $itemlist_item_background;
}
}
}
@@ -1324,6 +1377,16 @@ input.final-submit {
}
}
+.item-list__item .get-updates {
+ margin: 0 -1em -1em -1em;
+ padding: 1em;
+ background-color: $itemlist_item_background_hover;
+
+ p, label {
+ margin: 0 0 0.5em 0;
+ }
+}
+
.problem-header .update-img,
.item-list .update-img {
float: $right;
diff --git a/web/js/duplicates.js b/web/js/duplicates.js
new file mode 100644
index 000000000..4ed54846c
--- /dev/null
+++ b/web/js/duplicates.js
@@ -0,0 +1,206 @@
+$(function() {
+
+ // Store a reference to the "duplicate" report pins so we can
+ // quickly remove them when we’re finished showing duplicates.
+ var current_duplicate_markers;
+
+ // Report ID will be available on report inspect page,
+ // but undefined on new report page.
+ var report_id = $("#report_inspect_form .js-report-id").text() || undefined;
+
+ function refresh_duplicate_list() {
+ // This function will return a jQuery Promise, so callbacks can be
+ // hooked onto it, once the ajax request as completed.
+ var dfd = $.Deferred();
+
+ var nearby_url;
+ var url_params = {
+ filter_category: $('select[name="category"]').val(),
+ latitude: $('input[name="latitude"]').val(),
+ longitude: $('input[name="longitude"]').val()
+ };
+
+ if ( report_id ) {
+ nearby_url = '/report/' + report_id + '/nearby.json';
+ url_params.distance = 1000; // Inspectors might want to see reports fairly far away (1000 metres)
+ url_params.pin_size = 'small'; // How it's always been
+ } else {
+ nearby_url = '/around/nearby';
+ url_params.distance = 250; // Only want to bother public with very nearby reports (250 metres)
+ url_params.pin_size = 'normal';
+ }
+
+ $.ajax({
+ url: nearby_url,
+ data: url_params,
+ dataType: 'json'
+ }).done(function(response) {
+ if ( response.pins.length ){
+ render_duplicate_list(response);
+ render_duplicate_pins(response);
+ } else {
+ remove_duplicate_pins();
+ remove_duplicate_list();
+ }
+ dfd.resolve();
+ }).fail(function(){
+ remove_duplicate_pins();
+ remove_duplicate_list();
+ dfd.reject();
+ });
+
+ return dfd.promise();
+ }
+
+ function render_duplicate_list(api_response) {
+ var $reports = $( api_response.reports_list );
+
+ var duplicate_of = $('#report_inspect_form [name="duplicate_of"]').val();
+ if ( duplicate_of ) {
+ $reports.filter('[data-report-id="' + duplicate_of + '"]')
+ .addClass("item-list__item--selected");
+ }
+
+ $("#js-duplicate-reports ul").empty().prepend( $reports );
+ fixmystreet.set_up.fancybox_images();
+
+ $('#js-duplicate-reports').hide().removeClass('hidden').slideDown();
+ if ( $('#problem_form').length ) {
+ $('.js-hide-if-invalid-category').slideUp();
+ }
+
+ // Highlight map pin when hovering associated list item.
+ var timeout;
+ $reports.on('mouseenter', function(){
+ var id = parseInt( $(this).data('reportId'), 10 );
+ clearTimeout( timeout );
+ fixmystreet.maps.markers_highlight( id );
+ }).on('mouseleave', function(){
+ timeout = setTimeout( fixmystreet.maps.markers_highlight, 50 );
+ });
+
+ // Add a "select this report" button, when on the report inspect form.
+ if ( $('#report_inspect_form').length ) {
+ $reports.each(function(){
+ var $button = $('<button>').addClass('btn btn--small btn--primary');
+ $button.text(translation_strings.this_report);
+ $button.on('click', function(e) {
+ e.preventDefault(); // Prevent button from submitting parent form
+ var report_id = $(this).closest('li').data('reportId');
+ $('#report_inspect_form [name="duplicate_of"]').val(report_id);
+ $(this).closest('li')
+ .addClass('item-list__item--selected')
+ .siblings('.item-list__item--selected')
+ .removeClass('item-list__item--selected');
+ });
+ $(this).find('.item-list__item--expandable__actions').append($button);
+ });
+ }
+
+ // Add a "track this report" button when on the regular reporting form.
+ if ( $('#problem_form').length ) {
+ $reports.each(function() {
+ var $li = $(this);
+ var id = parseInt( $li.data('reportId'), 10 );
+ var alert_url = '/alert/subscribe?id=' + encodeURIComponent(id);
+ var $button = $('<a>').addClass('btn btn--small btn--primary');
+ $button.text(translation_strings.this_is_the_problem);
+ $button.attr('href', alert_url);
+ $button.on('click', function(e){
+ e.preventDefault();
+ var $div = $('.js-template-get-updates > div').clone();
+ $div.find('input[name="id"]').val(id);
+ $div.find('input[disabled]').prop('disabled', false);
+ $div.hide().appendTo($li).slideDown(250, function(){
+ $div.find('input[type="email"]').focus();
+ });
+ $li.find('.item-list__item--expandable__actions').slideUp(250);
+ $li.removeClass('js-expandable');
+ $li.addClass('item-list__item--selected');
+ });
+ $li.find('.item-list__item--expandable__actions').append($button);
+ });
+ }
+ }
+
+ function render_duplicate_pins(api_response) {
+ var markers = fixmystreet.maps.markers_list( api_response.pins, true );
+ fixmystreet.markers.removeFeatures( current_duplicate_markers );
+ fixmystreet.markers.addFeatures( markers );
+ current_duplicate_markers = markers;
+ }
+
+ function remove_duplicate_list(cb) {
+ var animations = [];
+
+ animations.push( $.Deferred() );
+ $('#js-duplicate-reports').slideUp(function(){
+ $(this).addClass('hidden');
+ $(this).find('ul').empty();
+ animations[0].resolve();
+ });
+ if ( $('#problem_form').length ) {
+ animations.push( $.Deferred() );
+ $('.js-hide-if-invalid-category').slideDown(function(){
+ animations[1].resolve();
+ });
+ }
+
+ $.when.apply(this, animations).then(cb);
+ }
+
+ function remove_duplicate_pins() {
+ fixmystreet.markers.removeFeatures( current_duplicate_markers );
+ }
+
+ function inspect_form_state_change() {
+ // The duplicate report list only makes sense when state is 'duplicate'
+ if ($(this).val() !== "duplicate") {
+ $("#js-duplicate-reports").addClass("hidden");
+ return;
+ } else {
+ $("#js-duplicate-reports").removeClass("hidden");
+ }
+ // If this report is already marked as a duplicate of another, then
+ // there's no need to refresh the list of duplicate reports
+ var duplicate_of = $("#report_inspect_form [name=duplicate_of]").val();
+ if (!!duplicate_of) {
+ return;
+ }
+ refresh_duplicate_list();
+ }
+
+ var category_changing = false;
+ function problem_form_category_change() {
+ // Annoyingly this event seems to fire a few times in quick succession,
+ // so set a flag to avoid multiple overlapping refreshes.
+ if (category_changing) { return; }
+ category_changing = true;
+
+ refresh_duplicate_list().always(function(){
+ // Wait an extra second until we allow another reload.
+ setTimeout(function(){
+ category_changing = false;
+ }, 1000);
+ });
+ }
+
+ // Want to show potential duplicates when a regular user starts a new
+ // report, or changes the category/location of a partial report.
+ $("#problem_form").on("change.category", "select#form_category", problem_form_category_change);
+
+ // Want to show duplicates when an inspector sets a report’s state to "duplicate".
+ $("#report_inspect_form").on("change.state", "select#state", inspect_form_state_change);
+
+ // Also want to give inspectors a way to select a *new* duplicate report.
+ $("#js-change-duplicate-report").click(refresh_duplicate_list);
+
+ $('.js-hide-duplicate-suggestions').on('click', function(e){
+ e.preventDefault();
+ remove_duplicate_pins();
+ remove_duplicate_list(function(){
+ $('#form_title').focus();
+ });
+ });
+
+});
diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js
index fdfeed314..984f4b098 100644
--- a/web/js/map-OpenLayers.js
+++ b/web/js/map-OpenLayers.js
@@ -381,15 +381,15 @@ $.extend(fixmystreet.utils, {
function sidebar_highlight(problem_id) {
if (typeof problem_id !== 'undefined') {
- var $a = $('.item-list--reports a[href$="/' + problem_id + '"]');
- $a.parent().addClass('hovered');
+ var $li = $('[data-report-id="' + problem_id + '"]');
+ $li.addClass('hovered');
} else {
- $('.item-list--reports .hovered').removeClass('hovered');
+ $('.item-list .hovered').removeClass('hovered');
}
}
function marker_click(problem_id, evt) {
- var $a = $('.item-list--reports a[href$="/' + problem_id + '"]');
+ var $a = $('.item-list a[href$="/' + problem_id + '"]');
if (!$a[0]) {
return;
}