Des formulaires magnifiques

This commit is contained in:
Evarin 2017-04-15 20:03:08 +02:00
parent 6c966ccb9c
commit 6e91b6cebb
7 changed files with 525 additions and 121 deletions

View file

@ -2,27 +2,60 @@
from django import forms
from avisstage.models import Normalien, Stage, Lieu, AvisLieu, AvisStage
from widget import LatLonField
from widgets import LatLonField
import re
class AvisStageForm(forms.ModelForm):
class HTMLTrimmerForm(forms.ModelForm):
def clean(self):
leading_white = re.compile(r"^( \t\n)*(<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>( \t\n)*)+?", re.IGNORECASE)
trailing_white = re.compile(r"(( \t\n)*<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>)+?( \t\n)*$", re.IGNORECASE)
cleaned_data = super(HTMLTrimmerForm, self).clean()
for (fname, fval) in cleaned_data.items():
if fname[:5] == "avis_":
cleaned_data[fname] = leading_white.sub("", trailing_white.sub("", fval))
return cleaned_data
class AvisStageForm(HTMLTrimmerForm):
class Meta:
model = AvisStage
fields = ['chapo', 'avis_ambiance', 'avis_sujet', 'avis_admin', 'les_plus', 'les_moins']
help_texts = {
"chapo": u"Une accroche résumant ce que vous avez pensé de ce stage",
"avis_ambiance": u"Avez-vous passé un bon moment à ce stage ? Étiez-vous assez guidé⋅e ? Aviez-vous un bon contact avec vos encadrant⋅e⋅s ? Y avait-il une bonne ambiance dans l'équipe ?",
"avis_sujet": u"Avez-vous appris des choses de votre stage ? Le travail correspondait-il à vos attentes ? Était-ce à votre niveau, trop dur, trop facile ?",
"avis_admin": u"Avez-vous commencé votre stage à la date prévue ? Était-ce compliqué d'obtenir les documents nécessaires (visa, contrats, etc) ? L'administration de l'établissement vous a-t-elle aidé⋅e ?",
"les_plus": u"Les principaux points positifs de ce stage",
"les_moins": u"Ce qui aurait pu être mieux",
}
class AvisLieuForm(forms.ModelForm):
class AvisLieuForm(HTMLTrimmerForm):
class Meta:
model = AvisLieu
fields = ['lieu', 'chapo', 'avis_lieustage', 'avis_pratique', 'avis_tourisme', 'les_plus', 'les_moins']
help_texts = {
"chapo": u"Une accroche résumant ce que vous avez pensé de cet endroit",
"avis_lieustage": u"Qu'avez-vous pensé des lieux où avait lieu votre stage ? Les bâtiments étaient-ils modernes ? Était-il agréable d'y travailler ?",
"avis_pratique": u"Avez-vous eu du mal à trouver un logement ? Y-a-t-il des choses que vous avez apprises sur place qu'il vous aurait été utile de savoir avant de partir ?",
"avis_tourisme": u"Y-a-t-il des lieux à visiter dans cette zone ? Avez-vous pratiqué des activités sportives ? Est-il facile de faire des rencontres ?",
"les_plus": u"Les meilleures raisons de partir à cet endroit",
"les_moins": u"Ce qui vous a gêné ou manqué là-bas",
}
class StageForm(forms.ModelForm):
date_widget = forms.DateInput(attrs={"class":"datepicker"})
date_debut = forms.DateField(input_formats=["%d/%m/%Y"], widget=date_widget)
date_fin = forms.DateField(input_formats=["%d/%m/%Y"], widget=date_widget)
date_debut = forms.DateField(label=u"Date de début", input_formats=["%d/%m/%Y"], widget=date_widget)
date_fin = forms.DateField(label=u"Date de fin", input_formats=["%d/%m/%Y"], widget=date_widget)
class Meta:
model = Stage
fields = ['sujet', 'date_debut', 'date_fin', 'type_stage', 'thematiques', 'matieres', 'encadrants']
help_texts = {
"thematiques": u"Mettez une virgule pour valider votre thématique si la suggestion ne correspond pas ou si elle n'existe pas encore"
}
labels = {
"date_debut": u"Date de début",
}
def __init__(self, *args, **kwargs):
if "request" in kwargs:

