Commit 074dd3f9 authored by Romain Loth's avatar Romain Loth

more responsive and interactive forms

parent 13ff9bdd
......@@ -393,7 +393,7 @@ def register():
if request.method == 'GET':
return render_template(
"registration_full_form.html",
"registration_short_form.html",
doors_connect=config['DOORS_HOST']+':'+config['DOORS_PORT']
)
elif request.method == 'POST':
......@@ -529,8 +529,9 @@ def read_record(incoming_data):
clean_records[field] = incoming_data[field]
# special treatment for "other" subquestions
if clean_records['org_type'] == 'other' and 'other_org_type' in clean_records:
clean_records['org_type'] = clean_records['other_org_type']
if 'org_type' in clean_records:
if clean_records['org_type'] == 'other' and 'other_org_type' in clean_records:
clean_records['org_type'] = clean_records['other_org_type']
# split for kw_array
kw_array = []
......
.white { color:#fff ; }
.red { color:#910 ; }
.green { color:#161 ; }
.grey { color:#554 ; }
.orange { color:#F96 ; }
.blue { color:#23A ; }
/* =============================== MAIN COMEX SERVICES STYLESHEET =============================== */
.white { color:#fff ;}
.red { color:#910 ;}
.green { color:#161 ;}
.grey { color:#554 ;}
.orange{ color:#F96 ;}
.blue { color:#23A ;}
/* classic look */
body {
margin: 0;
font-family: "Droid Sans", Calibri, "Helvetica Neue", Helvetica, sans-serif;
letter-spacing: -0.03em;
letter-spacing: -0.04em;
color: #333;
background-color: #fff;
line-height: .85em;
......@@ -21,6 +21,13 @@ body {
/* main content for all new pages */
div.my-box {
padding:0 15px;
}
@media(max-width:991px){
/* sm and md */
div.my-box {
padding:0;
}
}
/* form content for reg, profile, login, etc.... */
......@@ -30,11 +37,29 @@ div.uform {
background-color: #ddd;
}
/*div.uform::before {
content: "F O R M";
font-family: monospace;
font-size: 1em;
float: right;
color: #000;
}*/
/* same but to put a panel-body inside */
div.uform-nobg {
margin: 38px 38px 8px 38px;
}
@media(max-width:991px){
/* sm and md */
div.uform, div.uform-nobg {
padding: 0;
margin: 12px 12px 2px 12px;
}
}
button.clean-btn
p#doors_ret_msg {
font-weight: bold;
text-shadow: 2px;
......@@ -44,7 +69,6 @@ p#doors_ret_msg {
.autocomp {
}
.page {
margin-top: 45px; /* topbar height is 40px */
}
......@@ -59,7 +83,7 @@ p#doors_ret_msg {
}
/* a "subpage" container */
/* a "subpage" container UNUSED */
.subpage {
width: 100%;
max-width: 65em;
......@@ -75,6 +99,23 @@ p#doors_ret_msg {
}
/* a fixed div for validation messsages */
.menu-right-fixed {
position: fixed;
top: 4em;
right: 0;
display:block;
z-index: 4;
opacity: .8;
}
@media(max-width:991px){
/* sm and md */
.menu-right-fixed {
top: 11em;
}
}
/* ==> a question + input block <== */
.question {
padding: 0 1em;
......@@ -150,6 +191,12 @@ input#my-captcha{
border-radius: .2em;
}
/* like a close window element */
.pull-up-right {
margin-top: -.5em;
float: right;
}
/* like a dialog icon */
.glyphicon-float-left {
float: left ;
......@@ -250,7 +297,7 @@ ul.minilabels {
list-style-type: none;
font-size: 75% ;
text-align: left;
margin-left: 32%;
cursor: pointer;
}
li.minilabel {
......@@ -292,16 +339,33 @@ li.minilabel {
/* the main validation message (a special legend) */
#main_message {
/*color: white ;*/
color: white ;
font-size: 140%;
text-align:center;
line-height: 1.5em;
/*background-color: #988 ;
border-radius: 2em;*/
padding: 3em 3em 1em 3em;
margin-bottom: 2em;
border: none;
background-color: #333 ;
border-radius: .2em;
padding: 1em;
margin-bottom: 1em;
border: 2px solid #ddd;
-webkit-transition: opacity 5s ease;
}
#main_message.faded {
opacity: 0;
}
@media(max-width:991px){
/* sm and md */
#main_message {
font-size: 110%;
line-height: 1em;
padding: .1em .3em ;
margin: 0;
}
}
......
/**
/**we have all
* @fileoverview
* Profile 1/overview and 2/completing
* @todo
......@@ -32,6 +32,10 @@ selectSavedMenus(uinfo)
// initialize form controllers
cmxClt.uform.initialize("comex_profile_form", completionAsYouGo)
// memory
var formValid = false
// main validation function
// ------------------------
function completionAsYouGo() {
......@@ -41,30 +45,7 @@ function completionAsYouGo() {
var diagnosticParams = {'fixResidue': true,
'ignore': ['email']}
var diagnostic = cmxClt.uform.testFillField(cmxClt.uform.theForm,
diagnosticParams)
var valid = diagnostic[0]
var mandatoryMissingFields = diagnostic[1]
var optionalMissingFields = diagnostic[2]
if (valid) {
cmxClt.uform.mainMessage.innerHTML = "<span class='green glyphicon glyphicon-check glyphicon-float-left' style='float:left;'></span><p>OK thank you! we have all the fields needed for the mapping!</p>"
}
else {
cmxClt.uform.mainMessage.innerHTML = "<span class='orange glyphicon glyphicon-exclamation-sign glyphicon-float-left'></span><p>Sorry, there are some important missing fields</p>"
}
// list of missing fields
cmxClt.uform.mainMessage.innerHTML += cmxClt.ulListFromLabelsArray(mandatoryMissingFields, ['orange'])
if (optionalMissingFields.length) {
cmxClt.uform.mainMessage.innerHTML += cmxClt.ulListFromLabelsArray(
optionalMissingFields,
['white'],
"You may also want to fill:"
)
}
cmxClt.uform.simpleValidateAndMessage(diagnosticParams)
// stamp => #last_modified_date
cmxClt.uform.stampTime()
......
This diff is collapsed.
......@@ -86,7 +86,7 @@
// autocomplete institution
$(function() {
var $orgInput = $('#org')
var $orgInput = $('#team_lab')
var orgList = [
"Centre National de la Recherche Scientifique (CNRS)",
......
......@@ -34,17 +34,21 @@ var cmxClt = (function() {
// the target columns in DB: tuple (name, mandatory, group, type, section)
cC.COLS = [ ["doors_uid", true, "auto" , "t", null],
cC.COLS = [
["keywords", true, "plsfill", "at", "map_infos"],
// ==> *keywords* table
["doors_uid", true, "auto" , "t", null],
["last_modified_date", true, "auto" , "d", null],
["email", true, "plsfill", "t", "basic_infos"],
["country", true, "plsfill", "t", "basic_infos"],
["hon_title", false, "plsfill", "t", "basic_infos"],
["email", true, "plsfill", "t", "login_infos"],
["first_name", true, "plsfill", "t", "basic_infos"],
["middle_name", false, "pref", "t", "basic_infos"],
["last_name", true, "plsfill", "t", "basic_infos"],
["initials", true, "plsfill", "t", null],
["country", true, "plsfill", "t", "basic_infos"],
["initials", true, "pref", "t", null],
["position", true, "plsfill", "t", "map_infos"],
["hon_title", false, "plsfill", "t", "basic_infos"],
["interests_text", false, "plsfill", "t", "other_infos"],
["interests_text", false, "pref", "t", "other_infos"],
["community_hashtags", false, "plsfill", "at", "map_infos"],
["gender", false, "plsfill", "m", "other_infos"],
["job_looking_date", false, "pref" , "d", "map_infos"],
......@@ -53,12 +57,9 @@ var cmxClt = (function() {
["pic_file", false, "pref" , "f", "other_infos"],
// ==> *scholars* table
["keywords", true, "plsfill", "at", "map_infos"],
// ==> *keywords* table
["org", true, "plsfill", "t", "org_infos"],
["org_type", true, "plsfill", "m", "org_infos"],
["team_lab", false, "pref" , "t", "map_infos"],
["org", false, "plsfill", "t", "org_infos"],
["org_type", false, "plsfill", "m", "org_infos"],
["team_lab", true, "plsfill", "t", "map_infos"],
["org_city", false, "pref" , "t", "org_infos"]]
// ==> *affiliations* table
......@@ -91,12 +92,13 @@ var cmxClt = (function() {
var flabel = cplArray[i][1]
// to open any collapsible containing the label and input
var openFun = 'return cC.uform.openPanelForField(\''+fname+'\')'
var openFun = 'return cC.uform.gotoField(\''+fname+'\')'
console.log("openFun", openFun)
// debug onclick fun
// console.log("openFun", openFun)
// link works if anchorLabels was run
resultHtml += '<li class="minilabel"><a onclick="'+openFun+'" href="#'+fname+'_lbl'+'">'+flabel+'</a></li>'
resultHtml += '<li class="minilabel"><div onclick="'+openFun+'">'+flabel+'</div></li>'
}
resultHtml += '</ul>'
return resultHtml
......@@ -142,10 +144,10 @@ var cmxClt = (function() {
// functions
cC.uform.initialize
cC.uform.testFillField
cC.uform.simpleValidateAndMessage
cC.uform.stampTime
cC.uform.anchorLabels
cC.uform.gotoField
cC.uform.multiTextinput
cC.uform.openPanelForField
// dates up to 2049/12/31
cC.uform.validDate = new RegExp( /^20[0-4][0-9]\/(?:0?[1-9]|1[0-2])\/(?:0?[1-9]|[1-2][0-9]|3[0-1])$/)
......@@ -171,67 +173,12 @@ var cmxClt = (function() {
cC.insertAfter(normalInput, newTextArrayInput)
}
// anchorLabels
//
// replace(fname =~ /<label for="([^"]+)"/,
// `<label for="${fname}" id="${fname}_lbl"`)
// use at init
cC.uform.anchorLabels = function (cols) {
for (var i in cols) {
var fName = cols[i][0] // (-:)
var itsLabel = document.querySelector(`label[for=${fName}]`)
// set id
if (itsLabel) itsLabel.id = fName + '_lbl'
}
// also set the window to go 50px above label anchors
window.addEventListener("hashchange", function () {
window.scrollTo(window.scrollX, window.scrollY - 50);
});
}
// openPanelForField
cC.uform.openPanelForField = function (fName) {
console.log('fName', fName)
var labelElt = document.getElementById(fName+'_lbl')
var ourPanel = cC.findAncestor(labelElt, "panel-collapse")
console.log('ourPanel.classList.contains("in")', ourPanel.classList.contains('in'))
// if panel is not open
if (! ourPanel.classList.contains('in')) {
// POSS use cols with key/value structure to use cols[fName] instead of looking for i
var theCol = -1
for (var i in cC.COLS) {
if (fName == cC.COLS[i][0]) {
theCol = i
break
}
}
var ccSection = cC.COLS[i][4]
console.log('ccSection', ccSection)
if (ccSection) {
// click the corresponding toggler
document.getElementById('ccsection_toggle_'+ccSection).click()
}
}
}
// initialize
// -----------
cC.uform.initialize = function(aFormId, aValidationFun) {
cC.uform.theFormId = aFormId
cC.uform.theForm = document.getElementById(aFormId)
// todo pass formId and have a COLS by forms
cC.uform.anchorLabels(cC.COLS)
// events
cC.uform.theForm.onkeyup = aValidationFun
cC.uform.theForm.onchange = aValidationFun
......@@ -330,7 +277,7 @@ var cmxClt = (function() {
valid = false
// console.log("mandatoryMissingFields", fieldName)
if (params.doHighlight) {
if (params.doHighlight && labelElt) {
labelElt.style.backgroundColor = cC.colorOrange
}
}
......@@ -360,6 +307,79 @@ var cmxClt = (function() {
cC.uform.timestamp.value = now.toISOString()
}
// diagnosticParams are optional
//
cC.uform.simpleValidateAndMessage = function (diagnosticParams) {
var diagnostic = cmxClt.uform.testFillField(cmxClt.uform.theForm,
diagnosticParams)
var isValid = diagnostic[0]
var mandatoryMissingFields = diagnostic[1]
var optionalMissingFields = diagnostic[2]
if (isValid) {
cmxClt.uform.mainMessage.innerHTML = "<span class='green glyphicon glyphicon-check glyphicon-float-left' style='float:left;'></span><p>OK thank you! <br/>(we have all the fields needed for the mapping!)<br/>(don't forget to SAVE!)</p>"
cmxClt.uform.mainMessage.classList.add('faded')
}
else {
cmxClt.uform.mainMessage.innerHTML = "<span class='orange glyphicon glyphicon-exclamation-sign glyphicon-float-left'></span><p>Sorry, there are some<br/> important missing fields</p>"
cmxClt.uform.mainMessage.classList.remove('faded')
}
// list of missing fields
cmxClt.uform.mainMessage.innerHTML += cmxClt.ulListFromLabelsArray(mandatoryMissingFields, ['orange'])
if (optionalMissingFields.length) {
cmxClt.uform.mainMessage.innerHTML += cmxClt.ulListFromLabelsArray(
optionalMissingFields,
['white'],
"You may also want to fill:"
)
}
}
// gotoField
// (assumes nothing)
// (side-effect: opens the corresponding panel)
cC.uform.gotoField = function (fName) {
// debug
// console.log('goto fName', fName)
var fieldElt = document.getElementById(fName)
// open panel if it is closed
var ourPanel = cC.findAncestor(fieldElt, "panel-collapse")
if (ourPanel && ! ourPanel.classList.contains('in')) {
// POSS use cols with key/value structure to use cols[fName] instead of looking for i
var theCol = -1
for (var i in cC.COLS) {
if (fName == cC.COLS[i][0]) {
theCol = i
break
}
}
var ccSection = cC.COLS[i][4]
// debug
// console.log('ccSection', ccSection)
if (ccSection) {
// click the corresponding toggler
document.getElementById('ccsection_toggle_'+ccSection).click()
}
}
// now go to the field itself (actually, 120px above)
// --------------------------------------------------
fieldElt.scrollIntoView(true)
window.scrollTo(window.scrollX, window.scrollY - 120)
}
// ===================================================================
// additional controllers for detailed forms like /register, /profile
// ===================================================================
......
......@@ -65,7 +65,7 @@
<div class="col-lg-7 col-md-7 col-sm-10 wwwpanel">
<div class="panel panel-default">
<div class="panel-heading">
<p style="float:right">
<p class="pull-up-right">
<a target="_blank" href="/explorerjs.html?type=%22filter%22&nodeidparam=%22%257B%257D%22">
<span class="glyphicon glyphicon-new-window"></span>
Open in another window
......@@ -109,7 +109,7 @@
<div class="col-lg-7 col-md-7 col-sm-10">
<div class="panel panel-default wwwpanel">
<div class="panel-heading">
<p style="float:right">
<p class="pull-up-right">
<a target="_blank" href="/services/user/{% if current_user.info %}profile{% else %}register{% endif %}">
<span class="glyphicon glyphicon-new-window"></span>
Open in another window
......@@ -155,7 +155,7 @@
<div class="col-lg-7 col-md-7 col-sm-10">
<div class="panel panel-default wwwpanel">
<div class="panel-heading">
<p style="float:right">
<p class="pull-up-right">
<a target="_blank" href="/index.html">
<span class="glyphicon glyphicon-new-window"></span>
Open in another window
......@@ -194,7 +194,7 @@
<div class="col-lg-7 col-md-7 col-sm-10">
<div class="panel panel-default wwwpanel">
<div class="panel-heading">
<p style="float:right">
<p class="pull-up-right">
<a target="_blank" href="/print_directory.php?query=%7B%7D">
<span class="glyphicon glyphicon-new-window"></span>
Open in another window
......@@ -239,7 +239,7 @@
<div class="col-lg-7 col-md-7 col-sm-10 wwwpanel">
<div class="panel panel-default">
<div class="panel-heading">
<p style="float:right">
<p class="pull-up-right">
<a target="_blank" href="/explorerjs.html?type=%22filter%22&nodeidparam=%22%257B%257D%22">
<span class="glyphicon glyphicon-new-window"></span>
Open in another window
......
......@@ -102,7 +102,7 @@
<!-- ########################### ( FORM ) ########################## -->
<!-- todo onsubmit also save to cache -->
<div class="uform-nobg">
<div class="uform-nobg accordion" id="profile_uform">
<h2 class="oldstyle">Edit your profile</h2>
<p class="mini-hero">
......@@ -231,7 +231,7 @@
<h2 class="ccsection"
title="This is the main data that allows us to plot you in the exploration graph and render the 'carte de visite'">
<span class="glyphicon glyphicon-collapse-down glyphicon-float-right"></span>
<span class="glyphicon glyphicon-tags"></span>
<span class="glyphicon glyphicon-tags"></span>&nbsp;
Mapping data
</h2>
</div>
......@@ -269,7 +269,7 @@
<div class="question">
<div class="input-group">
<label for="team_lab" class="smlabel input-group-addon">Lab / Team / Dept</label>
<label for="team_lab" class="smlabel input-group-addon">* Lab / Team / Dept</label>
<input id="team_lab" name="team_lab" maxlength="120"
type="text" class="form-control" placeholder="More detailed affiliation, if relevant"
value="{{ current_user.info.team_lab }}">
......@@ -531,13 +531,10 @@
<!-- <p> TEST UID {{ current_user.uid | safe }} </p> -->
<!-- main validation message -->
<p id="main_message" class="cartouche legend" style="display:none"></p>
<!-- == S U B M I T == -->
<div style="text-align:center">
<!-- no @type => implicit @type=submit -->
<button class="btn btn-lg btn-success" id="form_submit">
<!-- @type button to avoid ENTER submit -->
<button class="btn btn-lg btn-success" id="form_submit" type="button" onclick="cmxClt.uform.theForm.submit()">
Save profile
</button>
</div>
......@@ -549,6 +546,14 @@
<div class="spacer col-sm-2 col-md-2">&nbsp;</div>
</div>
<div class="menu-right-fixed">
<!-- main validation message -->
<p id="main_message" class="legend"></p>
</div>
<!-- CNIL WARNING -->
<div class="row spacerrow">&nbsp;</div>
<div class="row">
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment