Keyword entry page
authorCharles Connell <charles@connells.org>
Thu, 13 Feb 2014 19:09:44 +0000 (14:09 -0500)
committerCharles Connell <charles@connells.org>
Thu, 13 Feb 2014 19:09:44 +0000 (14:09 -0500)
karmaworld/apps/quizzes/admin.py
karmaworld/apps/quizzes/forms.py [new file with mode: 0644]
karmaworld/apps/quizzes/migrations/0001_initial.py
karmaworld/apps/quizzes/migrations/0002_auto__add_definition__add_keyword.py [deleted file]
karmaworld/apps/quizzes/models.py
karmaworld/apps/quizzes/views.py
karmaworld/assets/js/quiz.js [new file with mode: 0644]
karmaworld/templates/quizzes/keyword_edit.html [new file with mode: 0644]
karmaworld/urls.py

index 0ef59bf4ef7f167c6c195aceec4ef67477701290..66481a177eab1923445ccc017e3b9e5941e4d7c9 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright (C) 2014  FinalsClub Foundation
 from django.contrib import admin
 from karmaworld.apps.quizzes.models import MultipleChoiceQuestion, FlashCardQuestion, MultipleChoiceOption, Quiz, \
-    TrueFalseQuestion
+    TrueFalseQuestion, Keyword
 from nested_inlines.admin import NestedTabularInline, NestedModelAdmin, NestedStackedInline
 
 
@@ -43,3 +43,4 @@ admin.site.register(MultipleChoiceQuestion, MultipleChoiceQuestionAdmin)
 admin.site.register(MultipleChoiceOption)
 admin.site.register(FlashCardQuestion)
 admin.site.register(TrueFalseQuestion)
