├── portal
├── __init__.py
├── migrations
│ ├── __init__.py
│ ├── 0002_auto_20170712_1441.py
│ ├── 0003_auto_20170712_1441.py
│ ├── 0004_auto_20170713_1325.py
│ └── 0001_initial.py
├── static
│ ├── img
│ │ ├── bg.jpg
│ │ ├── i1.jpg
│ │ ├── banner.jpg
│ │ ├── favicon.png
│ │ ├── overlay.png
│ │ └── iiitalogo.jpg
│ ├── js
│ │ ├── main.js
│ │ ├── skel.min.js
│ │ ├── jquery.poptrox.min.js
│ │ └── util.js
│ └── css
│ │ ├── fill_feedback(main).css
│ │ └── student_view.css
├── tests.py
├── urls.py
├── apps.py
├── forms.py
├── admin.py
├── templates
│ ├── portal
│ │ ├── base.html
│ │ ├── student_view(archive).html
│ │ ├── index.html
│ │ └── student_view.html
│ └── registration
│ │ └── login.html
├── views.py
└── models.py
├── geekhaven
├── __init__.py
├── wsgi.py
├── urls.py
└── settings.py
├── requirements.txt
├── .gitignore
└── manage.py
/portal/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/geekhaven/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/portal/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==1.11.4
2 | django-widget-tweaks==1.4.1
3 | pytz==2017.2
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *~
3 | __pycache__
4 | venvir
5 | db.sqlite3
6 | /static
7 | .DS_Store
8 |
--------------------------------------------------------------------------------
/portal/static/img/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/bg.jpg
--------------------------------------------------------------------------------
/portal/static/img/i1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/i1.jpg
--------------------------------------------------------------------------------
/portal/static/img/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/banner.jpg
--------------------------------------------------------------------------------
/portal/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/favicon.png
--------------------------------------------------------------------------------
/portal/static/img/overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/overlay.png
--------------------------------------------------------------------------------
/portal/static/img/iiitalogo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fossiiita/feedback-portal/master/portal/static/img/iiitalogo.jpg
--------------------------------------------------------------------------------
/portal/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/portal/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from . import views
3 | urlpatterns = [
4 | url(r'^$', views.home, name="home"),
5 | url(r'^fill/$', views.fill, name="fill"),
6 | ]
--------------------------------------------------------------------------------
/portal/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class PortalConfig(AppConfig):
8 | name = 'portal'
9 |
--------------------------------------------------------------------------------
/portal/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from models import Feedback_Theory
3 |
4 | class Feedback_Theoryform(forms.ModelForm):
5 |
6 | class Meta:
7 | model = Feedback_Theory
8 | exclude = ['feedback_given_at','user']
--------------------------------------------------------------------------------
/geekhaven/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for geekhaven project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geekhaven.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/portal/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.contrib import admin
5 | from .models import Student, Professor, Course, Professor_And_Students, Feedback_Theory, Feedback_Lab, Permissions
6 | # Register your models here.
7 | admin.site.register(Student)
8 | admin.site.register(Professor)
9 | admin.site.register(Course)
10 | admin.site.register(Professor_And_Students)
11 | admin.site.register(Feedback_Theory)
12 | admin.site.register(Feedback_Lab)
13 | admin.site.register(Permissions)
--------------------------------------------------------------------------------
/portal/migrations/0002_auto_20170712_1441.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 09:11
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('portal', '0001_initial'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='professor',
17 | name='dean_or_director',
18 | field=models.BooleanField(default=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/portal/migrations/0003_auto_20170712_1441.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 09:11
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('portal', '0002_auto_20170712_1441'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='professor',
17 | name='dean_or_director',
18 | field=models.BooleanField(default=False),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/portal/migrations/0004_auto_20170713_1325.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-13 07:55
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('portal', '0003_auto_20170712_1441'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='feedback_lab',
17 | name='textual_question_2',
18 | field=models.CharField(max_length=600),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/portal/templates/portal/base.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
5 | {% block title %}{% endblock %}
6 |
7 |
8 |
9 |
10 | {% block extend_head %}{% endblock %}
11 |
12 |
13 | {% block content %}
14 | {% endblock %}
15 |
16 |
17 |
--------------------------------------------------------------------------------
/portal/views.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.shortcuts import render
5 | from django.http import HttpResponse
6 | from forms import Feedback_Theoryform
7 | # Create your views here.
8 | def home(request):
9 | return render(request, 'portal/home.html', {})
10 |
11 | #def student(request):
12 | # return render(request, 'portal/student_view.html', {})
13 |
14 | def fill(request):
15 | if request.method == "POST":
16 | form = Feedback_Theoryform(request.POST)
17 | if form.is_valid():
18 | detail = form.save(commit=False)
19 | detail.user = request.user
20 | detail.save()
21 | return HttpResponse("done")
22 | else:
23 | form = Feedback_Theoryform()
24 | return render(request, 'portal/student_view.html', {"form":form})
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geekhaven.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError:
10 | # The above import may fail for some other reason. Ensure that the
11 | # issue is really that Django is missing to avoid masking other
12 | # exceptions on Python 2.
13 | try:
14 | import django
15 | except ImportError:
16 | raise ImportError(
17 | "Couldn't import Django. Are you sure it's installed and "
18 | "available on your PYTHONPATH environment variable? Did you "
19 | "forget to activate a virtual environment?"
20 | )
21 | raise
22 | execute_from_command_line(sys.argv)
23 |
--------------------------------------------------------------------------------
/geekhaven/urls.py:
--------------------------------------------------------------------------------
1 | """geekhaven URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.11/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf.urls import include, url
17 | from django.contrib import admin
18 | from django.contrib.auth import views as auth_views
19 |
20 | urlpatterns = [
21 | url(r'^$', auth_views.login, name='login'),
22 | url(r'^logout/$', auth_views.logout, name='logout'),
23 | url(r'', include('portal.urls')),
24 | url(r'^admin/', admin.site.urls),
25 | ]
26 |
--------------------------------------------------------------------------------
/portal/models.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models
5 | from django.conf import settings
6 | # Create your models here.
7 | class Student(models.Model):
8 | user = models.ForeignKey(settings.AUTH_USER_MODEL)
9 | semester = models.IntegerField()
10 |
11 | def __str__(self):
12 | return self.user.username
13 |
14 | class Professor(models.Model):
15 | user = models.ForeignKey(settings.AUTH_USER_MODEL)
16 | dean_or_director = models.BooleanField(default=False)
17 |
18 | def __str__(self):
19 | return self.user.username
20 |
21 | class Course(models.Model):
22 | name = models.CharField(max_length=200)
23 | code = models.CharField(max_length=100)
24 | assigned_to_professor = models.ManyToManyField(Professor)
25 | students_of_course = models.ManyToManyField(Student)
26 | is_course_lab = models.BooleanField(default=False)
27 |
28 | def __str__(self):
29 | return self.name
30 | class Professor_And_Students(models.Model):
31 | course_name = models.ForeignKey(Course)
32 | professor = models.ForeignKey(Professor)
33 | students = models.ManyToManyField(Student)
34 |
35 | def __str__(self):
36 | return self.course_name.name + ' - ' + self.professor.user.username
37 |
38 | class Feedback_Theory(models.Model):
39 | user = models.ForeignKey(settings.AUTH_USER_MODEL)
40 | student = models.ForeignKey(Professor_And_Students)
41 | mcq_1 = models.IntegerField()
42 | mcq_2 = models.IntegerField()
43 | mcq_3 = models.IntegerField()
44 | textual_question_1 = models.CharField(max_length=500)
45 | textual_question_2 = models.CharField(max_length=500)
46 | feedback_given_at = models.DateTimeField(auto_now_add=True)
47 |
48 | def __str__(self):
49 | return self.student.course_name.name + ' - ' + self.student.professor.user.username
50 |
51 | class Feedback_Lab(models.Model):
52 | student = models.ForeignKey(Professor_And_Students)
53 | mcq_1 = models.IntegerField()
54 | mcq_2 = models.IntegerField()
55 | mcq_3 = models.IntegerField()
56 | textual_question_1 = models.CharField(max_length=500)
57 | textual_question_2 = models.CharField(max_length=600)
58 | feedback_given_at = models.DateTimeField(auto_now_add=True)
59 |
60 | def __str__(self):
61 | return self.student.course_name.name + ' - ' + self.student.professor.user.username
62 |
63 | class Permissions(models.Model):
64 | user = models.ForeignKey(settings.AUTH_USER_MODEL)
65 | dean_or_director = models.BooleanField(default=False)
66 |
67 | class Meta:
68 | permissions = (("can_view_superview", "can view superview"),
69 | ("can_view_normalview", "can view normalview"),
70 | )
71 | def __str__(self):
72 | return self.user.username
--------------------------------------------------------------------------------
/portal/templates/registration/login.html:
--------------------------------------------------------------------------------
1 | {% extends 'portal/base.html' %}
2 | {% load staticfiles %}
3 | {% load widget_tweaks %}
4 | {% block title %}Portal-Login{% endblock %}
5 | {% block extend_head %}
6 |
7 | {% endblock %}
8 | {% block content %}
9 |
10 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Welcome to IIIT Allahabad Faculty Feedback Portal
41 |
42 | Guidelines for submitting feedback
43 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris egestas venenatis purus, ut aliquet lectus semper non. Aenean molestie, augue sed elementum pellentesque, quam arcu finibus libero, ut vulputate arcu elit a enim. Sed felis arcu, scelerisque vel ornare a, vestibulum nec enim. Nulla euismod vehicula arcu, consectetur euismod lacus condimentum fringilla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum gravida diam et purus
44 |
45 |
46 |
47 |
48 |
49 |
50 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 | {% endblock %}
--------------------------------------------------------------------------------
/portal/templates/portal/student_view(archive).html:
--------------------------------------------------------------------------------
1 | {% extends 'portal/base.html' %}
2 | {% load staticfiles %}
3 | {% load widget_tweaks %}
4 | {% block title %}Portal-View{% endblock %}
5 | {% block extend_head %}
6 |
7 | {% endblock %}
8 | {% block content %}
9 |
10 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Courses You Are Currently Enrolled In
32 | Click On The Respective Course To Give Feedback
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | Serial No.
42 | Course Code
43 | Course Name
44 | Professor
45 | Feedback Status
46 |
47 |
48 |
49 |
50 | 1
51 | IDST230C
52 | Data Structure
53 | Dr. Rahul Kala
54 | Not Given
55 |
56 |
57 | 2
58 | IDST230C
59 | Data Structure
60 | Dr. Rahul Kala
61 | Not Given
62 |
63 |
64 | 3
65 | IDST230C
66 | Data Structure
67 | Dr. Rahul Kala
68 | Not Given
69 |
70 |
71 | 4
72 | IDST230C
73 | Data Structure
74 | Dr. Rahul Kala
75 | Not Given
76 |
77 |
78 | 5
79 | IDST230C
80 | Data Structure
81 | Dr. Rahul Kala
82 | Not Given
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | {% endblock %}
--------------------------------------------------------------------------------
/portal/static/js/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | Strata by HTML5 UP
3 | html5up.net | @ajlkn
4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | */
6 |
7 | (function($) {
8 |
9 | var settings = {
10 |
11 | // Parallax background effect?
12 | parallax: true,
13 |
14 | // Parallax factor (lower = more intense, higher = less intense).
15 | parallaxFactor: 20
16 |
17 | };
18 |
19 | skel.breakpoints({
20 | xlarge: '(max-width: 1800px)',
21 | large: '(max-width: 1280px)',
22 | medium: '(max-width: 980px)',
23 | small: '(max-width: 736px)',
24 | xsmall: '(max-width: 480px)'
25 | });
26 |
27 | $(function() {
28 |
29 | var $window = $(window),
30 | $body = $('body'),
31 | $header = $('#header'),
32 | $footer = $('#footer'),
33 | $main = $('#main');
34 |
35 | // Disable animations/transitions until the page has loaded.
36 | $body.addClass('is-loading');
37 |
38 | $window.on('load', function() {
39 | $body.removeClass('is-loading');
40 | });
41 |
42 | // Touch?
43 | if (skel.vars.mobile) {
44 |
45 | // Turn on touch mode.
46 | $body.addClass('is-touch');
47 |
48 | // Height fix (mostly for iOS).
49 | window.setTimeout(function() {
50 | $window.scrollTop($window.scrollTop() + 1);
51 | }, 0);
52 |
53 | }
54 |
55 | // Fix: Placeholder polyfill.
56 | $('form').placeholder();
57 |
58 | // Prioritize "important" elements on medium.
59 | skel.on('+medium -medium', function() {
60 | $.prioritize(
61 | '.important\\28 medium\\29',
62 | skel.breakpoint('medium').active
63 | );
64 | });
65 |
66 | // Footer.
67 | skel.on('+medium', function() {
68 | $footer.insertAfter($main);
69 | });
70 |
71 | skel.on('-medium !medium', function() {
72 | $footer.appendTo($header);
73 | });
74 |
75 | // Header.
76 |
77 | // Parallax background.
78 |
79 | // Disable parallax on IE (smooth scrolling is jerky), and on mobile platforms (= better performance).
80 | if (skel.vars.browser == 'ie'
81 | || skel.vars.mobile)
82 | settings.parallax = false;
83 |
84 | if (settings.parallax) {
85 |
86 | skel.on('change', function() {
87 |
88 | if (skel.breakpoint('medium').active) {
89 |
90 | $window.off('scroll.strata_parallax');
91 | $header.css('background-position', 'top left, center center');
92 |
93 | }
94 | else {
95 |
96 | $header.css('background-position', 'left 0px');
97 |
98 | $window.on('scroll.strata_parallax', function() {
99 | $header.css('background-position', 'left ' + (-1 * (parseInt($window.scrollTop()) / settings.parallaxFactor)) + 'px');
100 | });
101 |
102 | }
103 |
104 | });
105 |
106 | $window.on('load', function() {
107 | $window.triggerHandler('scroll');
108 | });
109 |
110 | }
111 |
112 | // Main Sections: Two.
113 |
114 | // Lightbox gallery.
115 | $window.on('load', function() {
116 |
117 | $('#two').poptrox({
118 | caption: function($a) { return $a.next('h3').text(); },
119 | overlayColor: '#2c2c2c',
120 | overlayOpacity: 0.85,
121 | popupCloserText: '',
122 | popupLoaderText: '',
123 | selector: '.work-item a.image',
124 | usePopupCaption: true,
125 | usePopupDefaultStyling: false,
126 | usePopupEasyClose: false,
127 | usePopupNav: true,
128 | windowMargin: (skel.breakpoint('small').active ? 0 : 50)
129 | });
130 |
131 | });
132 |
133 | });
134 |
135 | })(jQuery);
--------------------------------------------------------------------------------
/geekhaven/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for geekhaven project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.11.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.11/ref/settings/
11 | """
12 |
13 | import os
14 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
15 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16 |
17 |
18 | # Quick-start development settings - unsuitable for production
19 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
20 |
21 | # SECURITY WARNING: keep the secret key used in production secret!
22 | SECRET_KEY = '*aa$pbdwd715-t*8v6w%1(r*w0!q#n3$o&zhs54&$axwb(u96#'
23 |
24 | # SECURITY WARNING: don't run with debug turned on in production!
25 | DEBUG = True
26 |
27 | ALLOWED_HOSTS = []
28 |
29 |
30 | # Application definition
31 |
32 | INSTALLED_APPS = [
33 | 'django.contrib.admin',
34 | 'django.contrib.auth',
35 | 'django.contrib.contenttypes',
36 | 'django.contrib.sessions',
37 | 'django.contrib.messages',
38 | 'django.contrib.staticfiles',
39 | 'portal',
40 | 'widget_tweaks'
41 | ]
42 |
43 | MIDDLEWARE = [
44 | 'django.middleware.security.SecurityMiddleware',
45 | 'django.contrib.sessions.middleware.SessionMiddleware',
46 | 'django.middleware.common.CommonMiddleware',
47 | 'django.middleware.csrf.CsrfViewMiddleware',
48 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
49 | 'django.contrib.messages.middleware.MessageMiddleware',
50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
51 | ]
52 |
53 | ROOT_URLCONF = 'geekhaven.urls'
54 |
55 | TEMPLATES = [
56 | {
57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
58 | 'DIRS': [],
59 | 'APP_DIRS': True,
60 | 'OPTIONS': {
61 | 'context_processors': [
62 | 'django.template.context_processors.debug',
63 | 'django.template.context_processors.request',
64 | 'django.contrib.auth.context_processors.auth',
65 | 'django.contrib.messages.context_processors.messages',
66 | ],
67 | },
68 | },
69 | ]
70 |
71 | WSGI_APPLICATION = 'geekhaven.wsgi.application'
72 |
73 |
74 | # Database
75 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
76 |
77 | DATABASES = {
78 | 'default': {
79 | 'ENGINE': 'django.db.backends.sqlite3',
80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
81 | }
82 | }
83 |
84 |
85 | # Password validation
86 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
87 |
88 | AUTH_PASSWORD_VALIDATORS = [
89 | {
90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
91 | },
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97 | },
98 | {
99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100 | },
101 | ]
102 |
103 | # Internationalization
104 | # https://docs.djangoproject.com/en/1.11/topics/i18n/
105 |
106 | LOGIN_REDIRECT_URL = '/view'
107 |
108 | LANGUAGE_CODE = 'en-us'
109 |
110 | TIME_ZONE = 'Asia/Kolkata'
111 |
112 | USE_I18N = True
113 |
114 | USE_L10N = True
115 |
116 | USE_TZ = True
117 |
118 |
119 | # Static files (CSS, JavaScript, Images)
120 | # https://docs.djangoproject.com/en/1.11/howto/static-files/
121 |
122 | STATIC_URL = '/static/'
123 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
124 | STATICFILES_DIRS = (
125 | os.path.join(BASE_DIR, 'portfolio/static'),
126 | )
--------------------------------------------------------------------------------
/portal/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 09:11
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16 | ]
17 |
18 | operations = [
19 | migrations.CreateModel(
20 | name='Course',
21 | fields=[
22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 | ('name', models.CharField(max_length=200)),
24 | ('code', models.CharField(max_length=100)),
25 | ('is_course_lab', models.BooleanField(default=False)),
26 | ],
27 | ),
28 | migrations.CreateModel(
29 | name='Feedback_Lab',
30 | fields=[
31 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
32 | ('mcq_1', models.IntegerField()),
33 | ('mcq_2', models.IntegerField()),
34 | ('mcq_3', models.IntegerField()),
35 | ('textual_question_1', models.CharField(max_length=500)),
36 | ('textual_question_2', models.CharField(max_length=500)),
37 | ('feedback_given_at', models.DateTimeField(auto_now_add=True)),
38 | ],
39 | ),
40 | migrations.CreateModel(
41 | name='Feedback_Theory',
42 | fields=[
43 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
44 | ('mcq_1', models.IntegerField()),
45 | ('mcq_2', models.IntegerField()),
46 | ('mcq_3', models.IntegerField()),
47 | ('textual_question_1', models.CharField(max_length=500)),
48 | ('textual_question_2', models.CharField(max_length=500)),
49 | ('feedback_given_at', models.DateTimeField(auto_now_add=True)),
50 | ],
51 | ),
52 | migrations.CreateModel(
53 | name='Permissions',
54 | fields=[
55 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
56 | ('dean_or_director', models.BooleanField(default=False)),
57 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
58 | ],
59 | options={
60 | 'permissions': (('can_view_superview', 'can view superview'), ('can_view_normalview', 'can view normalview')),
61 | },
62 | ),
63 | migrations.CreateModel(
64 | name='Professor',
65 | fields=[
66 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
67 | ('dean_or_director', models.BooleanField(default=False)),
68 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
69 | ],
70 | ),
71 | migrations.CreateModel(
72 | name='Professor_And_Students',
73 | fields=[
74 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
75 | ('course_name', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='portal.Course')),
76 | ('professor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='portal.Professor')),
77 | ],
78 | ),
79 | migrations.CreateModel(
80 | name='Student',
81 | fields=[
82 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
83 | ('semester', models.IntegerField()),
84 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
85 | ],
86 | ),
87 | migrations.AddField(
88 | model_name='professor_and_students',
89 | name='students',
90 | field=models.ManyToManyField(to='portal.Student'),
91 | ),
92 | migrations.AddField(
93 | model_name='feedback_theory',
94 | name='student',
95 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='portal.Professor_And_Students'),
96 | ),
97 | migrations.AddField(
98 | model_name='feedback_theory',
99 | name='user',
100 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
101 | ),
102 | migrations.AddField(
103 | model_name='feedback_lab',
104 | name='student',
105 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='portal.Professor_And_Students'),
106 | ),
107 | migrations.AddField(
108 | model_name='course',
109 | name='assigned_to_professor',
110 | field=models.ManyToManyField(to='portal.Professor'),
111 | ),
112 | migrations.AddField(
113 | model_name='course',
114 | name='students_of_course',
115 | field=models.ManyToManyField(to='portal.Student'),
116 | ),
117 | ]
118 |
--------------------------------------------------------------------------------
/portal/static/css/fill_feedback(main).css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2015 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | Note: any .css or .scss files included in the 'styles' directory
19 | will be correctly compiled during `gulp serve` and `gulp`
20 | */
21 |
22 | html, body {
23 | font-family: 'Roboto', 'Helvetica', sans-serif;
24 | margin: 0;
25 | padding: 0;
26 | background-image: url("../img/banner.jpg");
27 | background-repeat: no-repeat;
28 | background-size: cover;
29 | }
30 | .mdl-demo .mdl-layout__header-row {
31 | padding-left: 40px;
32 | }
33 | .mdl-demo .mdl-layout.is-small-screen .mdl-layout__header-row h3 {
34 | font-size: inherit;
35 | }
36 | .mdl-demo .mdl-layout__tab-bar-button {
37 | display: none;
38 | }
39 | .mdl-demo .mdl-layout.is-small-screen .mdl-layout__tab-bar .mdl-button {
40 | display: none;
41 | }
42 | .mdl-demo .mdl-layout:not(.is-small-screen) .mdl-layout__tab-bar,
43 | .mdl-demo .mdl-layout:not(.is-small-screen) .mdl-layout__tab-bar-container {
44 | overflow: visible;
45 | }
46 | .mdl-demo .mdl-layout__tab-bar-container {
47 | height: 64px;
48 | }
49 | .mdl-demo .mdl-layout__tab-bar {
50 | padding: 0;
51 | padding-left: 16px;
52 | box-sizing: border-box;
53 | height: 100%;
54 | width: 100%;
55 | }
56 | .mdl-demo .mdl-layout__tab-bar .mdl-layout__tab {
57 | height: 64px;
58 | line-height: 64px;
59 | }
60 | .mdl-demo .mdl-layout__tab-bar .mdl-layout__tab.is-active::after {
61 | background-color: white;
62 | height: 4px;
63 | }
64 | .mdl-demo main > .mdl-layout__tab-panel {
65 | padding: 8px;
66 | padding-top: 48px;
67 | }
68 | .mdl-demo .mdl-card {
69 | height: auto;
70 | display: flex;
71 | flex-direction: column;
72 | }
73 | .mdl-demo .mdl-card > * {
74 | height: auto;
75 | }
76 | .mdl-demo .mdl-card .mdl-card__supporting-text {
77 | margin: 40px;
78 | flex-grow: 1;
79 | padding: 0;
80 | color: inherit;
81 | width: calc(100% - 80px);
82 | }
83 | .mdl-demo.mdl-demo .mdl-card__supporting-text h4 {
84 | margin-top: 0;
85 | margin-bottom: 20px;
86 | }
87 | .mdl-demo .mdl-card__actions {
88 | margin: 0;
89 | padding: 4px 40px;
90 | color: inherit;
91 | }
92 | .mdl-demo .mdl-card__actions a {
93 | color: #00BCD4;
94 | margin: 0;
95 | }
96 | .mdl-demo .mdl-card__actions a:hover,
97 | .mdl-demo .mdl-card__actions a:active {
98 | color: inherit;
99 | background-color: transparent;
100 | }
101 | .mdl-demo .mdl-card__supporting-text + .mdl-card__actions {
102 | border-top: 1px solid rgba(0, 0, 0, 0.12);
103 | }
104 | .mdl-demo #add {
105 | position: absolute;
106 | right: 40px;
107 | top: 36px;
108 | z-index: 999;
109 | }
110 |
111 | .mdl-demo .mdl-layout__content section:not(:last-of-type) {
112 | position: relative;
113 | margin-bottom: 48px;
114 | }
115 | .mdl-demo section.section--center {
116 | max-width: 1060px;
117 | }
118 | .mdl-demo #features section.section--center {
119 | max-width: 620px;
120 | }
121 | .mdl-demo section > header{
122 | display: flex;
123 | align-items: center;
124 | justify-content: center;
125 | }
126 | .mdl-demo section > .section__play-btn {
127 | min-height: 200px;
128 | }
129 | .mdl-demo section > header > .material-icons {
130 | font-size: 3rem;
131 | }
132 | .mdl-demo section > button {
133 | position: absolute;
134 | z-index: 99;
135 | top: 8px;
136 | right: 8px;
137 | }
138 | .mdl-demo section .section__circle {
139 | display: flex;
140 | align-items: center;
141 | justify-content: flex-start;
142 | flex-grow: 0;
143 | flex-shrink: 1;
144 | }
145 | .mdl-demo section .section__text {
146 | flex-grow: 1;
147 | flex-shrink: 0;
148 | padding-top: 8px;
149 | }
150 | .mdl-demo section .section__text h5 {
151 | font-size: inherit;
152 | margin: 0;
153 | margin-bottom: 0.5em;
154 | }
155 | .mdl-demo section .section__text a {
156 | text-decoration: none;
157 | }
158 | .mdl-demo section .section__circle-container > .section__circle-container__circle {
159 | width: 64px;
160 | height: 64px;
161 | border-radius: 32px;
162 | margin: 8px 0;
163 | }
164 | .mdl-demo section.section--footer .section__circle--big {
165 | width: 100px;
166 | height: 100px;
167 | border-radius: 50px;
168 | margin: 8px 32px;
169 | }
170 | .mdl-demo .is-small-screen section.section--footer .section__circle--big {
171 | width: 50px;
172 | height: 50px;
173 | border-radius: 25px;
174 | margin: 8px 16px;
175 | }
176 | .mdl-demo section.section--footer {
177 | padding: 64px 0;
178 | margin: 0 -8px -8px -8px;
179 | }
180 | .mdl-demo section.section--center .section__text:not(:last-child) {
181 | border-bottom: 1px solid rgba(0,0,0,.13);
182 | }
183 | .mdl-demo .mdl-card .mdl-card__supporting-text > h3:first-child {
184 | margin-bottom: 24px;
185 | }
186 |
187 | .mdl-demo #features section {
188 | margin-bottom: 72px;
189 | }
190 | .mdl-demo #features h4, #features h5 {
191 | margin-bottom: 16px;
192 | }
193 | .mdl-demo .toc {
194 | border-left: 4px solid #C1EEF4;
195 | margin: 24px;
196 | padding: 0;
197 | padding-left: 8px;
198 | display: flex;
199 | flex-direction: column;
200 | }
201 | .mdl-demo .toc h4 {
202 | font-size: 0.9rem;
203 | margin-top: 0;
204 | }
205 | .mdl-demo .toc a {
206 | color: #4DD0E1;
207 | text-decoration: none;
208 | font-size: 16px;
209 | line-height: 28px;
210 | display: block;
211 | }
212 | .mdl-demo .mdl-menu__container {
213 | z-index: 99;
214 | }
215 | footer.mdl-mega-footer{
216 | background-color: #272833;
217 | }
--------------------------------------------------------------------------------
/portal/static/js/skel.min.js:
--------------------------------------------------------------------------------
1 | /* skel.js v3.0.1 | (c) skel.io | MIT licensed */
2 | var skel=function(){"use strict";var t={breakpointIds:null,events:{},isInit:!1,obj:{attachments:{},breakpoints:{},head:null,states:{}},sd:"/",state:null,stateHandlers:{},stateId:"",vars:{},DOMReady:null,indexOf:null,isArray:null,iterate:null,matchesMedia:null,extend:function(e,n){t.iterate(n,function(i){t.isArray(n[i])?(t.isArray(e[i])||(e[i]=[]),t.extend(e[i],n[i])):"object"==typeof n[i]?("object"!=typeof e[i]&&(e[i]={}),t.extend(e[i],n[i])):e[i]=n[i]})},newStyle:function(t){var e=document.createElement("style");return e.type="text/css",e.innerHTML=t,e},_canUse:null,canUse:function(e){t._canUse||(t._canUse=document.createElement("div"));var n=t._canUse.style,i=e.charAt(0).toUpperCase()+e.slice(1);return e in n||"Moz"+i in n||"Webkit"+i in n||"O"+i in n||"ms"+i in n},on:function(e,n){var i=e.split(/[\s]+/);return t.iterate(i,function(e){var a=i[e];if(t.isInit){if("init"==a)return void n();if("change"==a)n();else{var r=a.charAt(0);if("+"==r||"!"==r){var o=a.substring(1);if(o in t.obj.breakpoints)if("+"==r&&t.obj.breakpoints[o].active)n();else if("!"==r&&!t.obj.breakpoints[o].active)return void n()}}}t.events[a]||(t.events[a]=[]),t.events[a].push(n)}),t},trigger:function(e){return t.events[e]&&0!=t.events[e].length?(t.iterate(t.events[e],function(n){t.events[e][n]()}),t):void 0},breakpoint:function(e){return t.obj.breakpoints[e]},breakpoints:function(e){function n(t,e){this.name=this.id=t,this.media=e,this.active=!1,this.wasActive=!1}return n.prototype.matches=function(){return t.matchesMedia(this.media)},n.prototype.sync=function(){this.wasActive=this.active,this.active=this.matches()},t.iterate(e,function(i){t.obj.breakpoints[i]=new n(i,e[i])}),window.setTimeout(function(){t.poll()},0),t},addStateHandler:function(e,n){t.stateHandlers[e]=n},callStateHandler:function(e){var n=t.stateHandlers[e]();t.iterate(n,function(e){t.state.attachments.push(n[e])})},changeState:function(e){t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].sync()}),t.vars.lastStateId=t.stateId,t.stateId=e,t.breakpointIds=t.stateId===t.sd?[]:t.stateId.substring(1).split(t.sd),t.obj.states[t.stateId]?t.state=t.obj.states[t.stateId]:(t.obj.states[t.stateId]={attachments:[]},t.state=t.obj.states[t.stateId],t.iterate(t.stateHandlers,t.callStateHandler)),t.detachAll(t.state.attachments),t.attachAll(t.state.attachments),t.vars.stateId=t.stateId,t.vars.state=t.state,t.trigger("change"),t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].active?t.obj.breakpoints[e].wasActive||t.trigger("+"+e):t.obj.breakpoints[e].wasActive&&t.trigger("-"+e)})},generateStateConfig:function(e,n){var i={};return t.extend(i,e),t.iterate(t.breakpointIds,function(e){t.extend(i,n[t.breakpointIds[e]])}),i},getStateId:function(){var e="";return t.iterate(t.obj.breakpoints,function(n){var i=t.obj.breakpoints[n];i.matches()&&(e+=t.sd+i.id)}),e},poll:function(){var e="";e=t.getStateId(),""===e&&(e=t.sd),e!==t.stateId&&t.changeState(e)},_attach:null,attach:function(e){var n=t.obj.head,i=e.element;return i.parentNode&&i.parentNode.tagName?!1:(t._attach||(t._attach=n.firstChild),n.insertBefore(i,t._attach.nextSibling),e.permanent&&(t._attach=i),!0)},attachAll:function(e){var n=[];t.iterate(e,function(t){n[e[t].priority]||(n[e[t].priority]=[]),n[e[t].priority].push(e[t])}),n.reverse(),t.iterate(n,function(e){t.iterate(n[e],function(i){t.attach(n[e][i])})})},detach:function(t){var e=t.element;return t.permanent||!e.parentNode||e.parentNode&&!e.parentNode.tagName?!1:(e.parentNode.removeChild(e),!0)},detachAll:function(e){var n={};t.iterate(e,function(t){n[e[t].id]=!0}),t.iterate(t.obj.attachments,function(e){e in n||t.detach(t.obj.attachments[e])})},attachment:function(e){return e in t.obj.attachments?t.obj.attachments[e]:null},newAttachment:function(e,n,i,a){return t.obj.attachments[e]={id:e,element:n,priority:i,permanent:a}},init:function(){t.initMethods(),t.initVars(),t.initEvents(),t.obj.head=document.getElementsByTagName("head")[0],t.isInit=!0,t.trigger("init")},initEvents:function(){t.on("resize",function(){t.poll()}),t.on("orientationChange",function(){t.poll()}),t.DOMReady(function(){t.trigger("ready")}),window.onload&&t.on("load",window.onload),window.onload=function(){t.trigger("load")},window.onresize&&t.on("resize",window.onresize),window.onresize=function(){t.trigger("resize")},window.onorientationchange&&t.on("orientationChange",window.onorientationchange),window.onorientationchange=function(){t.trigger("orientationChange")}},initMethods:function(){document.addEventListener?!function(e,n){t.DOMReady=n()}("domready",function(){function t(t){for(r=1;t=n.shift();)t()}var e,n=[],i=document,a="DOMContentLoaded",r=/^loaded|^c/.test(i.readyState);return i.addEventListener(a,e=function(){i.removeEventListener(a,e),t()}),function(t){r?t():n.push(t)}}):!function(e,n){t.DOMReady=n()}("domready",function(t){function e(t){for(h=1;t=i.shift();)t()}var n,i=[],a=!1,r=document,o=r.documentElement,s=o.doScroll,c="DOMContentLoaded",d="addEventListener",u="onreadystatechange",l="readyState",f=s?/^loaded|^c/:/^loaded|c/,h=f.test(r[l]);return r[d]&&r[d](c,n=function(){r.removeEventListener(c,n,a),e()},a),s&&r.attachEvent(u,n=function(){/^c/.test(r[l])&&(r.detachEvent(u,n),e())}),t=s?function(e){self!=top?h?e():i.push(e):function(){try{o.doScroll("left")}catch(n){return setTimeout(function(){t(e)},50)}e()}()}:function(t){h?t():i.push(t)}}),Array.prototype.indexOf?t.indexOf=function(t,e){return t.indexOf(e)}:t.indexOf=function(t,e){if("string"==typeof t)return t.indexOf(e);var n,i,a=e?e:0;if(!this)throw new TypeError;if(i=this.length,0===i||a>=i)return-1;for(0>a&&(a=i-Math.abs(a)),n=a;i>n;n++)if(this[n]===t)return n;return-1},Array.isArray?t.isArray=function(t){return Array.isArray(t)}:t.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},Object.keys?t.iterate=function(t,e){if(!t)return[];var n,i=Object.keys(t);for(n=0;i[n]&&e(i[n],t[i[n]])!==!1;n++);}:t.iterate=function(t,e){if(!t)return[];var n;for(n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&e(n,t[n])===!1)break},window.matchMedia?t.matchesMedia=function(t){return""==t?!0:window.matchMedia(t).matches}:window.styleMedia||window.media?t.matchesMedia=function(t){if(""==t)return!0;var e=window.styleMedia||window.media;return e.matchMedium(t||"all")}:window.getComputedStyle?t.matchesMedia=function(t){if(""==t)return!0;var e=document.createElement("style"),n=document.getElementsByTagName("script")[0],i=null;e.type="text/css",e.id="matchmediajs-test",n.parentNode.insertBefore(e,n),i="getComputedStyle"in window&&window.getComputedStyle(e,null)||e.currentStyle;var a="@media "+t+"{ #matchmediajs-test { width: 1px; } }";return e.styleSheet?e.styleSheet.cssText=a:e.textContent=a,"1px"===i.width}:t.matchesMedia=function(t){if(""==t)return!0;var e,n,i,a,r={"min-width":null,"max-width":null},o=!1;for(i=t.split(/\s+and\s+/),e=0;er["max-width"]||null!==r["min-height"]&&cr["max-height"]?!1:!0},navigator.userAgent.match(/MSIE ([0-9]+)/)&&RegExp.$1<9&&(t.newStyle=function(t){var e=document.createElement("span");return e.innerHTML=' ",e})},initVars:function(){var e,n,i,a=navigator.userAgent;e="other",n=0,i=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(RegExp.$1),!1):void 0}),t.vars.browser=e,t.vars.browserVersion=n,e="other",n=0,i=[["ios",/([0-9_]+) like Mac OS X/,function(t){return t.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(t){return 0}],["wp",/Windows Phone ([0-9\.]+)/,null],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(t){return t.replace("_",".").replace("_","")}],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(i[2]?i[2](RegExp.$1):RegExp.$1),!1):void 0}),t.vars.os=e,t.vars.osVersion=n,t.vars.IEVersion="ie"==t.vars.browser?t.vars.browserVersion:99,t.vars.touch="wp"==t.vars.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),t.vars.mobile="wp"==t.vars.os||"android"==t.vars.os||"ios"==t.vars.os||"bb"==t.vars.os}};return t.init(),t}();!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.skel=e()}(this,function(){return skel});
3 |
--------------------------------------------------------------------------------
/portal/static/js/jquery.poptrox.min.js:
--------------------------------------------------------------------------------
1 | /* jquery.poptrox.js v2.5.2-dev | (c) @ajlkn | github.com/ajlkn/jquery.poptrox | MIT licensed */
2 | !function(e){e.fn.poptrox_disableSelection=function(){return e(this).css("user-select","none").css("-khtml-user-select","none").css("-moz-user-select","none").css("-o-user-select","none").css("-webkit-user-select","none")},e.fn.poptrox=function(o){function t(){i=e(window).width(),s=e(window).height()+r.windowHeightPad;var o=Math.abs(x.width()-x.outerWidth()),t=Math.abs(x.height()-x.outerHeight()),p=(w.width(),w.height(),i-2*r.windowMargin-o),n=s-2*r.windowMargin-t;x.css("min-width",r.popupWidth).css("min-height",r.popupHeight),v.children().css("max-width",p).css("max-height",n)}if(0==this.length)return e(this);if(this.length>1){for(var p=0;p'),u=e(window),d=[],h=0,g=!1,f=new Array;r.usePopupLoader||(r.popupLoaderSelector=null),r.usePopupCloser||(r.popupCloserSelector=null),r.usePopupCaption||(r.popupCaptionSelector=null),r.usePopupNav||(r.popupNavPreviousSelector=null,r.popupNavNextSelector=null);var x;x=e(r.popupSelector?r.popupSelector:'");var v=x.find(".pic"),w=e(),b=x.find(r.popupLoaderSelector),m=x.find(r.popupCaptionSelector),C=x.find(r.popupCloserSelector),y=x.find(r.popupNavNextSelector),S=x.find(r.popupNavPreviousSelector),P=y.add(S);if(r.usePopupDefaultStyling&&(x.css("background",r.popupBackgroundColor).css("color",r.popupTextColor).css("padding",r.popupPadding+"px"),m.length>0&&(x.css("padding-bottom",r.popupCaptionHeight+"px"),m.css("position","absolute").css("left","0").css("bottom","0").css("width","100%").css("text-align","center").css("height",r.popupCaptionHeight+"px").css("line-height",r.popupCaptionHeight+"px"),r.popupCaptionTextSize&&m.css("font-size",popupCaptionTextSize)),C.length>0&&C.html(r.popupCloserText).css("font-size",r.popupCloserTextSize).css("background",r.popupCloserBackgroundColor).css("color",r.popupCloserTextColor).css("display","block").css("width","40px").css("height","40px").css("line-height","40px").css("text-align","center").css("position","absolute").css("text-decoration","none").css("outline","0").css("top","0").css("right","-40px"),b.length>0&&b.html("").css("position","relative").css("font-size",r.popupLoaderTextSize).on("startSpinning",function(o){var t=e(""+r.popupLoaderText+"
");t.css("height",Math.floor(r.popupHeight/2)+"px").css("overflow","hidden").css("line-height",Math.floor(r.popupHeight/2)+"px").css("text-align","center").css("margin-top",Math.floor((x.height()-t.height()+(m.length>0?m.height():0))/2)).css("color",r.popupTextColor?r.popupTextColor:"").on("xfin",function(){t.fadeTo(300,.5,function(){t.trigger("xfout")})}).on("xfout",function(){t.fadeTo(300,.05,function(){t.trigger("xfin")})}).trigger("xfin"),b.append(t)}).on("stopSpinning",function(e){var o=b.find("div");o.remove()}),2==P.length)){P.css("font-size","75px").css("text-align","center").css("color","#fff").css("text-shadow","none").css("height","100%").css("position","absolute").css("top","0").css("opacity","0.35").css("cursor","pointer").css("box-shadow","inset 0px 0px 10px 0px rgba(0,0,0,0)").poptrox_disableSelection();var k,T;r.usePopupEasyClose?(k="100px",T="100px"):(k="75%",T="25%"),y.css("right","0").css("width",k).html('>
'),S.css("left","0").css("width",T).html('<
')}return u.on("resize orientationchange",function(){t()}),m.on("update",function(e,o){o&&0!=o.length||(o=r.popupBlankCaptionText),m.html(o)}),C.css("cursor","pointer").on("click",function(e){return e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_close"),!0}),y.on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_next")}),S.on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_previous")}),l.css("position","fixed").css("left",0).css("top",0).css("z-index",r.baseZIndex).css("width","100%").css("height","100%").css("text-align","center").css("cursor","pointer").appendTo(r.parent).prepend('
').append('
').hide().on("touchmove",function(e){return!1}).on("click",function(e){e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_close")}),x.css("display","inline-block").css("vertical-align","middle").css("position","relative").css("z-index",1).css("cursor","auto").appendTo(l).hide().on("poptrox_next",function(){var e=h+1;e>=d.length&&(e=0),x.trigger("poptrox_switch",[e])}).on("poptrox_previous",function(){var e=h-1;0>e&&(e=d.length-1),x.trigger("poptrox_switch",[e])}).on("poptrox_reset",function(){t(),x.data("width",r.popupWidth).data("height",r.popupHeight),b.hide().trigger("stopSpinning"),m.hide(),C.hide(),P.hide(),v.hide(),w.attr("src","").detach()}).on("poptrox_open",function(e,o){return g?!0:(g=!0,r.useBodyOverflow&&a.css("overflow","hidden"),r.onPopupOpen&&r.onPopupOpen(),x.addClass("loading"),void l.fadeTo(r.fadeSpeed,1,function(){x.trigger("poptrox_switch",[o,!0])}))}).on("poptrox_switch",function(o,p,i){var s;if(!i&&g)return!0;if(g=!0,x.addClass("loading").css("width",x.data("width")).css("height",x.data("height")),m.hide(),w.attr("src")&&w.attr("src",""),w.detach(),s=d[p],w=s.object,w.off("load"),v.css("text-indent","-9999px").show().append(w),"ajax"==s.type?e.get(s.src,function(e){w.html(e),w.trigger("load")}):w.attr("src",s.src),"image"!=s.type){var n,a;n=s.width,a=s.height,"%"==n.slice(-1)&&(n=parseInt(n.substring(0,n.length-1))/100*u.width()),"%"==a.slice(-1)&&(a=parseInt(a.substring(0,a.length-1))/100*u.height()),w.css("position","relative").css("outline","0").css("z-index",r.baseZIndex+100).width(n).height(a)}b.trigger("startSpinning").fadeIn(300),x.show(),r.popupIsFixed?(x.removeClass("loading").width(r.popupWidth).height(r.popupHeight),w.load(function(){w.off("load"),b.hide().trigger("stopSpinning"),m.trigger("update",[s.captionText]).fadeIn(r.fadeSpeed),C.fadeIn(r.fadeSpeed),v.css("text-indent",0).hide().fadeIn(r.fadeSpeed,function(){g=!1}),h=p,P.fadeIn(r.fadeSpeed)})):w.load(function(){t(),w.off("load"),b.hide().trigger("stopSpinning");var e=w.width(),o=w.height(),i=function(){m.trigger("update",[s.captionText]).fadeIn(r.fadeSpeed),C.fadeIn(r.fadeSpeed),v.css("text-indent",0).hide().fadeIn(r.fadeSpeed,function(){g=!1}),h=p,P.fadeIn(r.fadeSpeed),x.removeClass("loading").data("width",e).data("height",o).css("width","auto").css("height","auto")};e==x.data("width")&&o==x.data("height")?i():x.animate({width:e,height:o},r.popupSpeed,"swing",i)}),"image"!=s.type&&w.trigger("load")}).on("poptrox_close",function(){return g&&!r.usePopupForceClose?!0:(g=!0,x.hide().trigger("poptrox_reset"),r.onPopupClose&&r.onPopupClose(),void l.fadeOut(r.fadeSpeed,function(){r.useBodyOverflow&&a.css("overflow","auto"),g=!1}))}).trigger("poptrox_reset"),r.usePopupEasyClose?(m.on("click","a",function(e){e.stopPropagation()}),x.css("cursor","pointer").on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_close")})):x.on("click",function(e){e.stopPropagation()}),u.keydown(function(e){if(x.is(":visible"))switch(e.keyCode){case 37:case 32:if(r.usePopupNav)return x.trigger("poptrox_previous"),!1;break;case 39:if(r.usePopupNav)return x.trigger("poptrox_next"),!1;break;case 27:return x.trigger("poptrox_close"),!1}}),n.find(r.selector).each(function(o){var t,p,i=e(this),s=i.find("img"),n=i.data("poptrox");if("ignore"!=n&&i.attr("href")){if(t={src:i.attr("href"),captionText:s.attr("title"),width:null,height:null,type:null,object:null,options:null},r.caption){if("function"==typeof r.caption)c=r.caption(i);else if("selector"in r.caption){var a;a=i.find(r.caption.selector),"attribute"in r.caption?c=a.attr(r.caption.attribute):(c=a.html(),r.caption.remove===!0&&a.remove())}}else c=s.attr("title");if(t.captionText=c,n){var l=n.split(",");0 in l&&(t.type=l[0]),1 in l&&(p=l[1].match(/([0-9%]+)x([0-9%]+)/),p&&3==p.length&&(t.width=p[1],t.height=p[2])),2 in l&&(t.options=l[2])}if(!t.type)switch(p=t.src.match(/\/\/([a-z0-9\.]+)\/.*/),(!p||p.length<2)&&(p=[!1]),p[1]){case"api.soundcloud.com":t.type="soundcloud";break;case"youtu.be":t.type="youtube";break;case"vimeo.com":t.type="vimeo";break;case"wistia.net":t.type="wistia";break;case"bcove.me":t.type="bcove";break;default:t.type="image"}switch(p=t.src.match(/\/\/[a-z0-9\.]+\/(.*)/),t.type){case"iframe":t.object=e(''),t.object.on("click",function(e){e.stopPropagation()}).css("cursor","auto"),t.width&&t.height||(t.width="600",t.height="400");break;case"ajax":t.object=e('
'),t.object.on("click",function(e){e.stopPropagation()}).css("cursor","auto").css("overflow","auto"),t.width&&t.height||(t.width="600",t.height="400");break;case"soundcloud":t.object=e(''),t.src="//w.soundcloud.com/player/?url="+escape(t.src)+(t.options?"&"+t.options:""),t.width="600",t.height="166";break;case"youtube":t.object=e(''),t.src="//www.youtube.com/embed/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"vimeo":t.object=e(''),t.src="//player.vimeo.com/video/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"wistia":t.object=e(''),t.src="//fast.wistia.net/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"bcove":t.object=e(''),t.src="//bcove.me/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="640",t.height="360");break;default:if(t.object=e(' '),r.preload){var p=document.createElement("img");p.src=t.src,f.push(p)}t.width=i.attr("width"),t.height=i.attr("height")}"file:"==window.location.protocol&&t.src.match(/^\/\//)&&(t.src="http:"+t.src),d.push(t),s.removeAttr("title"),i.removeAttr("href").css("cursor","pointer").css("outline",0).on("click",function(e){e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_open",[o])})}}),n.prop("_poptrox",r),n}}(jQuery);
3 |
--------------------------------------------------------------------------------
/portal/static/js/util.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 |
3 | /**
4 | * Generate an indented list of links from a nav. Meant for use with panel().
5 | * @return {jQuery} jQuery object.
6 | */
7 | $.fn.navList = function() {
8 |
9 | var $this = $(this);
10 | $a = $this.find('a'),
11 | b = [];
12 |
13 | $a.each(function() {
14 |
15 | var $this = $(this),
16 | indent = Math.max(0, $this.parents('li').length - 1),
17 | href = $this.attr('href'),
18 | target = $this.attr('target');
19 |
20 | b.push(
21 | '' +
26 | ' ' +
27 | $this.text() +
28 | ' '
29 | );
30 |
31 | });
32 |
33 | return b.join('');
34 |
35 | };
36 |
37 | /**
38 | * Panel-ify an element.
39 | * @param {object} userConfig User config.
40 | * @return {jQuery} jQuery object.
41 | */
42 | $.fn.panel = function(userConfig) {
43 |
44 | // No elements?
45 | if (this.length == 0)
46 | return $this;
47 |
48 | // Multiple elements?
49 | if (this.length > 1) {
50 |
51 | for (var i=0; i < this.length; i++)
52 | $(this[i]).panel(userConfig);
53 |
54 | return $this;
55 |
56 | }
57 |
58 | // Vars.
59 | var $this = $(this),
60 | $body = $('body'),
61 | $window = $(window),
62 | id = $this.attr('id'),
63 | config;
64 |
65 | // Config.
66 | config = $.extend({
67 |
68 | // Delay.
69 | delay: 0,
70 |
71 | // Hide panel on link click.
72 | hideOnClick: false,
73 |
74 | // Hide panel on escape keypress.
75 | hideOnEscape: false,
76 |
77 | // Hide panel on swipe.
78 | hideOnSwipe: false,
79 |
80 | // Reset scroll position on hide.
81 | resetScroll: false,
82 |
83 | // Reset forms on hide.
84 | resetForms: false,
85 |
86 | // Side of viewport the panel will appear.
87 | side: null,
88 |
89 | // Target element for "class".
90 | target: $this,
91 |
92 | // Class to toggle.
93 | visibleClass: 'visible'
94 |
95 | }, userConfig);
96 |
97 | // Expand "target" if it's not a jQuery object already.
98 | if (typeof config.target != 'jQuery')
99 | config.target = $(config.target);
100 |
101 | // Panel.
102 |
103 | // Methods.
104 | $this._hide = function(event) {
105 |
106 | // Already hidden? Bail.
107 | if (!config.target.hasClass(config.visibleClass))
108 | return;
109 |
110 | // If an event was provided, cancel it.
111 | if (event) {
112 |
113 | event.preventDefault();
114 | event.stopPropagation();
115 |
116 | }
117 |
118 | // Hide.
119 | config.target.removeClass(config.visibleClass);
120 |
121 | // Post-hide stuff.
122 | window.setTimeout(function() {
123 |
124 | // Reset scroll position.
125 | if (config.resetScroll)
126 | $this.scrollTop(0);
127 |
128 | // Reset forms.
129 | if (config.resetForms)
130 | $this.find('form').each(function() {
131 | this.reset();
132 | });
133 |
134 | }, config.delay);
135 |
136 | };
137 |
138 | // Vendor fixes.
139 | $this
140 | .css('-ms-overflow-style', '-ms-autohiding-scrollbar')
141 | .css('-webkit-overflow-scrolling', 'touch');
142 |
143 | // Hide on click.
144 | if (config.hideOnClick) {
145 |
146 | $this.find('a')
147 | .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
148 |
149 | $this
150 | .on('click', 'a', function(event) {
151 |
152 | var $a = $(this),
153 | href = $a.attr('href'),
154 | target = $a.attr('target');
155 |
156 | if (!href || href == '#' || href == '' || href == '#' + id)
157 | return;
158 |
159 | // Cancel original event.
160 | event.preventDefault();
161 | event.stopPropagation();
162 |
163 | // Hide panel.
164 | $this._hide();
165 |
166 | // Redirect to href.
167 | window.setTimeout(function() {
168 |
169 | if (target == '_blank')
170 | window.open(href);
171 | else
172 | window.location.href = href;
173 |
174 | }, config.delay + 10);
175 |
176 | });
177 |
178 | }
179 |
180 | // Event: Touch stuff.
181 | $this.on('touchstart', function(event) {
182 |
183 | $this.touchPosX = event.originalEvent.touches[0].pageX;
184 | $this.touchPosY = event.originalEvent.touches[0].pageY;
185 |
186 | })
187 |
188 | $this.on('touchmove', function(event) {
189 |
190 | if ($this.touchPosX === null
191 | || $this.touchPosY === null)
192 | return;
193 |
194 | var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
195 | diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
196 | th = $this.outerHeight(),
197 | ts = ($this.get(0).scrollHeight - $this.scrollTop());
198 |
199 | // Hide on swipe?
200 | if (config.hideOnSwipe) {
201 |
202 | var result = false,
203 | boundary = 20,
204 | delta = 50;
205 |
206 | switch (config.side) {
207 |
208 | case 'left':
209 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
210 | break;
211 |
212 | case 'right':
213 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
214 | break;
215 |
216 | case 'top':
217 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
218 | break;
219 |
220 | case 'bottom':
221 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
222 | break;
223 |
224 | default:
225 | break;
226 |
227 | }
228 |
229 | if (result) {
230 |
231 | $this.touchPosX = null;
232 | $this.touchPosY = null;
233 | $this._hide();
234 |
235 | return false;
236 |
237 | }
238 |
239 | }
240 |
241 | // Prevent vertical scrolling past the top or bottom.
242 | if (($this.scrollTop() < 0 && diffY < 0)
243 | || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
244 |
245 | event.preventDefault();
246 | event.stopPropagation();
247 |
248 | }
249 |
250 | });
251 |
252 | // Event: Prevent certain events inside the panel from bubbling.
253 | $this.on('click touchend touchstart touchmove', function(event) {
254 | event.stopPropagation();
255 | });
256 |
257 | // Event: Hide panel if a child anchor tag pointing to its ID is clicked.
258 | $this.on('click', 'a[href="#' + id + '"]', function(event) {
259 |
260 | event.preventDefault();
261 | event.stopPropagation();
262 |
263 | config.target.removeClass(config.visibleClass);
264 |
265 | });
266 |
267 | // Body.
268 |
269 | // Event: Hide panel on body click/tap.
270 | $body.on('click touchend', function(event) {
271 | $this._hide(event);
272 | });
273 |
274 | // Event: Toggle.
275 | $body.on('click', 'a[href="#' + id + '"]', function(event) {
276 |
277 | event.preventDefault();
278 | event.stopPropagation();
279 |
280 | config.target.toggleClass(config.visibleClass);
281 |
282 | });
283 |
284 | // Window.
285 |
286 | // Event: Hide on ESC.
287 | if (config.hideOnEscape)
288 | $window.on('keydown', function(event) {
289 |
290 | if (event.keyCode == 27)
291 | $this._hide(event);
292 |
293 | });
294 |
295 | return $this;
296 |
297 | };
298 |
299 | /**
300 | * Apply "placeholder" attribute polyfill to one or more forms.
301 | * @return {jQuery} jQuery object.
302 | */
303 | $.fn.placeholder = function() {
304 |
305 | // Browser natively supports placeholders? Bail.
306 | if (typeof (document.createElement('input')).placeholder != 'undefined')
307 | return $(this);
308 |
309 | // No elements?
310 | if (this.length == 0)
311 | return $this;
312 |
313 | // Multiple elements?
314 | if (this.length > 1) {
315 |
316 | for (var i=0; i < this.length; i++)
317 | $(this[i]).placeholder();
318 |
319 | return $this;
320 |
321 | }
322 |
323 | // Vars.
324 | var $this = $(this);
325 |
326 | // Text, TextArea.
327 | $this.find('input[type=text],textarea')
328 | .each(function() {
329 |
330 | var i = $(this);
331 |
332 | if (i.val() == ''
333 | || i.val() == i.attr('placeholder'))
334 | i
335 | .addClass('polyfill-placeholder')
336 | .val(i.attr('placeholder'));
337 |
338 | })
339 | .on('blur', function() {
340 |
341 | var i = $(this);
342 |
343 | if (i.attr('name').match(/-polyfill-field$/))
344 | return;
345 |
346 | if (i.val() == '')
347 | i
348 | .addClass('polyfill-placeholder')
349 | .val(i.attr('placeholder'));
350 |
351 | })
352 | .on('focus', function() {
353 |
354 | var i = $(this);
355 |
356 | if (i.attr('name').match(/-polyfill-field$/))
357 | return;
358 |
359 | if (i.val() == i.attr('placeholder'))
360 | i
361 | .removeClass('polyfill-placeholder')
362 | .val('');
363 |
364 | });
365 |
366 | // Password.
367 | $this.find('input[type=password]')
368 | .each(function() {
369 |
370 | var i = $(this);
371 | var x = $(
372 | $('')
373 | .append(i.clone())
374 | .remove()
375 | .html()
376 | .replace(/type="password"/i, 'type="text"')
377 | .replace(/type=password/i, 'type=text')
378 | );
379 |
380 | if (i.attr('id') != '')
381 | x.attr('id', i.attr('id') + '-polyfill-field');
382 |
383 | if (i.attr('name') != '')
384 | x.attr('name', i.attr('name') + '-polyfill-field');
385 |
386 | x.addClass('polyfill-placeholder')
387 | .val(x.attr('placeholder')).insertAfter(i);
388 |
389 | if (i.val() == '')
390 | i.hide();
391 | else
392 | x.hide();
393 |
394 | i
395 | .on('blur', function(event) {
396 |
397 | event.preventDefault();
398 |
399 | var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
400 |
401 | if (i.val() == '') {
402 |
403 | i.hide();
404 | x.show();
405 |
406 | }
407 |
408 | });
409 |
410 | x
411 | .on('focus', function(event) {
412 |
413 | event.preventDefault();
414 |
415 | var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
416 |
417 | x.hide();
418 |
419 | i
420 | .show()
421 | .focus();
422 |
423 | })
424 | .on('keypress', function(event) {
425 |
426 | event.preventDefault();
427 | x.val('');
428 |
429 | });
430 |
431 | });
432 |
433 | // Events.
434 | $this
435 | .on('submit', function() {
436 |
437 | $this.find('input[type=text],input[type=password],textarea')
438 | .each(function(event) {
439 |
440 | var i = $(this);
441 |
442 | if (i.attr('name').match(/-polyfill-field$/))
443 | i.attr('name', '');
444 |
445 | if (i.val() == i.attr('placeholder')) {
446 |
447 | i.removeClass('polyfill-placeholder');
448 | i.val('');
449 |
450 | }
451 |
452 | });
453 |
454 | })
455 | .on('reset', function(event) {
456 |
457 | event.preventDefault();
458 |
459 | $this.find('select')
460 | .val($('option:first').val());
461 |
462 | $this.find('input,textarea')
463 | .each(function() {
464 |
465 | var i = $(this),
466 | x;
467 |
468 | i.removeClass('polyfill-placeholder');
469 |
470 | switch (this.type) {
471 |
472 | case 'submit':
473 | case 'reset':
474 | break;
475 |
476 | case 'password':
477 | i.val(i.attr('defaultValue'));
478 |
479 | x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
480 |
481 | if (i.val() == '') {
482 | i.hide();
483 | x.show();
484 | }
485 | else {
486 | i.show();
487 | x.hide();
488 | }
489 |
490 | break;
491 |
492 | case 'checkbox':
493 | case 'radio':
494 | i.attr('checked', i.attr('defaultValue'));
495 | break;
496 |
497 | case 'text':
498 | case 'textarea':
499 | i.val(i.attr('defaultValue'));
500 |
501 | if (i.val() == '') {
502 | i.addClass('polyfill-placeholder');
503 | i.val(i.attr('placeholder'));
504 | }
505 |
506 | break;
507 |
508 | default:
509 | i.val(i.attr('defaultValue'));
510 | break;
511 |
512 | }
513 | });
514 |
515 | });
516 |
517 | return $this;
518 |
519 | };
520 |
521 | /**
522 | * Moves elements to/from the first positions of their respective parents.
523 | * @param {jQuery} $elements Elements (or selector) to move.
524 | * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
525 | */
526 | $.prioritize = function($elements, condition) {
527 |
528 | var key = '__prioritize';
529 |
530 | // Expand $elements if it's not already a jQuery object.
531 | if (typeof $elements != 'jQuery')
532 | $elements = $($elements);
533 |
534 | // Step through elements.
535 | $elements.each(function() {
536 |
537 | var $e = $(this), $p,
538 | $parent = $e.parent();
539 |
540 | // No parent? Bail.
541 | if ($parent.length == 0)
542 | return;
543 |
544 | // Not moved? Move it.
545 | if (!$e.data(key)) {
546 |
547 | // Condition is false? Bail.
548 | if (!condition)
549 | return;
550 |
551 | // Get placeholder (which will serve as our point of reference for when this element needs to move back).
552 | $p = $e.prev();
553 |
554 | // Couldn't find anything? Means this element's already at the top, so bail.
555 | if ($p.length == 0)
556 | return;
557 |
558 | // Move element to top of parent.
559 | $e.prependTo($parent);
560 |
561 | // Mark element as moved.
562 | $e.data(key, $p);
563 |
564 | }
565 |
566 | // Moved already?
567 | else {
568 |
569 | // Condition is true? Bail.
570 | if (condition)
571 | return;
572 |
573 | $p = $e.data(key);
574 |
575 | // Move element back to its original location (using our placeholder).
576 | $e.insertAfter($p);
577 |
578 | // Unmark element as moved.
579 | $e.removeData(key);
580 |
581 | }
582 |
583 | });
584 |
585 | };
586 |
587 | })(jQuery);
--------------------------------------------------------------------------------
/portal/templates/portal/index.html:
--------------------------------------------------------------------------------
1 | {% extends 'portal/base.html' %}
2 | {% load staticfiles %}
3 | {% load widget_tweaks %}
4 | {% block title %}Portal-Fill{% endblock %}
5 | {% block extend_head %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
41 |
42 |
43 |
44 | {% endblock %}
45 | {% block content %}
46 |