From 7503eee0dfd1724c8ef42e785d9de894c1c78200 Mon Sep 17 00:00:00 2001 From: Charles Connell Date: Sun, 15 Dec 2013 17:03:07 -0500 Subject: [PATCH] Autocomplete instructor names, take users to existing courses, be stricter about school names --- karmaworld/apps/courses/views.py | 55 +++++++++++- karmaworld/assets/css/global.css | 3 + karmaworld/assets/js/add-course.js | 94 ++++++++++++++++---- karmaworld/templates/partial/add_course.html | 12 ++- karmaworld/urls.py | 3 + 5 files changed, 143 insertions(+), 24 deletions(-) diff --git a/karmaworld/apps/courses/views.py b/karmaworld/apps/courses/views.py index ab2c57e..18f27fe 100644 --- a/karmaworld/apps/courses/views.py +++ b/karmaworld/apps/courses/views.py @@ -117,19 +117,66 @@ def school_course_list(request): try: _school_id = int(request.POST['school_id']) except: - return HttpResponseNotFound(json.dumps({'status': 'fail', 'message':'could not convert school id to integer'}), mimetype="application/json") + return HttpResponseNotFound(json.dumps({'status': 'fail', + 'message': 'could not convert school id to integer'}), + mimetype="application/json") # Look up the school try: school = School.objects.get(id__exact=_school_id) except (MultipleObjectsReturned, ObjectDoesNotExist): - return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'school id did not match exactly one school'}), mimetype="application/json") + return HttpResponseNotFound(json.dumps({'status': 'fail', + 'message': 'school id did not match exactly one school'}), + mimetype="application/json") + # Look up matching courses _courses = Course.objects.filter(school__exact=school.id, name__icontains=_query) courses = [{'name': c.name} for c in _courses] # return as json - return HttpResponse(json.dumps({'status':'success', 'courses': courses}), mimetype="application/json") + return HttpResponse(json.dumps({'status':'success', 'courses': courses}), + mimetype="application/json") else: # else return that the api call failed - return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'query parameters missing'}), mimetype="application/json") + return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'query parameters missing'}), + mimetype="application/json") + +def school_course_instructor_list(request): + """Return JSON describing instructors we know of at the given school + teaching the given course + that match the query """ + if request.method == 'POST' and request.is_ajax() \ + and request.POST.has_key('q')\ + and request.POST.has_key('course_name')\ + and request.POST.has_key('school_id'): + + _query = request.POST['q'] + _course_name = request.POST['course_name'] + try: + _school_id = int(request.POST['school_id']) + except: + return HttpResponseNotFound(json.dumps({'status': 'fail', + 'message':'could not convert school id to integer'}), + mimetype="application/json") + + # Look up the school + try: + school = School.objects.get(id__exact=_school_id) + except (MultipleObjectsReturned, ObjectDoesNotExist): + return HttpResponseNotFound(json.dumps({'status': 'fail', + 'message': 'school id did not match exactly one school'}), + mimetype="application/json") + + # Look up matching courses + _courses = Course.objects.filter(school__exact=school.id, + name__exact=_course_name, + instructor_name__icontains=_query) + instructors = [{'name': c.instructor_name, 'url': c.get_absolute_url()} for c in _courses] + + # return as json + return HttpResponse(json.dumps({'status':'success', 'instructors': instructors}), + mimetype="application/json") + else: + # else return that the api call failed + return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'query parameters missing'}), + mimetype="application/json") diff --git a/karmaworld/assets/css/global.css b/karmaworld/assets/css/global.css index b5d5dce..355ab01 100644 --- a/karmaworld/assets/css/global.css +++ b/karmaworld/assets/css/global.css @@ -532,6 +532,7 @@ a.activity_target:hover .add-note-btn, #add-note-btn, #add-course-btn, +#existing-course-btn, #save-btn { border: none; @@ -545,10 +546,12 @@ a.activity_target:hover /* transition: ease-out ? ? ? */ } +#existing-course-btn, #save-btn { margin-top: 13px; } +#existing-course-btn.disabled, #save-btn.disabled { color: #afafaf; diff --git a/karmaworld/assets/js/add-course.js b/karmaworld/assets/js/add-course.js index f9f0e07..d46e1f6 100644 --- a/karmaworld/assets/js/add-course.js +++ b/karmaworld/assets/js/add-course.js @@ -1,7 +1,22 @@ // Setup all the javascript stuff we need for the various // incarnations of the Add Course form + $(function() { + var schoolSelected = false; + var courseNameSelected = false; + var instructorSelected = false; + + function fieldEdited() { + if (schoolSelected && courseNameSelected && instructorSelected) { + $('#save-btn').hide(); + $('#existing-course-msg').show(); + } else { + $('#save-btn').show(); + $('#existing-course-msg').hide(); + } + } + // Set up the "Add Course" button at bottom // of page $('#add-course-btn').click(function() { @@ -52,7 +67,6 @@ $(function() { url: json_school_list, data: {q: request.term}, success: function(data) { - console.log(data); if (data['status'] === 'success') { response($.map(data['schools'], function(item) { return { @@ -70,31 +84,33 @@ $(function() { type: 'POST' }); }, - select: function(event, ui) { - console.log("select func"); - console.log("id"); - console.log(ui.item.value); - console.log("name"); - console.log(ui.item.label); - // don't let the user edit the field anymore - //$('#str_school').attr('readonly', true); - + select: function(event, ui) { // set the school id as the value of the hidden field $('#id_school').val(ui.item.real_value); - // set the School name as the textbox field - //$('#str_school').val(ui.item.label); + schoolSelected = true; + $('#str_school').removeClass('error'); + $('#save-btn').removeClass('disabled'); + fieldEdited(); + }, + change: function(event, ui) { + if (ui.item == null) { + $('#id_school').val(''); + schoolSelected = false; + $('#str_school').addClass('error'); + $('#save-btn').addClass('disabled'); + fieldEdited(); + } }, minLength: 3 }); $("#id_name").autocomplete({ source: function(request, response){ - var school_id = $('#id_school').val() + var school_id = $('#id_school').val(); $.ajax({ url: json_school_course_list, data: {q: request.term, school_id: school_id}, success: function(data) { - console.log(data); if (data['status'] === 'success') { response($.map(data['courses'], function(item) { return { @@ -102,14 +118,60 @@ $(function() { label: item.name, }; })); - } else { - // FIXME: do something? } }, dataType: "json", type: 'POST' }); }, + select: function(event, ui) { + courseNameSelected = true; + fieldEdited(); + }, + change: function(event, ui) { + if (ui.item == null) { + courseNameSelected = false; + fieldEdited(); + } + }, + minLength: 3 + }); + + $("#id_instructor_name").autocomplete({ + source: function(request, response) { + var school_id = $('#id_school').val(); + var course_name = $('#id_name').val(); + $.ajax({ + url: json_school_course_instructor_list, + data: {q: request.term, school_id: school_id, course_name: course_name}, + success: function(data) { + if (data['status'] === 'success') { + // Fill in the autocomplete entries + response($.map(data['instructors'], function(item) { + return { + value: item.name, + label: item.name, + url: item.url + }; + })); + } + }, + dataType: "json", + type: 'POST' + }); + }, + select: function(event, ui) { + instructorSelected = true; + $('#existing-course-btn').attr('href', ui.item.url); + fieldEdited(); + }, + change: function(event, ui) { + if (ui.item == null) { + instructorSelected = false; + $('#existing-course-btn').attr('href', ''); + fieldEdited(); + } + }, minLength: 3 }); diff --git a/karmaworld/templates/partial/add_course.html b/karmaworld/templates/partial/add_course.html index ea0c366..efa6d98 100644 --- a/karmaworld/templates/partial/add_course.html +++ b/karmaworld/templates/partial/add_course.html @@ -2,6 +2,7 @@ @@ -87,10 +88,13 @@
-
-
+
+ + + Looks like this course already exists on KarmaNotes! + Go To Existing Course
diff --git a/karmaworld/urls.py b/karmaworld/urls.py index f69edd0..fe9ba61 100644 --- a/karmaworld/urls.py +++ b/karmaworld/urls.py @@ -15,6 +15,7 @@ from karmaworld.apps.courses.views import CourseDetailView from karmaworld.apps.courses.views import CourseListView from karmaworld.apps.courses.views import school_list from karmaworld.apps.courses.views import school_course_list +from karmaworld.apps.courses.views import school_course_instructor_list from karmaworld.apps.notes.views import NoteView from karmaworld.apps.notes.views import RawNoteDetailView from karmaworld.apps.notes.views import PDFView @@ -91,6 +92,8 @@ urlpatterns = patterns('', url(r'^school/list/$', school_list, name='json_school_list'), # return json list of courses for a given school url(r'^school/course/list/$', school_course_list, name='json_school_course_list'), + # return json list of instructors for a given school and course + url(r'^school/course/instructors/list/$', school_course_instructor_list, name='json_school_course_instructor_list'), # ---- end JSON views ----# url(r'^$', CourseListView.as_view(model=Course), name='home'), -- 2.25.1