implements forms and wizard replacement
This commit is contained in:
parent
24696da391
commit
f1369f59ec
|
@ -0,0 +1,102 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Div, HTML, Field, Fieldset
|
||||
|
||||
from polynum.base.models import Entity
|
||||
from polynum.request import widgets , forms as request_forms
|
||||
|
||||
import django_ws
|
||||
|
||||
YEAR = '2012'
|
||||
DEFAULT_CATEGORY = ''
|
||||
|
||||
def categories():
|
||||
yield ('', '---')
|
||||
ok, response = django_ws.get_bb_conn().get_categories()
|
||||
if ok:
|
||||
for category in response.categories:
|
||||
yield (category.id, category.name)
|
||||
|
||||
class func2iter(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __iter__(self):
|
||||
return self.func()
|
||||
|
||||
|
||||
class CreateCourseForm(forms.Form):
|
||||
helper = FormHelper()
|
||||
helper.form_tag = False
|
||||
helper.layout = Layout(
|
||||
'description',
|
||||
'entity',
|
||||
'category',
|
||||
'td_group',
|
||||
'open_to_visitors',
|
||||
'subscription_policy',
|
||||
Div(Field('password'), css_class="hide"))
|
||||
|
||||
SUBSCRIPTION_POLICIES = (
|
||||
('auto', u'oui'),
|
||||
('password', u'avec mot de passe'),
|
||||
('no', u'non'))
|
||||
description = forms.CharField(max_length=32)
|
||||
entity = forms.ModelChoiceField(Entity.objects.all(), label=u'Diplôme')
|
||||
category = forms.ChoiceField(label=u'Catégorie',
|
||||
choices=func2iter(categories))
|
||||
td_group = forms.CharField(label=u'Groupe de TD', max_length=16,
|
||||
required=False)
|
||||
open_to_visitors = forms.BooleanField(label=u'Ouvert aux visiteurs',
|
||||
required=False)
|
||||
subscription_policy = forms.ChoiceField(label=u'Auto-inscription', choices=SUBSCRIPTION_POLICIES)
|
||||
password = forms.CharField(max_length=32)
|
||||
|
||||
def __init__(self, request=None, *args, **kwargs):
|
||||
self.request = request
|
||||
super(CreateCourseForm, self).__init__(*args, **kwargs)
|
||||
self.fields['entity'].widget = widgets.MillerColumns(attrs={'data-entity-type': 'etape'})
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = self.cleaned_data
|
||||
if not cleaned_data['category']:
|
||||
cleaned_data['category'] = DEFAULT_CATEGORY
|
||||
if cleaned_data['subscription_policy'] == 'password' and not cleaned_data['password']:
|
||||
raise forms.ValidationError(u'vous devez fournir un mot de passe')
|
||||
if cleaned_data['entity'].entity_type.name != 'element pedagogique':
|
||||
raise forms.ValidationError(u'vous devez sélectionner une UE')
|
||||
diplome_entity = cleaned_data['entity'].parents().get(entity_type__name='etape')
|
||||
cleaned_data['course_id'] = '{0}_{1}_{2}'.format(diplome_entity,
|
||||
YEAR, self.request.user.username)
|
||||
|
||||
return cleaned_data
|
||||
|
||||
class MyCourseForm(request_forms.CopyrigtsForm):
|
||||
send_to_mycourse = forms.BooleanField(
|
||||
label=u'Envoyer le document à MyCourse')
|
||||
visible_to_students = forms.BooleanField(
|
||||
label=u'Visible aux étudiants',
|
||||
initial=True)
|
||||
course_name = forms.CharField(max_length=64)
|
||||
|
||||
class Meta(request_forms.CopyrigtsForm.Meta):
|
||||
fields = ('copyright',)
|
||||
required = ('copyright',)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MyCourseForm, self).__init__(*args, **kwargs)
|
||||
self.fields['course_name'].widget = forms.HiddenInput()
|
||||
self.fields['send_to_mycourse'].initial = \
|
||||
settings.POLYNUM_BB_SEND_TO_MYCOURSE_DEFAULT
|
||||
self.helper.layout = Layout(
|
||||
'copyright',
|
||||
Fieldset(u'Diffusion sur la plateform d\'e-Learning',
|
||||
'send_to_mycourse',
|
||||
Div(
|
||||
'visible_to_students',
|
||||
HTML('{% include \'_select_course.html\' %}'),
|
||||
id='mycourse-block', css_class='hide')))
|
|
@ -0,0 +1,10 @@
|
|||
from django.db import models
|
||||
|
||||
from polynum.base.models import Request
|
||||
|
||||
class BlackBoardPush(models.Model):
|
||||
request = models.ForeignKey(Request)
|
||||
course_name = models.TextField(max_length=64)
|
||||
visible_to_students = models.BooleanField(blank=True)
|
||||
sent = models.BooleanField(blank=True)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
{% load sekizai_tags %}
|
||||
{% load url from future %}
|
||||
|
||||
<div class="course-selector" data-refresh-url="{% url 'courses_list' pk=object.pk %}">
|
||||
{% if courses.error %}
|
||||
<div class="alert alert-error">Impossible de récupérer la liste des cours: {{ course.error }}</div>
|
||||
{% else %}
|
||||
|
||||
<div class="control-group">
|
||||
<label for="course-type-owner" class="control-label">Mes cours</label>
|
||||
<div class="controls">
|
||||
<select {% if not courses.user_courses.courses %}disabled{% endif %} class="courses-selector">
|
||||
{% if not courses.user_courses.courses %}
|
||||
<option>Aucun cours disponible</option>
|
||||
{% else %}
|
||||
<option value="">---</option>
|
||||
{% for course in courses.user_courses.courses %}
|
||||
<option {% if not course.avaiblable %}disabled{% endif %} value="{{ course.id }}">{{ course.name }}</option>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</select>
|
||||
<a href="#create-course" role="button" class="btn" data-toggle="modal">Créer un nouveau cours</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="course-type-ue" class="control-label">Cours proches du document</label>
|
||||
<div class="controls">
|
||||
<select {% if not courses.ue_courses.courses %}disabled{% endif %} class="courses-selector">
|
||||
{% if not courses.ue_courses.courses %}
|
||||
<option>Aucun cours disponible</option>
|
||||
{% else %}
|
||||
<option value="">---</option>
|
||||
{% for course in courses.ue_courses.courses %}
|
||||
<option {% if not course.avaiblable %}disabled{% endif %} value="{{ course.id }}">{{ course.name }}</option>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% addtoblock "endscripts" %}
|
||||
<script>
|
||||
(function ($) {
|
||||
$(function () {
|
||||
$('body', 'change', '.courses-selector', function (){
|
||||
$('.courses-selector').not(this).val('');
|
||||
$('.courses-input').val($(this).val());
|
||||
});
|
||||
})
|
||||
})(window.jQuery)
|
||||
</script>
|
||||
{% endaddtoblock %}
|
|
@ -0,0 +1,73 @@
|
|||
{% extends "new_request.html" %}
|
||||
{% load url from future %}
|
||||
{% load sekizai_tags %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load editor %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
{{ block.super }}
|
||||
{{ create_course_form.media.css }}
|
||||
<style>
|
||||
#create-course .miller-columns {
|
||||
height: 10em;
|
||||
}
|
||||
.modal.large {
|
||||
margin: -250px 0px 0px -380px;
|
||||
width: 760px;
|
||||
}
|
||||
.modal.large .modal-body {
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
{% editablecontent wizard.steps.current "form-header" %}
|
||||
{% endeditablecontent %}
|
||||
|
||||
{{ wizard.management_form }}
|
||||
{% crispy wizard.form %}
|
||||
|
||||
{% editablecontent wizard.steps.current "form-footer" %}
|
||||
{% endeditablecontent %}
|
||||
|
||||
{% addtoblock "endscripts" %}
|
||||
<div id="create-course" class="modal hide fade large">
|
||||
<form action="{% url 'create_course' %}" method="POST">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Création d'un nouveau cours</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% crispy create_course_form %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-dismiss="modal" class="btn">Fermer</a>
|
||||
<button class="btn btn-primary">Créer</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ create_course_form.media.js }}
|
||||
<script>
|
||||
(function ($) {
|
||||
$(function () {
|
||||
$('#id_subscription_policy').on('change', function() {
|
||||
if ($(this).val() == 'password') {
|
||||
$('#div_id_password').parent().show();
|
||||
} else {
|
||||
$('#div_id_password').parent().hide();
|
||||
}
|
||||
});
|
||||
$('#create-course').on('shown', function () {
|
||||
$('.miller-columns').millercolumns('refresh');
|
||||
});
|
||||
$('#id_document_copyrights-send_to_mycourse').on('change', function () {
|
||||
$('#mycourse-block').toggle('slow');
|
||||
});
|
||||
$('#mycourse-block').toggle($('#id_document_copyrights-send_to_mycourse').is(':checked'));
|
||||
})
|
||||
})(window.jQuery)
|
||||
</script>
|
||||
{% endaddtoblock %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,152 @@
|
|||
<form class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label for="mycourse" class="control-label">Diffusion dans MyCourse</label>
|
||||
<div class="controls">
|
||||
{% with mycourse=1 %}
|
||||
<input type="checkbox" id="mycourse" name="mycourse" {% if mycourse %}checked{% endif %}>
|
||||
</div>
|
||||
<style>
|
||||
#diffusion { margin-left: 2em; border-left: 1px solid #DDD; padding: 1ex; }
|
||||
.element-pedagogique { color: green; font-weight: bold; }
|
||||
span.error { color: red }
|
||||
#course-type-new-block { display: none; }
|
||||
</style>
|
||||
{% if not mycourse %}
|
||||
<style>
|
||||
#diffusion { display: none; }
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div id="diffusion" class="control-group">
|
||||
<div class="control-group">
|
||||
<label for="visible" class="control-label">Fichier visible aux étudiants</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="visible" checked>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="control-type-owner" class="control-label">Dans un de mes cours</label>
|
||||
<div class="controls">
|
||||
<input type="radio" id="course-type-owner" name="course-type" {% if mycourse %}checked{% endif %}>
|
||||
<select id="courses-owner" class="courses">
|
||||
<option value="">---</option>
|
||||
<option disabled>A</option>
|
||||
<option disabled>B (indisponible)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="control-type-sponsor" class="control-label">Dans un cours du commanditaire</label>
|
||||
<div class="controls">
|
||||
<input type="radio" id="course-type-sponsor" name="course-type">
|
||||
<select id="courses-sponsor" class="courses">
|
||||
<option value="">---</option>
|
||||
<option>A</option>
|
||||
<option>B</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="control-type-ue" class="control-label">Dans un cours de l'UE </label>
|
||||
<div class="controls">
|
||||
<input type="radio" id="course-type-ue" name="course-type">
|
||||
<select id="courses-ue" class="courses">
|
||||
<option value="">---</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="control-type-new" class="control-label">Créer un nouveau cours</label>
|
||||
<div class="controls">
|
||||
<input type="radio" id="course-type-new" name="course-type">
|
||||
</div>
|
||||
<div class="controls" id="course-type-new-block">
|
||||
<div class="control-group">
|
||||
<label for="control-type-ue">UE du nouveau cours (les UE sont affichées en vert)</label>
|
||||
<input type="hidden" id="ue">
|
||||
<div id="ue-selector">
|
||||
</div>
|
||||
<label for="control-type-ue">Groupe de TD (facultatif)</label>
|
||||
<input type="text" id="td-group">
|
||||
<div class="control-group">
|
||||
<label for="control-type-new" class="control-label">Ouvert aux visiteurs</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="open-to-visitors">
|
||||
</div>
|
||||
</div>
|
||||
<p>Nom du nouveau cours: <span id="course-name"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{% addtoblock "css" %}
|
||||
<link href="{{STATIC_URL}}eo/css/eo.millercolumns.css" rel="stylesheet">
|
||||
{% endaddtoblock %}
|
||||
|
||||
{% addtoblock "endscripts" %}
|
||||
<script src="{{STATIC_URL}}jquery/js/jquery-ui.js"></script>
|
||||
<script src="{{STATIC_URL}}eo/js/eo.millercolumns.js"></script>
|
||||
<script src="{{STATIC_URL}}eo/js/eo.django.millercolumns.widget.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var MyCourseDelegate = PolynumDelegate('ue');
|
||||
function UpdateCourseName() {
|
||||
var item = $('#ue-selector').millercolumns('getSelection');
|
||||
var parents = MyCourseDelegate.getParents(item);
|
||||
var diplome;
|
||||
var ue = MyCourseDelegate._getItem(item);
|
||||
if (ue.type != 'element pedagogique') {
|
||||
$('#course-name').html('<span class="error">L\'entité sélectionnée n\'est pas une UE</span>');
|
||||
return;
|
||||
}
|
||||
for (i = parents.length - 1; i >= 0; i--) {
|
||||
var data = MyCourseDelegate._getItem(parents[i]);
|
||||
if (data.type == 'etape') {
|
||||
diplome = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var course_name = diplome.code+'_2012_'+ue.code+'_{{user.username}}';
|
||||
var group = $('#td-group').val();
|
||||
if (group) {
|
||||
course_name += '_' + group;
|
||||
}
|
||||
$('#course-name').text(course_name);
|
||||
}
|
||||
MyCourseDelegate.old_selectItem = MyCourseDelegate.selectItem;
|
||||
MyCourseDelegate.old_isLeaf = MyCourseDelegate.isLeaf;
|
||||
MyCourseDelegate.is
|
||||
MyCourseDelegate.selectItem = function (item) {
|
||||
$('#course-type-new').attr('checked', 1);
|
||||
this.old_selectItem(item);
|
||||
UpdateCourseName();
|
||||
}
|
||||
$('#td-group').keyup(function () {
|
||||
UpdateCourseName();
|
||||
});
|
||||
$('#ue-selector').millercolumns({delegate: MyCourseDelegate});
|
||||
if ('{{object.entity.id}}') {
|
||||
$('#ue-selector').millercolumns('setItem', '{{object.entity.id}}');
|
||||
}
|
||||
$('#mycourse').change(function () {
|
||||
$('#diffusion').toggle();
|
||||
return true;
|
||||
});
|
||||
$('.courses').each(function (i, v) {
|
||||
if ($('option', v).not('[disabled]').length < 2) {
|
||||
$('select, input', $(v).parent()).attr('disabled', 1);
|
||||
$('<span>Aucun cours disponible</span>').appendTo($(v).parent());
|
||||
}
|
||||
});
|
||||
$('#course-type-new').change(function (){
|
||||
$('#course-type-new-block').toggle();
|
||||
$('#ue-selector').millercolumns('refresh');
|
||||
UpdateCourseName();
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endaddtoblock %}
|
|
@ -0,0 +1,12 @@
|
|||
from django.conf.urls import patterns, include, url
|
||||
|
||||
import views
|
||||
import wizard
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^request/(?P<pk>\d+)/edit/(?P<step>.+)/$', wizard.request_wizard_step, name='request_wizard_step'),
|
||||
url(r'^request/(?P<pk>\d+)/edit/$', wizard.request_wizard_step, name='request_wizard'),
|
||||
url(r'^request/(?P<pk>\d+)/course-list/$', views.courses_list, name='courses_list'),
|
||||
url(r'bb/create_course/', views.create_course, name='create_course'),
|
||||
(r'^', include('polynum.urls')))
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import json
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.template import RequestContext
|
||||
from django.template.loader import render_to_string
|
||||
from django import shortcuts
|
||||
|
||||
from polynum.base.models import Request
|
||||
|
||||
import django_ws
|
||||
from forms import CreateCourseForm
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
def create_course(request):
|
||||
form = CreateCourseForm(request.POST, request=request)
|
||||
ctx = { 'form': form }
|
||||
if form.is_valid():
|
||||
conn = get_conn()
|
||||
course_id = form.cleaned_data['course_id']
|
||||
ok, result = conn.create_course(course_id,
|
||||
form.cleaned_data['description'],
|
||||
form.cleaned_data['category'],
|
||||
form.cleaned_data['open_to_visitors'],
|
||||
form.cleaned_data['subscription_policy'] != 'no',
|
||||
form.cleaned_data['password'])
|
||||
ctx['ok'], ctx['result'] = ok, result
|
||||
form = CreateCourseForm(request=request)
|
||||
data = {
|
||||
"html": render_to_string("_create_course.html", ctx,
|
||||
context_instance=RequestContext(request))
|
||||
}
|
||||
return HttpResponse(json.dumps(data), mimetype="application/json")
|
||||
|
||||
@login_required
|
||||
def courses_list(request, pk):
|
||||
polynum_request = shortcuts.get_object_or_404(Request, pk=pk)
|
||||
data = { "html": render_to_string("_select_course.html", {
|
||||
"courses": courses_ctx(request, polynum_request)},
|
||||
context_instance=RequestContext(request)) }
|
||||
return HttpResponse(json.dumps(data), mimetype="application/json")
|
||||
|
||||
def courses_ctx(request, polynum_request):
|
||||
ctx = {}
|
||||
conn = django_ws.get_bb_conn()
|
||||
ok, result = conn.get_course_by_owner(request.user.username)
|
||||
if not ok:
|
||||
ctx['error'] = result
|
||||
return ctx
|
||||
user_courses = result
|
||||
if polynum_request.entity:
|
||||
ok, result = conn.get_course_by_ue(polynum_request.entity.code)
|
||||
if not ok:
|
||||
ctx['error'] = result
|
||||
return ctx
|
||||
ue_courses = result
|
||||
return {
|
||||
'ue_courses': ue_courses,
|
||||
'user_courses': user_courses,
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from polynum.request import views as request_views
|
||||
|
||||
import forms
|
||||
import views
|
||||
|
||||
named_new_request_forms = []
|
||||
|
||||
for step, form_class in request_views.named_new_request_forms:
|
||||
p = (step, form_class)
|
||||
if step == 'document_copyrights':
|
||||
p = (step, forms.MyCourseForm)
|
||||
named_new_request_forms.append(p)
|
||||
|
||||
class RequestWizardView(request_views.RequestWizardView):
|
||||
def get_context_data(self, form, **kwargs):
|
||||
context = super(RequestWizardView, self).get_context_data(form=form, **kwargs)
|
||||
polynum_request = self.get_object()
|
||||
diplome_entity = polynum_request.entity
|
||||
if diplome_entity:
|
||||
possible_diplome_entity = diplome_entity.parents(True).filter(entity_type__name='etape')
|
||||
if possible_diplome_entity:
|
||||
diplome_entity = possible_diplome_entity[0]
|
||||
context['create_course_form'] = forms.CreateCourseForm(request=self.request,
|
||||
initial={'entity': diplome_entity})
|
||||
context['courses'] = views.courses_ctx(self.request, polynum_request)
|
||||
return context
|
||||
|
||||
request_wizard_step = login_required(RequestWizardView.as_view(named_new_request_forms,
|
||||
done_step_name='finished', url_name='request_wizard_step'))
|
Reference in New Issue