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")
.add-note-btn,
#add-note-btn,
#add-course-btn,
+#existing-course-btn,
#save-btn
{
border: none;
/* transition: ease-out ? ? ? */
}
+#existing-course-btn,
#save-btn {
margin-top: 13px;
}
+#existing-course-btn.disabled,
#save-btn.disabled
{
color: #afafaf;
// 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() {
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 {
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 {
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
});
<script>
var json_school_list = "{% url 'json_school_list' %}"
var json_school_course_list = "{% url 'json_school_course_list' %}"
+ var json_school_course_instructor_list = "{% url 'json_school_course_instructor_list' %}"
var csrf_token = "{{ csrf_token }}";
</script>
<script src="{{ STATIC_URL }}js/add-course.js"></script>
</div> <!-- .row -->
<div class="row">
- <div class="small-4 columns small-centered">
- <button id="save-btn">
- <i class=icon-save></i> Save
- </div>
+ <div class="small-4 large-8 columns small-centered text-center">
+ <button id="save-btn" class="disabled">
+ <i class="icon-save"></i> Save
+ </button>
+ <span id="existing-course-msg" class="hide">
+ Looks like this course already exists on KarmaNotes!
+ <a id="existing-course-btn" class="button">Go To Existing Course <i class="icon-arrow-right"></i></a></span>
</div>
</div>
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
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'),