diff --git a/cms/djangoapps/contentstore/api/tests/test_validation.py b/cms/djangoapps/contentstore/api/tests/test_validation.py
index acaa4dc0c68d6464238d553a19bb54aac69a1ea7..87142cb3bec51ec4d9a9410945091cbeac0d4248 100644
--- a/cms/djangoapps/contentstore/api/tests/test_validation.py
+++ b/cms/djangoapps/contentstore/api/tests/test_validation.py
@@ -77,11 +77,10 @@ class CourseValidationViewTest(SharedModuleStoreTestCase, APITestCase):
         self.assertEqual(resp.status_code, status.HTTP_200_OK)
         expected_data = {
             'assignments': {
-                'num_with_dates_before_end': 0,
-                'num_with_dates': 0,
-                'total_visible': 1,
-                'num_with_dates_after_start': 0,
                 'total_number': 1,
+                'total_visible': 1,
+                'assignments_with_dates_before_start': [],
+                'assignments_with_dates_after_end': [],
             },
             'dates': {
                 'has_start_date': True,
@@ -99,4 +98,5 @@ class CourseValidationViewTest(SharedModuleStoreTestCase, APITestCase):
             },
             'is_self_paced': True,
         }
+
         self.assertDictEqual(resp.data, expected_data)
diff --git a/cms/djangoapps/contentstore/api/views/course_validation.py b/cms/djangoapps/contentstore/api/views/course_validation.py
index f6c68e9e17c2113593be7022ee336c773a63991a..b0b7ee35329d350eefdc131b0ded0ca5475e412b 100644
--- a/cms/djangoapps/contentstore/api/views/course_validation.py
+++ b/cms/djangoapps/contentstore/api/views/course_validation.py
@@ -33,6 +33,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView):
         * grades
         * certificates
         * updates
+        * graded_only (boolean) - whether to included graded subsections only in the assignments information.
 
     **GET Response Values**
 
@@ -45,9 +46,8 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView):
         * assignments
             * total_number - total number of assignments in the course.
             * total_visible - number of assignments visible to learners in the course.
-            * num_with_dates - number of assignments with due dates.
-            * num_with_dates_after_start - number of assignments with due dates after the start date.
-            * num_with_dates_before_end - number of assignments with due dates before the end date.
+            * assignments_with_dates_before_start - assignments with due dates before the start date.
+            * assignments_with_dates_after_end - assignments with due dates after the end date.
         * grades
             * sum_of_weights - sum of weights for all assignments in the course (valid ones should equal 1).
         * certificates
@@ -77,7 +77,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView):
                 )
             if get_bool_param(request, 'assignments', all_requested):
                 response.update(
-                    assignments=self._assignments_validation(course)
+                    assignments=self._assignments_validation(course, request)
                 )
             if get_bool_param(request, 'grades', all_requested):
                 response.update(
@@ -106,28 +106,54 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView):
             has_end_date=course.end is not None,
         )
 
-    def _assignments_validation(self, course):
+    def _assignments_validation(self, course, request):
         assignments, visible_assignments = self._get_assignments(course)
-        assignments_with_dates = [a for a in visible_assignments if a.due]
+        assignments_with_dates = [
+            a for a in visible_assignments if a.due
+        ]
 
