From 731c1567ba3c39f293e1ade72dd2e99316c96812 Mon Sep 17 00:00:00 2001 From: Charles Connell Date: Tue, 8 Apr 2014 18:29:23 -0400 Subject: [PATCH] Keyword on note page --- karmaworld/apps/notes/views.py | 52 ++++++++++++++++++--- karmaworld/assets/css/note_course_pages.css | 4 ++ karmaworld/assets/js/note-detail.js | 47 ++++++++++++++++++- karmaworld/settings/dev.py | 2 + karmaworld/templates/notes/note_detail.html | 48 ++++++++++++++++++- 5 files changed, 145 insertions(+), 8 deletions(-) diff --git a/karmaworld/apps/notes/views.py b/karmaworld/apps/notes/views.py index b9be9b5..8c62087 100644 --- a/karmaworld/apps/notes/views.py +++ b/karmaworld/apps/notes/views.py @@ -2,21 +2,19 @@ # -*- coding:utf8 -*- # Copyright (C) 2012 FinalsClub Foundation -import json import traceback import logging from django.core import serializers -from django.core.exceptions import ObjectDoesNotExist +from django.forms.formsets import formset_factory from karmaworld.apps.courses.models import Course from karmaworld.apps.notes.search import SearchIndex +from karmaworld.apps.quizzes.forms import KeywordForm +from karmaworld.apps.quizzes.models import Keyword from karmaworld.apps.users.models import NoteKarmaEvent from karmaworld.utils.ajax_utils import * -import os - -from django.conf import settings -from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound +from django.http import HttpResponse, HttpResponseBadRequest from django.views.generic import DetailView, ListView from django.views.generic import FormView from django.views.generic import View @@ -38,11 +36,30 @@ class NoteDetailView(DetailView): """ Class-based view for the note html page """ model = Note context_object_name = u"note" # name passed to template + keyword_form_class = formset_factory(KeywordForm) + + def post(self, requests, *args, **kwargs): + formset = self.keyword_form_class(requests) + if formset.is_valid(): + self.keyword_form_valid(formset) + self.keyword_formset = self.keyword_form_class(initial=self.get_initial_keywords()) + return super(NoteDetailView, self).post(requests, *args, **kwargs) + else: + self.keyword_formset = formset + return super(NoteDetailView, self).post(requests, *args, **kwargs) + + def get(self, request, *args, **kwargs): + self.keyword_formset = self.keyword_form_class(initial=self.get_initial_keywords()) + return super(NoteDetailView, self).get(request, *args, **kwargs) def get_context_data(self, **kwargs): """ Generate custom context for the page rendering a Note + if pdf, set the `pdf` flag """ + + kwargs['keyword_prototype_form'] = KeywordForm + kwargs['keyword_formset'] = self.keyword_formset + if self.object.is_pdf(): kwargs['pdf_controls'] = True @@ -61,6 +78,29 @@ class NoteDetailView(DetailView): return super(NoteDetailView, self).get_context_data(**kwargs) + def get_initial_keywords(self): + existing_keywords = self.get_object().keyword_set.order_by('id') + initial_data = [{'keyword': keyword.word, 'definition': keyword.definition, 'id': keyword.pk} + for keyword in existing_keywords] + return initial_data + + def keyword_form_valid(self, formset): + for form in formset: + word = form['keyword'].data + definition = form['definition'].data + id = form['id'].data + if word == '': + continue + try: + keyword_object = Keyword.objects.get(id=id) + except (ValueError, ObjectDoesNotExist): + keyword_object = Keyword() + + keyword_object.note = self.note + keyword_object.word = word + keyword_object.definition = definition + keyword_object.save() + class NoteSaveView(FormView, SingleObjectMixin): """ Save a Note and then view the page, diff --git a/karmaworld/assets/css/note_course_pages.css b/karmaworld/assets/css/note_course_pages.css index 8332842..1b0ab22 100644 --- a/karmaworld/assets/css/note_course_pages.css +++ b/karmaworld/assets/css/note_course_pages.css @@ -101,4 +101,8 @@ div.header-title-row { #minus-btn, #plus-btn { cursor: pointer; +} + +.keyword-form-row textarea.definition { + max-height: 75px; } \ No newline at end of file diff --git a/karmaworld/assets/js/note-detail.js b/karmaworld/assets/js/note-detail.js index 16ec911..b150f56 100644 --- a/karmaworld/assets/js/note-detail.js +++ b/karmaworld/assets/js/note-detail.js @@ -91,6 +91,48 @@ function injectRemoteCSS(url, noteframe) { noteframe.document.head.appendChild(injectCSS); } +function tabHandler(event) { + // check for: + // key pressed was TAB + // key was pressed in last row + if (event.which == 9) { + var totalForms = parseInt($('#id_form-TOTAL_FORMS').attr('value')); + var formIndex = parseInt($(this).closest('div.keyword-form-row').data('index')); + if (formIndex === totalForms-1) { + addForm(event); + event.preventDefault(); + } + } +} + +function addForm(event) { + var prototypeForm = $('#keyword-form-prototype div.keyword-form-row').clone().appendTo('#keyword-form-rows'); + var newForm = $('.keyword-form-row:last'); + var totalForms = $('#id_form-TOTAL_FORMS').attr('value'); + var newIdRoot = 'id_form-' + totalForms + '-'; + var newNameRoot = 'form-' + totalForms + '-'; + + newForm.data('index', totalForms); + + var keywordInput = newForm.find('.keyword'); + keywordInput.attr('id', newIdRoot + 'keyword'); + keywordInput.attr('name', newNameRoot + 'keyword'); + keywordInput.focus(); + + var definitionInput = newForm.find('.definition'); + definitionInput.attr('id', newIdRoot + 'definition'); + definitionInput.attr('name', newNameRoot + 'definition'); + definitionInput.keydown(tabHandler); + + var objectIdInput = newForm.find('.object-id'); + objectIdInput.attr('id', newIdRoot + 'id'); + objectIdInput.attr('name', newNameRoot + 'id'); + + $('#id_form-TOTAL_FORMS').attr('value', parseInt(totalForms)+1); + + keywordInput.focus(); +} + $(function() { $("#thank-button").click(function(event) { @@ -224,6 +266,9 @@ $(function() { }); } - + $('.definition').keydown(tabHandler); + $('#add-row-btn').click(addForm); }); + + diff --git a/karmaworld/settings/dev.py b/karmaworld/settings/dev.py index 70dccca..646cacc 100644 --- a/karmaworld/settings/dev.py +++ b/karmaworld/settings/dev.py @@ -73,6 +73,7 @@ AWS_HEADERS = { ########## TOOLBAR CONFIGURATION # See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation INSTALLED_APPS += ( + 'debug_toolbar', 'django_extensions', 'django_nose', ) @@ -82,6 +83,7 @@ INTERNAL_IPS = ('127.0.0.1',) # See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation MIDDLEWARE_CLASSES += ( + 'debug_toolbar.middleware.DebugToolbarMiddleware', ) diff --git a/karmaworld/templates/notes/note_detail.html b/karmaworld/templates/notes/note_detail.html index 1e8db7d..785d535 100644 --- a/karmaworld/templates/notes/note_detail.html +++ b/karmaworld/templates/notes/note_detail.html @@ -174,6 +174,7 @@
Note
+
Keywords
@@ -215,8 +216,53 @@ {% endif %} {# note.static_html #}
+
+ +
+
+
+
+ {% csrf_token %} + {{ keyword_formset.management_form }} +
+
+
+ {{ keyword_prototype_form.keyword }} +
+
+ {{ keyword_prototype_form.definition }} + {{ keyword_prototype_form.id }} +
+
+
+
+
+ {% for form_row in keyword_formset %} +
+
+ {{ form_row.keyword }} +
+
+ {{ form_row.definition }} + {{ form_row.id }} +
+
+
+ {% endfor %} +
+
+
+ +
+
+ +
+
+
+
+
- + -- 2.25.1