View file

@ -143,8 +143,8 @@ class Stage(models.Model):
max_length=choices_length(TYPE_STAGE_OPTIONS))
thematiques = TaggableManager(u"Thématiques", blank=True)
matieres = models.ManyToManyField(StageMatiere, related_name="stages")
encadrants = models.CharField(u"Encadrants", max_length=500, blank=True)
matieres = models.ManyToManyField(StageMatiere, verbose_name=u"Matière(s)", related_name="stages")
encadrants = models.CharField(u"Encadrant⋅e⋅s", max_length=500, blank=True)
# Avis
lieux = models.ManyToManyField(Lieu, related_name="stages",

View file

@ -9,16 +9,19 @@ $jaune: #FCEB26;
$vert: #27E35F;
$rouge: #C21B26;
$textfont: 'Dosis', sans-serif;
$headfont: Podkova, serif;
body {
background: $fond;
font-family: 'Dosis', sans-serif;
font-family: $textfont;
line-height: 1.4;
font-size: 19px;
font-weight: 300;
}
h1, h2, h3, h4 {
font-family: Podkova;
font-family: $headfont;
}
h1 {
@ -33,7 +36,7 @@ h3 {
font-size: 1.4em;
}
b {
b, strong, em {
font-weight: bold;
}
@ -68,7 +71,7 @@ header {
padding: 0 20px;
height: 90px;
vertical-align: middle;
color: #fff;
color: lighten($fond, 40%);
&:hover {
background: $barre * 0.6;
@ -327,5 +330,149 @@ article.stage {
color: $fond;
}
}
}
// Formulaires
input, textarea, select, div.tinymce {
background: #fff;
font-size: 1em;
font-family: $textfont;
line-height: 1.3em;
font-weight: 500;
padding: 5px;
}
input[type='text'], input[type='password'], textarea, select {
border:none;
border-bottom: 1px solid $fond;
width: 100%;
transition: border 1s ease-out, background 1s ease-out;
&:focus {
background-color: lighten($fond, 50%);
}
}
select {
-moz-appearance: none;
appearance: none;
width: auto;
margin-right: 5px;
}
textarea, div.tinymce {
border:none;
border-left: 1px solid $fond;
height: auto;
min-height: 200px;
transition: border 1s ease-out, background 1s ease-out;
}
div.tinymce.mce-edit-focus {
background-color: lighten($fond, 50%);
outline: none;
}
textarea {
height: 200px;
resize: vertical;
}
form {
.field {
margin: 5px 0;
display: flex;
background: #fff;
padding: 10px;
label, .label {
display:inline-block;
width: 250px;
text-align: right;
margin-right: 12px;
padding-top: 5px;
flex-shrink: 0;
}
label {
font-family: $headfont;
font-weight: bold;
}
.help_text {
font-style: italic;
font-size: 0.9em;
}
.input {
display:inline-block;
flex-grow:1;
margin-right:10px;
}
}
}
// taggit autosuggest
ul.as-selections {
display: flex;
flex-wrap: wrap;
li {
display:inline-block;
}
.as-selection-item {
padding: 0 5px;
background: $compl;
color: #fff;
margin: 5px;
border-radius: 2px;
font-weight: 500;
a.as-close {
color: #fff;
-webkit-cursor: pointer;
cursor: pointer;
margin-right: 5px;
}
&.selected {
background: $fond;
}
}
.as-original {
flex-grow: 1;
min-width: 200px;
input {
width: 100%;
}
}
}
div.as-results {
position: relative;
ul {
position: absolute;
width: 100%;
background: #fff;
border: 1px solid lighten($fond, 30%);
li {
padding: 3px 5px;
}
li.as-result-item {
&.active {
background: lighten($compl, 50%);
}
}
li.as-message {
font-style: italic;
}
}
}

View file

@ -65,41 +65,41 @@ article, aside, details, figcaption, figure, footer, header, hgroup, main, menu,
display: block;
}
/* line 12, ../../sass/screen.scss */
/* line 15, ../../sass/screen.scss */
body {
background: #E80051;
font-family: 'Dosis', sans-serif;
font-family: "Dosis", sans-serif;
line-height: 1.4;
font-size: 19px;
font-weight: 300;
}
/* line 20, ../../sass/screen.scss */
/* line 23, ../../sass/screen.scss */
h1, h2, h3, h4 {
font-family: Podkova;
font-family: Podkova, serif;
}
/* line 24, ../../sass/screen.scss */
/* line 27, ../../sass/screen.scss */
h1 {
font-size: 2.3em;
}
/* line 28, ../../sass/screen.scss */
/* line 31, ../../sass/screen.scss */
h2 {
font-size: 1.8em;
}
/* line 32, ../../sass/screen.scss */
/* line 35, ../../sass/screen.scss */
h3 {
font-size: 1.4em;
}
/* line 36, ../../sass/screen.scss */
b {
/* line 39, ../../sass/screen.scss */
b, strong, em {
font-weight: bold;
}
/* line 40, ../../sass/screen.scss */
/* line 43, ../../sass/screen.scss */
.beta {
opacity: 0.5;
font-size: 0.7em;
@ -107,65 +107,65 @@ b {
transform: translate(-1em, 0.6em) rotate(-15deg);
}
/* line 47, ../../sass/screen.scss */
/* line 50, ../../sass/screen.scss */
a {
font-weight: bold;
color: #24ac7c;
text-decoration: none;
}
/* line 53, ../../sass/screen.scss */
/* line 56, ../../sass/screen.scss */
header {
background: #a20039;
display: flex;
justify-content: space-between;
align-items: center;
}
/* line 59, ../../sass/screen.scss */
/* line 62, ../../sass/screen.scss */
header nav ul {
display: inline-flex;
}
/* line 62, ../../sass/screen.scss */
/* line 65, ../../sass/screen.scss */
header nav ul li {
display: inline-table;
}
/* line 65, ../../sass/screen.scss */
/* line 68, ../../sass/screen.scss */
header nav ul li a {
text-align: center;
display: table-cell;
padding: 0 20px;
height: 90px;
vertical-align: middle;
color: #fff;
color: #ffb5cf;
}
/* line 73, ../../sass/screen.scss */
/* line 76, ../../sass/screen.scss */
header nav ul li a:hover {
background: #610022;
}
/* line 80, ../../sass/screen.scss */
/* line 83, ../../sass/screen.scss */
header a {
color: #fff;
text-decoration: none;
}
/* line 85, ../../sass/screen.scss */
/* line 88, ../../sass/screen.scss */
header h1 {
padding: 15px;
word-wrap: none;
}
/* line 95, ../../sass/screen.scss */
/* line 98, ../../sass/screen.scss */
.content {
background: #efefef;
max-width: 900px;
padding: 30px;
margin: 15px auto;
}
/* line 101, ../../sass/screen.scss */
/* line 104, ../../sass/screen.scss */
.content p {
margin: 0.5em 0;
}
/* line 108, ../../sass/screen.scss */
/* line 111, ../../sass/screen.scss */
.homeh1 {
display: flex;
justify-content: space-between;
@ -175,33 +175,33 @@ header h1 {
border-bottom: 3px solid #000;
margin-bottom: 15px;
}
/* line 117, ../../sass/screen.scss */
/* line 120, ../../sass/screen.scss */
.homeh1 > * {
display: inline-block;
}
/* line 127, ../../sass/screen.scss */
/* line 130, ../../sass/screen.scss */
.stagelist li {
display: table;
width: 100%;
background: #fff;
margin: 12px;
}
/* line 134, ../../sass/screen.scss */
/* line 137, ../../sass/screen.scss */
.stagelist li > *, .stagelist li:before {
display: table-cell;
vertical-align: middle;
padding: 15px;
}
/* line 139, ../../sass/screen.scss */
/* line 142, ../../sass/screen.scss */
.stagelist li a {
width: auto;
}
/* line 141, ../../sass/screen.scss */
/* line 144, ../../sass/screen.scss */
.stagelist li a:hover {
background: #ccc;
}
/* line 145, ../../sass/screen.scss */
/* line 148, ../../sass/screen.scss */
.stagelist li:before {
content: "&nbsp";
text-align: right;
@ -209,27 +209,27 @@ header h1 {
opacity: 0.8;
color: #fff;
}
/* line 152, ../../sass/screen.scss */
/* line 155, ../../sass/screen.scss */
.stagelist li.stage-brouillon:before {
content: "Brouillon";
background: #C21B26;
}
/* line 156, ../../sass/screen.scss */
/* line 159, ../../sass/screen.scss */
.stagelist li.stage-publie:before {
content: "Publié";
background: #27E35F;
}
/* line 160, ../../sass/screen.scss */
/* line 163, ../../sass/screen.scss */
.stagelist li.stage-ajout:before {
content: "+";
color: #000;
}
/* line 169, ../../sass/screen.scss */
/* line 172, ../../sass/screen.scss */
article.stage {
font-weight: normal;
}
/* line 172, ../../sass/screen.scss */
/* line 175, ../../sass/screen.scss */
article.stage h2 {
background: #d8d864;
padding: 10px 20px;
@ -237,7 +237,7 @@ article.stage h2 {
margin-bottom: 25px;
text-shadow: -3px 3px 0 rgba(0, 0, 0, 0.3);
}
/* line 179, ../../sass/screen.scss */
/* line 182, ../../sass/screen.scss */
article.stage h3 {
border-bottom: 2px solid #56917c;
margin-left: -25px;
@ -247,30 +247,30 @@ article.stage h3 {
color: #000;
text-shadow: -3px 3px 0 rgba(0, 0, 0, 0.1);
}
/* line 189, ../../sass/screen.scss */
/* line 192, ../../sass/screen.scss */
article.stage section {
background: #eee;
padding: 14px;
max-width: 600px;
margin: 30px auto;
}
/* line 195, ../../sass/screen.scss */
/* line 198, ../../sass/screen.scss */
article.stage section:first-child {
margin-top: 0;
}
/* line 197, ../../sass/screen.scss */
/* line 200, ../../sass/screen.scss */
article.stage section:first-child h3 {
margin-top: 0;
}
/* line 202, ../../sass/screen.scss */
/* line 205, ../../sass/screen.scss */
article.stage section.misc {
padding-top: 0;
}
/* line 204, ../../sass/screen.scss */
/* line 207, ../../sass/screen.scss */
article.stage section.misc ul.infos {
margin: 0 -3px;
}
/* line 207, ../../sass/screen.scss */
/* line 210, ../../sass/screen.scss */
article.stage section.misc ul.infos li {
display: inline-block;
padding: 5px;
@ -280,42 +280,42 @@ article.stage section.misc ul.infos li {
font-size: 0.9em;
border-radius: 4px;
}
/* line 216, ../../sass/screen.scss */
/* line 219, ../../sass/screen.scss */
article.stage section.misc ul.infos li.thematique {
background-color: #28BF8A;
}
/* line 219, ../../sass/screen.scss */
/* line 222, ../../sass/screen.scss */
article.stage section.misc ul.infos li.matiere {
background-color: #E80051;
}
/* line 226, ../../sass/screen.scss */
/* line 229, ../../sass/screen.scss */
article.stage section .chapo, article.stage section .avis-texte {
margin-bottom: 15px;
background: #fff;
padding: 20px;
}
/* line 231, ../../sass/screen.scss */
/* line 234, ../../sass/screen.scss */
article.stage section .chapo {
font-size: 1.1em;
font-weight: 500;
font-variant: small-caps;
}
/* line 236, ../../sass/screen.scss */
/* line 239, ../../sass/screen.scss */
article.stage section .avis-texte {
border-left: 1px solid #ccc;
padding-left: 15px;
}
/* line 241, ../../sass/screen.scss */
/* line 244, ../../sass/screen.scss */
article.stage section .plusmoins {
max-width: 600px;
margin: 15px auto;
}
/* line 245, ../../sass/screen.scss */
/* line 248, ../../sass/screen.scss */
article.stage section .plusmoins > div {
display: table;
width: 100%;
}
/* line 249, ../../sass/screen.scss */
/* line 252, ../../sass/screen.scss */
article.stage section .plusmoins > div:before {
content: "&nbsp";
width: 100px;
@ -324,78 +324,225 @@ article.stage section .plusmoins > div:before {
text-align: right;
padding-right: 12px;
}
/* line 258, ../../sass/screen.scss */
/* line 261, ../../sass/screen.scss */
article.stage section .plusmoins > div > *, article.stage section .plusmoins > div:before {
display: table-cell;
}
/* line 262, ../../sass/screen.scss */
/* line 265, ../../sass/screen.scss */
article.stage section .plusmoins > div > div {
padding: 15px;
color: #fff;
}
/* line 265, ../../sass/screen.scss */
/* line 268, ../../sass/screen.scss */
article.stage section .plusmoins > div > div h4 {
font-weight: normal;
margin-left: -5px;
font-size: 0.9em;
opacity: 0.9;
}
/* line 271, ../../sass/screen.scss */
/* line 274, ../../sass/screen.scss */
article.stage section .plusmoins > div > div p {
font-weight: bold;
margin: 2px;
}
/* line 279, ../../sass/screen.scss */
/* line 282, ../../sass/screen.scss */
article.stage section .plusmoins .plus > div {
background: #23cc56;
}
/* line 282, ../../sass/screen.scss */
/* line 285, ../../sass/screen.scss */
article.stage section .plusmoins .plus:before {
content: "Les +";
vertical-align: bottom;
color: #1b9f43;
}
/* line 289, ../../sass/screen.scss */
/* line 292, ../../sass/screen.scss */
article.stage section .plusmoins .moins > div {
background: #af1822;
}
/* line 292, ../../sass/screen.scss */
/* line 295, ../../sass/screen.scss */
article.stage section .plusmoins .moins:before {
content: "Les -";
vertical-align: top;
color: #88131b;
}
/* line 302, ../../sass/screen.scss */
/* line 305, ../../sass/screen.scss */
.article-wrapper {
display: table;
}
/* line 304, ../../sass/screen.scss */
/* line 307, ../../sass/screen.scss */
.article-wrapper .toc-wrapper, .article-wrapper article {
display: table-cell;
vertical-align: top;
}
/* line 308, ../../sass/screen.scss */
/* line 311, ../../sass/screen.scss */
.article-wrapper .toc-wrapper {
max-width: 250px;
width: 25%;
}
/* line 312, ../../sass/screen.scss */
/* line 315, ../../sass/screen.scss */
.article-wrapper .toc {
position: -webkit-sticky;
position: sticky;
top: 0;
}
/* line 316, ../../sass/screen.scss */
/* line 319, ../../sass/screen.scss */
.article-wrapper .toc a {
color: inherit;
font-weight: normal;
}
/* line 323, ../../sass/screen.scss */
/* line 326, ../../sass/screen.scss */
.article-wrapper .toc .toc-h3 a {
font-weight: 300;
}
/* line 326, ../../sass/screen.scss */
/* line 329, ../../sass/screen.scss */
.article-wrapper .toc .toc-active a {
color: #E80051;
}
/* line 338, ../../sass/screen.scss */
input, textarea, select, div.tinymce {
background: #fff;
font-size: 1em;
font-family: "Dosis", sans-serif;
line-height: 1.3em;
font-weight: 500;
padding: 5px;
}
/* line 347, ../../sass/screen.scss */
input[type='text'], input[type='password'], textarea, select {
border: none;
border-bottom: 1px solid #E80051;
width: 100%;
transition: border 1s ease-out, background 1s ease-out;
}
/* line 353, ../../sass/screen.scss */
input[type='text']:focus, input[type='password']:focus, textarea:focus, select:focus {
background-color: #ffe8f0;
}
/* line 359, ../../sass/screen.scss */
select {
-moz-appearance: none;
appearance: none;
width: auto;
margin-right: 5px;
}
/* line 366, ../../sass/screen.scss */
textarea, div.tinymce {
border: none;
border-left: 1px solid #E80051;
height: auto;
min-height: 200px;
transition: border 1s ease-out, background 1s ease-out;
}
/* line 374, ../../sass/screen.scss */
div.tinymce.mce-edit-focus {
background-color: #ffe8f0;
outline: none;
}
/* line 379, ../../sass/screen.scss */
textarea {
height: 200px;
resize: vertical;
}
/* line 385, ../../sass/screen.scss */
form .field {
margin: 5px 0;
display: flex;
background: #fff;
padding: 10px;
}
/* line 391, ../../sass/screen.scss */
form .field label, form .field .label {
display: inline-block;
width: 250px;
text-align: right;
margin-right: 12px;
padding-top: 5px;
flex-shrink: 0;
}
/* line 399, ../../sass/screen.scss */
form .field label {
font-family: Podkova, serif;
font-weight: bold;
}
/* line 403, ../../sass/screen.scss */
form .field .help_text {
font-style: italic;
font-size: 0.9em;
}
/* line 407, ../../sass/screen.scss */
form .field .input {
display: inline-block;
flex-grow: 1;
margin-right: 10px;
}
/* line 416, ../../sass/screen.scss */
ul.as-selections {
display: flex;
flex-wrap: wrap;
}
/* line 420, ../../sass/screen.scss */
ul.as-selections li {
display: inline-block;
}
/* line 424, ../../sass/screen.scss */
ul.as-selections .as-selection-item {
padding: 0 5px;
background: #28BF8A;
color: #fff;
margin: 5px;
border-radius: 2px;
font-weight: 500;
}
/* line 432, ../../sass/screen.scss */
ul.as-selections .as-selection-item a.as-close {
color: #fff;
-webkit-cursor: pointer;
cursor: pointer;
margin-right: 5px;
}
/* line 439, ../../sass/screen.scss */
ul.as-selections .as-selection-item.selected {
background: #E80051;
}
/* line 444, ../../sass/screen.scss */
ul.as-selections .as-original {
flex-grow: 1;
min-width: 200px;
}
/* line 448, ../../sass/screen.scss */
ul.as-selections .as-original input {
width: 100%;
}
/* line 454, ../../sass/screen.scss */
div.as-results {
position: relative;
}
/* line 456, ../../sass/screen.scss */
div.as-results ul {
position: absolute;
width: 100%;
background: #fff;
border: 1px solid #ff82ae;
}
/* line 463, ../../sass/screen.scss */
div.as-results ul li {
padding: 3px 5px;
}
/* line 469, ../../sass/screen.scss */
div.as-results ul li.as-result-item.active {
background: #ebfbf5;
}
/* line 474, ../../sass/screen.scss */
div.as-results ul li.as-message {
font-style: italic;
}

View file

@ -13,23 +13,131 @@
</script>
<script type="text/javascript" src="{% static "js/tinymce/tinymce.min.js" %}"></script>
<script type="text/javascript">
tinyMCE.init({
selector: "textarea.tinymce",
menubar: false,
plugins: "paste,searchreplace,lists,autolink,link",
toolbar: 'undo redo | bold italic underline strikethrough | bullist numlist outdent indent | link',
language: "fr_FR",
$(function() {
// Process rich text fields
var txtr = $("textarea.tinymce");
$.each(txtr, function(i, item) {
var newitem = $("<div>", {"class":"tinymce"}).html(item.value)
item.fakeinput = newitem;
item.style.display = "none";
$(item).parent().append(newitem);
});
tinyMCE.init({
selector: "div.tinymce",
menubar: false,
plugins: "paste,searchreplace,lists,autolink,link",
toolbar: 'undo redo | bold italic underline strikethrough | bullist numlist outdent indent | link',
inline: true,
language: "fr_FR",
});
// process select multiple fields
var slts = $("select[multiple]");
var NULL_VAL = " ";
$.each(slts, function(i, item) {
var $item = $(item);
var $parent = $item.parent();
var $liste = $("<div>", {class: "msel-liste"});
item.msel_liste = $liste;
var template = $item.clone(false);
template.prepend($("<option>", {"value": NULL_VAL})
.text("Choisir..."));
template.removeAttr("multiple")
.removeAttr("required")
.attr("id", "")
.addClass("msel-choix");
var vl = $item.val();
if(vl.length == 0) vl = [NULL_VAL];
for(var i=0; i<vl.length; i++) {
$liste.append(template.clone(false).val(vl[i]));
}
$ajouter = $("<a>", {"href": "javascript:void(0);", "class":"msel-add"}).text("Ajouter");
function ajout() {
var prevv = $liste.find("select");
if($(prevv[prevv.length-1]).val() == NULL_VAL) return;
$ajouter.before(template.clone(false).val(NULL_VAL));
}
$ajouter.on("click", ajout);
$liste.append($ajouter);
$parent.append($liste);
$item.remove();
});
// À l'envoi du formulaire
$("#stageform").submit(function() {
$.each(txtr, function(i, item) {
item.value = tinyMCE.get(item.fakeinput.attr("id")).getContent();
});
$.each(slts, function(i, item) {
$.each(item.msel_liste.find("select"), function(j, sel) {
var v = $(sel).val();
if(v == NULL_VAL)
$(sel).val(undefined);
});
});
});
});
</script>
{% endblock %}
{% block content %}
<h1>Ajouter un stage</h1>
<form action="" method="post">
<h1>{% if creation %}Nouveau stage{% else %}Modification d'un stage{% endif %}</h1>
<form action="" method="post" id="stageform">
{% csrf_token %}
{{ form.as_p }}
{{ avis_stage_form.as_p }}
{{ avis_lieu_formset.as_p }}
<h2>Informations générales</h2>
{{ form.non_field_errors }}
{% for field in form %}
{{ field.errors }}
<div class="field">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
<div class="input">
{{ field }}
{% if field.help_text %}
<p class="help_text">{{ field.help_text }}</p>
{% endif %}
</div>
</div>
{% endfor %}
<h2>Commentaires sur le stage</h2>
{{ avis_stage_form.non_field_errors }}
{% for field in avis_stage_form %}
{{ field.errors }}
<div class="field">
<div class="label">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if field.help_text %}
<p class="help_text">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="input">
{{ field }}
</div>
</div>
{% endfor %}
{{ avis_lieu_formset.management_form }}
{% for fform in avis_lieu_formset %}
<h2>Commentaire sur le lieu</h2>
{{ fform.non_field_errors }}
{% for field in fform %}
{% if true or not field.name == "lieu" %}
{{ field.errors }}
<div class="field">
<div class="label">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if field.help_text %}
<p class="help_text">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="input">
{{ field }}
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
<input type="submit" value="Enregistrer" />
</form>
{% endblock %}

View file

@ -57,7 +57,7 @@ def manage_stage(request, id_stage=None):
c_del = True
AvisLieuFormSet = forms.inlineformset_factory(
Stage, AvisLieu, form=AvisLieuForm, can_delete=c_del)
Stage, AvisLieu, form=AvisLieuForm, can_delete=c_del, extra=0)
if request.method == "POST":
form = StageForm(request.POST, request=request, instance=stage, prefix="stage")
@ -80,40 +80,8 @@ def manage_stage(request, id_stage=None):
return render(request, "avisstage/formulaires/stage.html",
{'form': form, 'avis_stage_form': avis_stage_form,
'avis_lieu_formset': avis_lieu_formset})
class StageAjout(CreateView, LoginRequiredMixin):
model = Stage
form_class = StageForm
template_name = 'avisstage/formulaires/stage.html'
def get_form_kwargs(self):
kwargs = super(StageAjout, self).get_form_kwargs()
kwargs.update({'request': self.request})
return kwargs
class StageEdit(UpdateView, LoginRequiredMixin):
model = Stage
form_class = StageForm
template_name = 'avisstage/formulaires/stage.html'
def get_queryset(self):
# Autorise les modifications des seuls stages qu'on "possède"
queryset = super(StageEdit, self).get_queryset()
return queryset.filter(auteur=self.request.user.profil)
def get_form_kwargs(self):
kwargs = super(StageEdit, self).get_form_kwargs()
kwargs.update({'request': self.request})
return kwargs
def get_success_url(self):
return reverse('avisstage:stage', self.instance.id)
def get_context_data(self, *args, **kwargs):
ctx = super(StageEdit, self).get_context_data(*args, **kwargs)
print ctx
return ctx
'avis_lieu_formset': avis_lieu_formset,
'creation': id_stage is None})
class StageView(DetailView, LoginRequiredMixin):
model = Stage

View file

@ -45,3 +45,4 @@ class LatLonField(forms.MultiValueField):
point_str = 'POINT(%f %f)'%tuple(reversed(data_list))
return ';'.join([srid_str, point_str])
return None