+admin.site.register(Keyword)
diff --git a/karmaworld/apps/quizzes/forms.py b/karmaworld/apps/quizzes/forms.py
new file mode 100644 (file)
index 0000000..f91c4ea
--- /dev/null
@@ -0,0 +1,17 @@
+from django import forms
+from django.forms import TextInput, Textarea
+
+
+class KeywordForm(forms.Form):
+    keyword = forms.CharField(widget=TextInput)
+    definition = forms.CharField(widget=Textarea)
+    id = forms.IntegerField(required=False)
+
+    def as_p(self):
+        return '<div class="row keyword-form-row"><div class="small-4 columns">' + \
+                self['keyword'].as_text(attrs={'placeholder': 'Keyword', 'class': 'keyword'}) + \
+                '</div><div class="small-8 columns">' + \
+                self['definition'].as_textarea(attrs={'placeholder': 'Definition', 'class': 'definition'}) + \
+                self['id'].as_hidden(attrs={'class': 'object-id'}) + \
+                '</div></div>'
+
index 10695cf7b003214dd303f70107e9325c3b60587e..f3e408abee7648c6729d097bdaaa7e5ac1ddfed1 100644 (file)
@@ -8,6 +8,19 @@ from django.db import models
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
+        # Adding model 'Keyword'
+        db.create_table(u'quizzes_keyword', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('word', self.gf('django.db.models.fields.CharField')(max_length=1024)),
+            ('definition', self.gf('django.db.models.fields.CharField')(max_length=2048, null=True, blank=True)),
+            ('note', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['notes.Note'], null=True, blank=True)),
+            ('timestamp', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.utcnow)),
+        ))
+        db.send_create_signal(u'quizzes', ['Keyword'])
+
+        # Adding unique constraint on 'Keyword', fields ['word', 'note']
+        db.create_unique(u'quizzes_keyword', ['word', 'note_id'])
+
         # Adding model 'Quiz'
         db.create_table(u'quizzes_quiz', (
             (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
@@ -66,6 +79,12 @@ class Migration(SchemaMigration):
 
 
     def backwards(self, orm):
+        # Removing unique constraint on 'Keyword', fields ['word', 'note']
+        db.delete_unique(u'quizzes_keyword', ['word', 'note_id'])
+
+        # Deleting model 'Keyword'
+        db.delete_table(u'quizzes_keyword')
+
         # Deleting model 'Quiz'
         db.delete_table(u'quizzes_quiz')
 
@@ -199,6 +218,14 @@ class Migration(SchemaMigration):
             'sideB': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
             'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
         },
+        u'quizzes.keyword': {
+            'Meta': {'unique_together': "(('word', 'note'),)", 'object_name': 'Keyword'},
+            'definition': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'note': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['notes.Note']", 'null': 'True', 'blank': 'True'}),
+            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
+            'word': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
         u'quizzes.multiplechoiceoption': {
             'Meta': {'object_name': 'MultipleChoiceOption'},
             'correct': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
@@ -235,10 +262,9 @@ class Migration(SchemaMigration):
             'true': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
         },
         u'taggit.tag': {
-            'Meta': {'ordering': "['namespace', 'name']", 'object_name': 'Tag'},
+            'Meta': {'object_name': 'Tag'},
             u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
             'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'namespace': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
             'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
         },
         u'taggit.taggeditem': {
diff --git a/karmaworld/apps/quizzes/migrations/0002_auto__add_definition__add_keyword.py b/karmaworld/apps/quizzes/migrations/0002_auto__add_definition__add_keyword.py
deleted file mode 100644 (file)
index fcf6f2a..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Definition'
-        db.create_table(u'quizzes_definition', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('text', self.gf('django.db.models.fields.CharField')(max_length=2048)),
-            ('timestamp', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.utcnow)),
-        ))
-        db.send_create_signal(u'quizzes', ['Definition'])
-
-        # Adding model 'Keyword'
-        db.create_table(u'quizzes_keyword', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('word', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('definition', self.gf('django.db.models.fields.related.OneToOneField')(related_name='keyword', unique=True, to=orm['quizzes.Definition'])),
-            ('timestamp', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.utcnow)),
-        ))
-        db.send_create_signal(u'quizzes', ['Keyword'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Definition'
-        db.delete_table(u'quizzes_definition')
-
-        # Deleting model 'Keyword'
-        db.delete_table(u'quizzes_keyword')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'courses.course': {
-            'Meta': {'ordering': "['-file_count', 'school', 'name']", 'unique_together': "(('name', 'school'),)", 'object_name': 'Course'},
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'department': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['courses.Department']", 'null': 'True', 'blank': 'True'}),
-            'desc': ('django.db.models.fields.TextField', [], {'max_length': '511', 'null': 'True', 'blank': 'True'}),
-            'file_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'flags': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'instructor_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
-            'instructor_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'school': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['courses.School']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'null': 'True'}),
-            'updated_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
-            'url': ('django.db.models.fields.URLField', [], {'max_length': '511', 'null': 'True', 'blank': 'True'})
-        },
-        u'courses.department': {
-            'Meta': {'unique_together': "(('name', 'school'),)", 'object_name': 'Department'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'school': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['courses.School']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'null': 'True'}),
-            'url': ('django.db.models.fields.URLField', [], {'max_length': '511', 'null': 'True', 'blank': 'True'})
-        },
-        u'courses.school': {
-            'Meta': {'ordering': "['-file_count', '-priority', 'name']", 'object_name': 'School'},
-            'alias': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'facebook_id': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'file_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hashtag': ('django.db.models.fields.CharField', [], {'max_length': '16', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'location': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'priority': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'null': 'True'}),
-            'url': ('django.db.models.fields.URLField', [], {'max_length': '511', 'blank': 'True'}),
-            'usde_id': ('django.db.models.fields.BigIntegerField', [], {'unique': 'True', 'null': 'True', 'blank': 'True'})
-        },
-        u'licenses.license': {
-            'Meta': {'object_name': 'License'},
-            'html': ('django.db.models.fields.TextField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'})
-        },
-        u'notes.note': {
-            'Meta': {'ordering': "['-uploaded_at']", 'unique_together': "(('fp_file', 'upstream_link'),)", 'object_name': 'Note'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['courses.Course']"}),
-            'file_type': ('django.db.models.fields.CharField', [], {'default': "'???'", 'max_length': '15', 'null': 'True', 'blank': 'True'}),
-            'flags': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'fp_file': ('django_filepicker.models.FPFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'gdrive_url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
-            'is_hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'license': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['licenses.License']", 'null': 'True', 'blank': 'True'}),
-            'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'static_html': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'thanks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
-            'tweeted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow', 'null': 'True'}),
-            'upstream_link': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'year': ('django.db.models.fields.IntegerField', [], {'default': '2014', 'null': 'True', 'blank': 'True'})
-        },
-        u'quizzes.definition': {
-            'Meta': {'object_name': 'Definition'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'text': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        u'quizzes.flashcardquestion': {
-            'Meta': {'object_name': 'FlashCardQuestion'},
-            'category': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'difficulty': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'explanation': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'quiz': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['quizzes.Quiz']"}),
-            'sideA': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
-            'sideB': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        u'quizzes.keyword': {
-            'Meta': {'object_name': 'Keyword'},
-            'definition': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'keyword'", 'unique': 'True', 'to': u"orm['quizzes.Definition']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
-            'word': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        u'quizzes.multiplechoiceoption': {
-            'Meta': {'object_name': 'MultipleChoiceOption'},
-            'correct': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': u"orm['quizzes.MultipleChoiceQuestion']"}),
-            'text': ('django.db.models.fields.CharField', [], {'max_length': '2048'})
-        },
-        u'quizzes.multiplechoicequestion': {
-            'Meta': {'object_name': 'MultipleChoiceQuestion'},
-            'category': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'difficulty': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'explanation': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'question_text': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
-            'quiz': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['quizzes.Quiz']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        u'quizzes.quiz': {
-            'Meta': {'object_name': 'Quiz'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'note': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['notes.Note']", 'null': 'True', 'blank': 'True'}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        u'quizzes.truefalsequestion': {
-            'Meta': {'object_name': 'TrueFalseQuestion'},
-            'category': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'difficulty': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
-            'explanation': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'quiz': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['quizzes.Quiz']"}),
-            'text': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
-            'true': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['quizzes']
\ No newline at end of file
index 19a278a5cc03da6361ba16ff0f9a31e58fac7816..6e659dd31edb2981ff5506b38b4e7381118eebc7 100644 (file)
@@ -7,21 +7,17 @@ from django.db import models
 
 class Keyword(models.Model):
     word = models.CharField(max_length=1024)
-    definition = models.OneToOneField('quizzes.Definition', related_name='keyword')
+    definition = models.CharField(max_length=2048, blank=True, null=True)
 
-    timestamp = models.DateTimeField(default=datetime.datetime.utcnow)
-
-    def __unicode__(self):
-        return self.word
-
-
-class Definition(models.Model):
-    text = models.CharField(max_length=2048)
+    note = models.ForeignKey('notes.Note', blank=True, null=True)
 
     timestamp = models.DateTimeField(default=datetime.datetime.utcnow)
 
+    class Meta:
+        unique_together = ('word', 'note')
+
     def __unicode__(self):
-        return self.text
+        return self.word
 
 
 class Quiz(models.Model):
index f3e8702503bcd61d47166737932666661b760251..68601ead6f648e458d993247c25c3649afc43106 100644 (file)
@@ -2,17 +2,23 @@
 # -*- coding:utf8 -*-
 # Copyright (C) 2014  FinalsClub Foundation
 from itertools import chain
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.urlresolvers import reverse
+from django.forms.formsets import formset_factory
+from django.http import HttpResponseRedirect
 
-from django.views.generic import DetailView
-from karmaworld.apps.quizzes.models import Quiz, ALL_QUESTION_CLASSES
+from django.views.generic import DetailView, FormView
+from django.views.generic.detail import SingleObjectMixin
+from django.views.generic.edit import FormMixin, ProcessFormView
+from karmaworld.apps.notes.models import Note
+from karmaworld.apps.quizzes.forms import KeywordForm
+from karmaworld.apps.quizzes.models import Quiz, ALL_QUESTION_CLASSES, Keyword
 
 
 class QuizView(DetailView):
-
     queryset = Quiz.objects.all()
-
     model = Quiz
-    context_object_name = 'quiz' # name passed to template
+    context_object_name = 'quiz'  # name passed to template
     template_name = 'quizzes/quiz.html'
 
     def get_context_data(self, **kwargs):
@@ -30,3 +36,52 @@ class QuizView(DetailView):
 
         return super(QuizView, self).get_context_data(**kwargs)
 
+
+class KeywordEditView(FormView):
+    template_name = 'quizzes/keyword_edit.html'
+    form_class = formset_factory(KeywordForm)
+
+    def get(self, requests, *args, **kwargs):
+        self.lookup_note()
+        return super(KeywordEditView, self).get(requests, *args, **kwargs)
+
+    def post(self, requests, *args, **kwargs):
+        self.lookup_note()
+        return super(KeywordEditView, self).post(requests, *args, **kwargs)
+
+    def lookup_note(self):
+        self.note = Note.objects.get(pk=self.kwargs['pk'])
+
+    def get_success_url(self):
+        return reverse('keyword_edit', args=(self.note.pk,))
+
+    def get_initial(self):
+        existing_keywords = self.note.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 get_context_data(self, **kwargs):
+        kwargs['note'] = self.note
+        kwargs['prototype_form'] = KeywordForm
+        return super(KeywordEditView, self).get_context_data(**kwargs)
+
+    def 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()
+
+        return super(KeywordEditView, self).form_valid(formset)
+
diff --git a/karmaworld/assets/js/quiz.js b/karmaworld/assets/js/quiz.js
new file mode 100644 (file)
index 0000000..50c039e
--- /dev/null
@@ -0,0 +1,39 @@
+
+function addForm(event) {
+
+  // check for:
+  // key pressed was TAB
+  // key was pressed in last row
+  if (event.which == 9 &&
+      (!$(this).closest('div.keyword-form-row').next().hasClass('keyword-form-row'))) {
+
+    var prototypeFormString = $('#keyword-form-prototype').text();
+    var newForm = $('#keyword-form-rows').append(prototypeFormString).find('.keyword-form-row:last');
+    var totalForms = $('#id_form-TOTAL_FORMS').attr('value');
+    var newIdRoot = 'id_form-' + totalForms + '-';
+    var newNameRoot = 'form-' + totalForms + '-';
+
+    var keywordInput = newForm.find('.keyword');
+    console.log(newForm);
+    console.log(keywordInput);
+    keywordInput.attr('id', newIdRoot + 'keyword');
+    keywordInput.attr('name', newNameRoot + 'keyword');
+
+    var definitionInput = newForm.find('.definition');
+    definitionInput.attr('id', newIdRoot + 'definition');
+    definitionInput.attr('name', newNameRoot + 'definition');
+    definitionInput.keydown(addForm);
+
+    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);
+
+  }
+}
+
+$(function() {
+  $('.definition').keydown(addForm);
+});
+
diff --git a/karmaworld/templates/quizzes/keyword_edit.html b/karmaworld/templates/quizzes/keyword_edit.html
new file mode 100644 (file)
index 0000000..19eeb9b
--- /dev/null
@@ -0,0 +1,50 @@
+{% extends "base.html" %}
+{% load url from future %}
+{% load account %}
+
+{% block pagestyle %}
+  <link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}css/quiz.css">
+{% endblock %}
+
+{% block bodyscripts %}
+  <script src="{{ STATIC_URL }}js/quiz.js"></script>
+{% endblock %}
+
+{% block title %}
+  {{ note.name }}
+{% endblock %}
+
+{% block content %}
+  <section id="dashboard_content">
+    <div id="stats_container" class="hero_gradient_bar">
+      <div class="row">
+        <div class="small-10 columns small-centered center header_title">
+          <p>Define keywords for the note</p>
+          <p><a href="{{ note.get_absolute_url }}">{{ note.name }}</a></p>
+        </div>
+      </div>
+
+    </div>
+
+    <div id="activity_container">
+      <div class="row">
+        <div class="small-12 columns center">
+          <form id="keyword-form" action="{% url 'keyword_edit' note.id %}" method="post">
+            {% csrf_token %}
+            <div class="hide" id="keyword-form-prototype">
+              {{ prototype_form.as_p }}
+            </div>
+            <div id="keyword-form-rows">
+              {{ form.as_p }}
+            </div>
+            <button type="submit" name="action">Save</button>
+          </form>
+        </div>
+      </div>
+    </div>
+
+
+
+  </section>
+
+{% endblock %}
index a48d20e6344e02fe8bb9454dede09d3189e642f0..b16f827f98b15dabedc952b14bbafe4c3118765c 100644 (file)
@@ -20,7 +20,7 @@ from karmaworld.apps.notes.views import RawNoteDetailView
 from karmaworld.apps.notes.views import PDFView
 from karmaworld.apps.moderation import moderator
 from karmaworld.apps.document_upload.views import save_fp_upload
-from karmaworld.apps.quizzes.views import QuizView
+from karmaworld.apps.quizzes.views import QuizView, KeywordEditView
 from karmaworld.apps.users.views import ProfileView
 
 # See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#hooking-adminsite-instances-into-your-urlconf
@@ -69,6 +69,7 @@ urlpatterns = patterns('',
 
     # Quizzes
     url(r'^quiz/(?P<pk>\d+)/$', QuizView.as_view(), name='quiz'),
+    url(r'^note/(?P<pk>\d+)/keywords/$', KeywordEditView.as_view(), name='keyword_edit'),
 
     #url(r'^pdfview$', PDFView.as_view(), name='pdf'),
     url(r'^pdfview/(?P<pk>\d+)$', PDFView.as_view(), name='pdf'),