-        num_with_dates = len(assignments_with_dates)
-        num_with_dates_after_start = (
-            len([a for a in assignments_with_dates if a.due > course.start])
+        assignments_with_dates_before_start = (
+            [
+                {'id': unicode(a.location), 'display_name': a.display_name}
+                for a in assignments_with_dates
+                if a.due < course.start
+            ]
             if self._has_start_date(course)
-            else 0
+            else []
         )
-        num_with_dates_before_end = (
-            len([a for a in assignments_with_dates if a.due < course.end])
+
+        assignments_with_dates_after_end = (
+            [
+                {'id': unicode(a.location), 'display_name': a.display_name}
+                for a in assignments_with_dates
+                if a.due > course.end
+            ]
             if course.end
-            else 0
+            else []
         )
 
+        if get_bool_param(request, 'graded_only', False):
+            assignments_with_dates = [
+                a
+                for a in visible_assignments
+                if a.due and a.graded
+            ]
+
+            assignments_with_dates_before_start = [
+                {'id': unicode(a.location), 'display_name': a.display_name}
+                for a in assignments_with_dates if a.due < course.start
+            ]
+
+            assignments_with_dates_after_end = [
+                {'id': unicode(a.location), 'display_name': a.display_name}
+                for a in assignments_with_dates if a.due > course.end
+            ]
+
         return dict(
             total_number=len(assignments),
             total_visible=len(visible_assignments),
-            num_with_dates=num_with_dates,
-            num_with_dates_after_start=num_with_dates_after_start,
-            num_with_dates_before_end=num_with_dates_before_end,
+            assignments_with_dates_before_start=assignments_with_dates_before_start,
+            assignments_with_dates_after_end=assignments_with_dates_after_end,
         )
 
     def _grades_validation(self, course):
@@ -158,7 +184,6 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView):
             for section in sections
             for assignment_usage_key in section.children
         ]
-
         visible_sections = [
             s for s in sections
             if not s.visible_to_staff_only and not s.hide_from_toc
diff --git a/cms/static/js/views/pages/course_outline.js b/cms/static/js/views/pages/course_outline.js
index 7e65dd8e3d45df2ba4be4cc3f866428967c3b6c3..00335e92a39f5dbb5bf0f4c4d28b6e6bafdf4f8c 100644
--- a/cms/static/js/views/pages/course_outline.js
+++ b/cms/static/js/views/pages/course_outline.js
@@ -18,6 +18,18 @@ define([
                 'click .button-toggle-expand-collapse': 'toggleExpandCollapse'
             },
 
+            /**
+             * keep a running timeout counter of 5,000 milliseconds
+             * for finding an element; see afterRender and scrollToElement function
+             */
+            findElementPollingTimeout: 5000,
+
+            /**
+             * used as the delay parameter to setTimeout in scrollToElement
+             * function for polling for an element
+             */
+            pollingDelay: 100,
+
             options: {
                 collapsedClass: 'is-collapsed'
             },
@@ -90,6 +102,32 @@ define([
                 return $.Deferred().resolve().promise();
             },
 
+            afterRender: function() {
+                this.scrollToElement();
+            },
+
+            /**
+             * recursively poll for element specified by the URL fragment
+             * at 100 millisecond intervals until element is found or
+             * Polling is reached
+             */
+            scrollToElement: function () {
+                this.findElementPollingTimeout -= this.pollingDelay;
+
+                const elementID = window.location.hash.replace("#", "");
+
+                if (this.findElementPollingTimeout > 0) {
+                    if (elementID) {
+                        const element = document.getElementById(elementID);
+                        if (element) {
+                            element.scrollIntoView();
+                        } else {
+                            setTimeout(this.scrollToElement, this.pollingDelay);
+                        }
+                    }
+                }
+            },
+
             hasContent: function() {
                 return this.model.hasChildren();
             },
diff --git a/cms/templates/js/course-outline.underscore b/cms/templates/js/course-outline.underscore
index 5599a001812c0d0648b660da1b3fb2ae5ef1ebe0..13aadc7c2e56ab263dffbfe5b02c53edafa2b3b6 100644
--- a/cms/templates/js/course-outline.underscore
+++ b/cms/templates/js/course-outline.underscore
@@ -97,7 +97,7 @@ if (is_proctored_exam) {
 %>
 <% if (parentInfo) { %>
 <li class="outline-item outline-<%- xblockType %> <%- visibilityClass %> is-draggable <%- includesChildren ? 'is-collapsible' : '' %> <%- isCollapsed ? 'is-collapsed' : '' %>"
-    data-parent="<%- parentInfo.get('id') %>" data-locator="<%- xblockInfo.get('id') %>">
+    data-parent="<%- parentInfo.get('id') %>" data-locator="<%- xblockInfo.get('id') %>" id="<%- xblockInfo.get('id') %>">
 
     <span class="draggable-drop-indicator draggable-drop-indicator-before"><span class="icon fa fa-caret-right" aria-hidden="true"></span></span>
     <% if (xblockInfo.isHeaderVisible()) { %>