Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
clinicaltrials
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
david Chavalarias
clinicaltrials
Commits
a8ac0399
Commit
a8ac0399
authored
Mar 13, 2017
by
Romain Loth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adapt dbcrud for new org table structure (profile, registration)
parent
326c2ed8
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
592 additions
and
196 deletions
+592
-196
cascade_full_scholar_info.sql
doc/data_mining_exemples/cascade_full_scholar_info.sql
+8
-4
org_to_orgs.sql
doc/data_mining_exemples/org_to_orgs.sql
+43
-0
dev_setup.md
doc/dev_setup.md
+4
-15
table_specifications.md
doc/table_specifications.md
+9
-11
print_directory.php
print_directory.php
+6
-4
dbcrud.py
services/dbcrud.py
+142
-54
main.py
services/main.py
+109
-15
utils.py
services/text/utils.py
+159
-0
init_comex_shared.sql
setup/dockers/comex2_mysql_server/init_comex_shared.sql
+8
-8
comex_page_profile_controllers.js
static/js/comex_page_profile_controllers.js
+4
-4
comex_page_reg_controllers.js
static/js/comex_page_reg_controllers.js
+3
-3
comex_user_shared.js
static/js/comex_user_shared.js
+19
-5
profile.html
templates/profile.html
+8
-66
org_details.html
templates/questions/org_details.html
+63
-0
registration_super_short_form.html
templates/registration_super_short_form.html
+7
-7
No files found.
doc/cascade_full_scholar_info.sql
→
doc/
data_mining_exemples/
cascade_full_scholar_info.sql
View file @
a8ac0399
...
...
@@ -25,19 +25,23 @@ SELECT * FROM (
FROM
scholars
LEFT
JOIN
sch_org
AS
map_labs
ON
map_labs
.
uid
=
luid
JOIN
orgs
AS
labs
LEFT
JOIN
(
-- class constraint can't appear later,
-- it would give no scholar when empty
SELECT
*
FROM
orgs
WHERE
class
=
'lab'
)
AS
labs
ON
map_labs
.
orgid
=
labs
.
orgid
WHERE
(
record_status
=
'active'
OR
(
record_status
=
'legacy'
AND
valid_date
>=
NOW
()))
AND
labs
.
class
=
'lab'
GROUP
BY
luid
)
AS
scholars_and_labs
LEFT
JOIN
sch_org
AS
map_insts
ON
map_insts
.
uid
=
luid
JOIN
orgs
AS
insts
LEFT
JOIN
(
SELECT
*
FROM
orgs
WHERE
class
=
'inst'
)
AS
insts
ON
map_insts
.
orgid
=
insts
.
orgid
AND
insts
.
class
=
'inst'
GROUP
BY
luid
)
AS
scholars_and_orgs
...
...
doc/data_mining_exemples/org_to_orgs.sql
0 → 100644
View file @
a8ac0399
-- we pass through scholars
-- org1 => scholars => orgs2
-- (for suggestions and/or than mapping)
SELECT
orgs
.
*
,
GROUP_CONCAT
(
tgt_tostring
ORDER
BY
tgt_freq
DESC
SEPARATOR
'%%%'
)
AS
related_insts
FROM
orgs
LEFT
JOIN
(
SELECT
sch_org
.
orgid
AS
src_orgid
,
sch_org2
.
orgid
AS
tgt_orgid
,
orgs2
.
tostring
AS
tgt_tostring
,
count
(
*
)
AS
tgt_freq
FROM
sch_org
LEFT
JOIN
sch_org
AS
sch_org2
ON
sch_org
.
uid
=
sch_org2
.
uid
JOIN
orgs
AS
orgs2
ON
sch_org2
.
orgid
=
orgs2
.
orgid
WHERE
orgs2
.
class
=
'inst'
AND
sch_org
.
orgid
!=
sch_org2
.
orgid
GROUP
BY
sch_org
.
orgid
,
sch_org2
.
orgid
)
AS
lab_relationship_to_inst_via_scholars
ON
src_orgid
=
orgs
.
orgid
WHERE
orgs
.
orgid
IN
(
{$
ids_str
}
)
AND
orgs
.
name
!=
'_NULL'
GROUP
BY
orgs
.
orgid
ORDER
BY
orgs
.
name
,
orgs
.
acro
;
-- a POSSible alternative would be create an org_org tabls
-- relationship organizations <=> organizations
-- formally many-to-many but one could say many-to-few :)
CREATE
TABLE
org_org
(
orgid_src
int
(
15
)
not
null
,
-- @class 'lab'
orgid_tgt
int
(
15
)
not
null
,
-- @class 'inst'
sch_freq
int
(
15
)
default
0
,
-- how often declared in sch records
-- (useful if unsure main parent org)
PRIMARY
KEY
(
orgid_src
,
orgid_tgt
),
FOREIGN
KEY
(
orgid_src
)
REFERENCES
orgs
(
orgid
)
ON
DELETE
CASCADE
,
FOREIGN
KEY
(
orgid_tgt
)
REFERENCES
orgs
(
orgid
)
ON
DELETE
CASCADE
);
-- NB +/-1 to org -> org freq in org_org would be triggered indirectly by new scholars rows so made in profile saving at middle-ware lvl (dbcrud.py)
doc/dev_setup.md
View file @
a8ac0399
## dev overview
comex app contains:
...
...
@@ -34,13 +33,10 @@ cd $INSTALL_DIR
sudo pip3 install -r setup/requirements.txt
```
Then to run the comex2 serv
ices in the simplest way
just do:
Then to run the comex2 serv
er
just do:
```
cd services
python3 comex_main_backend.py
bash comex-run.sh
```
The form server is then accessible locally on
`0.0.0.0:5000/services/user`
The tina api server is on
`0.0.0.0:5000/services/api`
Check the parameters in
`config/parametres_comex.ini`
...
...
@@ -49,7 +45,7 @@ Finally, simply configure the serving of your php|www documentroot in nginx (cf
-------
####
Advanced
dev config
####
Full
dev config
1.
external mysql database
2.
external doors (or simulated by docker)
3.
gunicorn webserver (linked to 1 & 2 via
`$SQL_HOST`
and
`$DOORS_HOST`
)
...
...
@@ -92,15 +88,8 @@ nano config/parametres_comex.ini
###### If you have no doors server
For tests you can use a
`minidoors`
container
```
# build the docker image (once)
cd setup/dockers
docker build -t minidoors:latest minidoors/
For tests you can use a self-deployed doors container, available on
[
this repository
](
https://github.com/ISCPIF/doors-docker
)
# run the container (each time)
docker run -it -p 32789:8989 --name doors_test minidoors
```
##### 3) Run the regomex app with gunicorn
```
...
...
doc/table_specifications.md
View file @
a8ac0399
...
...
@@ -46,7 +46,6 @@ CREATE TABLE scholars (
) ;
CREATE TABLE locs(
locname varchar(120),
lat float(6,4),
...
...
@@ -54,12 +53,11 @@ CREATE TABLE locs(
PRIMARY KEY (locname)
) ;
-- table for all organization classes (team, lab, large institution)
CREATE TABLE orgs(
orgid int(15) not null auto_increment,
name varchar(120), -- full name
acro varchar(
2
0), -- acronym or short name
acro varchar(
3
0), -- acronym or short name
class varchar(25), -- "team|lab|inst"
-- like the calibre of the organization
...
...
@@ -78,15 +76,14 @@ CREATE TABLE orgs(
-- address... (...) -- address elements POSS NOT IMPLEMENTED
reserved varchar(30),
--
generated column, often useful for autocompletes etc
--
tostring: generated column
-- ex "Instituto de Fisica de Cantabria (IFCA), Santander, Spain"
tostring varchar(800) AS (CONCAT(
name, ' (', acro, ')',
IF(locname IS NOT NULL ,
CONCAT(', ', locname),
'')
)),
-- searchable + human readable, often useful for autocompletes etc
tostring varchar(800)
AS (CONCAT_WS( '',
CONCAT(name, ' '),
CONCAT('(',acro,')'),
CONCAT(', ', locname)) ),
PRIMARY KEY (orgid),
UNIQUE KEY full_org (name, acro, locname)
...
...
@@ -106,6 +103,7 @@ CREATE TABLE sch_org(
-- POSS: relationship organizations <=> keywords
-- POSS: relationship organizations <=> organizations
-- cf. doc/data_mining_exemples/org_to_orgs.sql
-- keyword/subject terms
...
...
print_directory.php
View file @
a8ac0399
...
...
@@ -303,19 +303,21 @@ SELECT * FROM (
FROM
scholars
LEFT
JOIN
sch_org
AS
map_labs
ON
map_labs
.
uid
=
luid
JOIN
orgs
AS
labs
LEFT
JOIN
(
SELECT
*
FROM
orgs
WHERE
class
='
lab
'
) AS labs
ON map_labs.orgid = labs.orgid
WHERE (record_status = '
active
'
OR (record_status = '
legacy
' AND valid_date >= NOW()))
AND
labs
.
class
=
'
lab
'
GROUP BY luid
) AS scholars_and_labs
LEFT JOIN sch_org AS map_insts
ON map_insts.uid = luid
JOIN orgs AS insts
LEFT JOIN (
SELECT * FROM orgs WHERE class='
inst
'
) AS insts
ON map_insts.orgid = insts.orgid
AND insts.class = '
inst
'
GROUP BY luid
) AS scholars_and_orgs
...
...
services/dbcrud.py
View file @
a8ac0399
This diff is collapsed.
Click to expand it.
services/main.py
View file @
a8ac0399
...
...
@@ -25,7 +25,7 @@ __status__ = "Dev"
# ============== imports ==============
from
re
import
sub
from
re
import
sub
,
match
from
os
import
path
,
remove
from
json
import
dumps
from
datetime
import
timedelta
...
...
@@ -101,12 +101,12 @@ SOURCE_FIELDS = [
(
"pic_file"
,
False
,
None
),
# saved separately
# => for *scholars* table (optional)
(
"
org"
,
True
,
None
),
(
"
org_type"
,
False
,
None
),
# predefined values
(
"other_org_type"
,
True
,
None
),
# +=> org_type
(
"
team_lab"
,
True
,
None
),
(
"org_city"
,
True
,
None
),
# => for *
affiliations* table
(
"
lab_label"
,
True
,
None
),
# ~ /acro (name)/
(
"
lab_locname"
,
True
,
None
),
# 'Paris, France'
(
"inst_label"
,
True
,
None
),
# ~ /acro (name)/
(
"
inst_type"
,
False
,
None
),
# predefined values
(
"other_inst_type"
,
True
,
None
),
# +=> org_type
# => for *
orgs* table via sort_affiliation_records
(
"keywords"
,
True
,
None
),
# => for *keywords* table (after split str)
...
...
@@ -752,6 +752,84 @@ def show_privacy():
########### SUBS ###########
def
sort_affiliation_records
(
clean_records
):
"""
Transform GUI side input data into at most 2 orgs objects for DB
In general:
1) the front-end inputs are less free than the DB structure
(DB could save an array of orgids but in the inputs they're only allowed max 2 atm : lab and inst)
2) each org has its microstructure:
- name, acronym, class, location (base properties)
- inst_type (specific to institutions)
- lab_code, url, contact <= not fillable in GUI yet
3) between themselves 2 orgs can have org_org relationships
TODO LATER (not a priority)
4) we want at least one of lab_label or inst_label to be NOT NULL
Choices:
- values are already sanitized by read_record_from_request
- We call label the concatenated name + acronym information,
handling here the possibilities for the input via str analysis
(just short name, just long name, both)
- We return a map with 2 key/value submaps for lab and institutions
"""
new_orgs
=
{
'lab'
:
None
,
'inst'
:
None
}
for
org_class
in
new_orgs
:
# can't create org without some kind of label
if
(
org_class
+
"_label"
not
in
clean_records
or
not
len
(
clean_records
[
org_class
+
"_label"
])):
pass
else
:
# submap
new_org_info
=
{}
# 1) label analysis
clean_input
=
clean_records
[
org_class
+
"_label"
]
# custom split attempt
# eg 'CNRS (Centre National de la Recherche Scientifique)'
# vvvv vvvvvvvvvv
# acro name
test_two_groups
=
match
(
r'([^\(]{1,30}) \(([^\)]+)\)'
,
clean_input
)
if
test_two_groups
:
new_org_info
[
'acro'
]
=
test_two_groups
.
groups
()[
0
]
new_org_info
[
'name'
]
=
test_two_groups
.
groups
()[
1
]
# fallback cases
elif
len
(
clean_input
)
<
30
:
new_org_info
[
'acro'
]
=
clean_input
else
:
new_org_info
[
'name'
]
=
clean_input
# 2) enrich with any other optional org info
for
detail_col
in
[
'type'
,
'code'
,
'locname'
,
'url'
,
'contact_email'
,
'contact_name'
]:
# this is a convention in our templates
org_detail
=
org_class
+
'_'
+
detail_col
if
org_detail
in
clean_records
:
val
=
clean_records
[
org_detail
]
if
len
(
val
):
new_org_info
[
detail_col
]
=
val
# 3) keep
new_orgs
[
org_class
]
=
new_org_info
return
new_orgs
def
save_form
(
clean_records
,
update_flag
=
False
,
previous_user_info
=
None
):
"""
wrapper function for save profile/register (all DB-related form actions)
...
...
@@ -767,11 +845,23 @@ def save_form(clean_records, update_flag=False, previous_user_info=None):
# A) a new DB connection
reg_db
=
dbcrud
.
connect_db
(
config
)
# B) read/fill the affiliation table to get associated id
clean_records
[
'affiliation_id'
]
=
dbcrud
.
get_or_create_affiliation
(
clean_records
,
reg_db
)
# B1) re-group the org fields into at most 2 org 'objects'
declared_orgs
=
sort_affiliation_records
(
clean_records
)
# B2) check our constraint (cf. also E.)
if
(
declared_orgs
[
'lab'
]
is
None
or
declared_orgs
[
'inst'
]
is
None
):
raise
ValueError
(
"At least 1 org (lab or institution) must be filled"
)
# B3) for each, read/fill the orgs table to get associated id(s) in DB
orgids
=
[]
for
oclass
in
[
'lab'
,
'inst'
]:
if
(
declared_orgs
[
oclass
]):
orgids
.
append
(
dbcrud
.
get_or_create_org
(
declared_orgs
[
oclass
],
reg_db
)
)
# B4) save the org <=> org mappings TODO LATER (not a priority)
# dbcrud.record_org_org_link(src_orgid, tgt_orgid, reg_db)
# C) create/update record into the primary user table
# ----------------------------------------------------
...
...
@@ -824,6 +914,10 @@ def save_form(clean_records, update_flag=False, previous_user_info=None):
map_table
)
# E) save the (uid <=> orgid) mapping(s)
for
orgid
in
orgids
:
dbcrud
.
record_sch_org_link
(
luid
,
orgid
,
reg_db
)
# F) end connection
reg_db
.
close
()
...
...
@@ -872,9 +966,9 @@ def read_record_from_request(request):
clean_records
[
field
]
=
request
.
form
[
field
]
# special treatment for "other" subquestions
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'
]
if
'
inst
_type'
in
clean_records
:
if
clean_records
[
'
inst_type'
]
==
'other'
and
'other_inst
_type'
in
clean_records
:
clean_records
[
'
inst_type'
]
=
clean_records
[
'other_inst
_type'
]
# splits for kw_array and ht_array
for
tok_field
in
[
'keywords'
,
'hashtags'
]:
...
...
services/text/utils.py
View file @
a8ac0399
...
...
@@ -140,3 +140,162 @@ class CountryConverter:
self
.
connDBLP
.
close
()
return
fails
#! /usr/bin/python3
from
re
import
sub
from
sys
import
stdin
,
stderr
# settings
dont_touch_first_column
=
False
NCOLS
=
1
# functions
def
normalize_chars
(
my_str
,
rm_qt
=
False
):
"""
Simplification des chaînes de caractères en entrée de la BDD
- normalisation
> espaces
> tirets
> guillemets
- déligatures
Goal: normalize input values more like ascii will be easier to process
"""
# print('normalize_chars IN: "%s"' % my_str)
# --------------
# E S P A C E S
# --------------
# tous les caractères de contrôle (dont \t = \x{0009} et \r = \x{000D}) --> espace
my_str
=
sub
(
r'[\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000B\u000C\u000D\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F]'
,
' '
,
my_str
)
# mais pas \n = \x{000A}
# Line separator
my_str
=
sub
(
r'\u2028'
,
' '
,
my_str
)
my_str
=
sub
(
r'\u2029'
,
' '
,
my_str
)
# U+0092: parfois quote parfois cara de contrôle
my_str
=
sub
(
r'\u0092'
,
' '
,
my_str
)
# tous les espaces alternatifs --> espace
my_str
=
sub
(
r'[\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u202F\u205F\u3000\uFEFF]'
,
' '
,
my_str
)
# quelques puces courantes (bullets)
my_str
=
sub
(
r'^\s+►'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+●'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+◘'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+→'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+▪'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+·'
,
' • '
,
my_str
)
my_str
=
sub
(
r'^\s+\*'
,
' • '
,
my_str
)
# pour finir on enlève les espaces en trop
# (dits "trailing spaces")
my_str
=
sub
(
r' +'
,
' '
,
my_str
)
my_str
=
sub
(
r'^ +'
,
''
,
my_str
)
my_str
=
sub
(
r' +$'
,
''
,
my_str
)
# ------------------------
# P O N C T U A T I O N S
# ------------------------
# la plupart des tirets alternatifs --> tiret normal (dit "du 6")
# (dans l'ordre U+002D U+2010 U+2011 U+2012 U+2013 U+2014 U+2015 U+2212 U+FE63)
my_str
=
sub
(
r'[‐‑‒–—―−﹣]'
,
'-'
,
my_str
)
# le macron aussi parfois comme tiret
my_str
=
sub
(
r'\u00af'
,
'-'
,
my_str
)
# Guillemets
# ----------
# la plupart des quotes simples --> ' APOSTROPHE
my_str
=
sub
(
r"[‘’‚`‛]"
,
"'"
,
my_str
)
# U+2018 U+2019 U+201a U+201b
my_str
=
sub
(
r'‹ ?'
,
"'"
,
my_str
)
# U+2039 plus espace éventuel après
my_str
=
sub
(
r' ?›'
,
"'"
,
my_str
)
# U+203A plus espace éventuel avant
# la plupart des quotes doubles --> " QUOTATION MARK
my_str
=
sub
(
r'[“”„‟]'
,
'"'
,
my_str
)
# U+201C U+201D U+201E U+201F
# my_str = sub(r'« ?', '"', my_str) # U+20AB plus espace éventuel après
# my_str = sub(r' ?»', '"', my_str) # U+20AB plus espace éventuel avant
# deux quotes simples (préparées ci-dessus) => une double
my_str
=
sub
(
r"''"
,
'"'
,
my_str
)
# if we need to remove single quotes
if
rm_qt
:
my_str
=
sub
(
r"'"
,
'"'
,
my_str
)
# print('normalize_chars OUT: "%s"' % my_str)
return
my_str
def
normalize_forms
(
term_str
,
do_lowercase
=
False
):
"""
Removes unwanted trailing punctuation
AND optionally puts everything to lowercase
ex /©""ecosystem services"";/ => /"ecosystem services"/
(benefits from normalize_chars upstream so there's less cases to consider)
largely inadequate to the enormity of the task
"""
# print('normalize_forms IN: "%s"' % term_str)
term_str
=
sub
(
r'^[,; ©]+'
,
''
,
term_str
)
term_str
=
sub
(
r'[,; ©]+$'
,
''
,
term_str
)
term_str
=
sub
(
r'"+'
,
'"'
,
term_str
)
term_str
=
sub
(
r'/+'
,
'/'
,
term_str
)
term_str
=
sub
(
r"'+"
,
"'"
,
term_str
)
if
do_lowercase
:
term_str
=
term_str
.
lower
()
# print('normalize_forms OUT: "%s"' % term_str)
return
term_str
if
__name__
==
"__main__"
:
for
i
,
line
in
enumerate
(
stdin
):
fields
=
line
.
rstrip
()
.
split
(
'
\t
'
)
if
len
(
fields
)
>
NCOLS
:
print
(
"skipping line
%
i (
%
s)"
%
(
i
,
fields
),
file
=
stderr
)
continue
if
dont_touch_first_column
:
# some ID supposed in 1st col => kept unchanged
clean_fields
=
[
fields
[
0
]]
todo_fields
=
fields
[
1
:]
else
:
# normalize in all columns
clean_fields
=
[]
todo_fields
=
fields
for
field
in
todo_fields
:
clean_lines
=
[]
last_line
=
None
for
line
in
field
.
split
(
'
%%%
'
):
# print(">> (doing line)", line)
clean_line
=
normalize_forms
(
normalize_chars
(
line
))
if
clean_line
==
''
and
last_line
==
''
:
last_line
=
clean_line
continue
else
:
clean_lines
.
append
(
normalize_forms
(
normalize_chars
(
line
)))
last_line
=
clean_line
# remove trailing lines
# TODO test if instead s/(?:%%%)+$// on clean_fields later is faster
for
i
in
range
(
len
(
clean_lines
)
-
1
,
0
,
-
1
):
if
not
len
(
clean_lines
[
i
]):
clean_lines
.
pop
()
else
:
break
clean_fields
.
append
(
'
%%%
'
.
join
(
clean_lines
))
# OUTPUT
print
(
"
\t
"
.
join
(
clean_fields
))
setup/dockers/comex2_mysql_server/init_comex_shared.sql
View file @
a8ac0399
...
...
@@ -69,15 +69,14 @@ CREATE TABLE orgs(
-- address... (...) -- address elements POSS NOT IMPLEMENTED
reserved
varchar
(
30
),
--
generated column, often useful for autocompletes etc
--
tostring: generated column
-- ex "Instituto de Fisica de Cantabria (IFCA), Santander, Spain"
tostring
varchar
(
800
)
AS
(
CONCAT
(
name
,
' ('
,
acro
,
')'
,
IF
(
locname
IS
NOT
NULL
,
CONCAT
(
', '
,
locname
),
''
)
)),
-- searchable + human readable, often useful for autocompletes etc
tostring
varchar
(
800
)
AS
(
CONCAT_WS
(
''
,
CONCAT
(
name
,
' '
),
CONCAT
(
'('
,
acro
,
')'
),
CONCAT
(
', '
,
locname
))
),
PRIMARY
KEY
(
orgid
),
UNIQUE
KEY
full_org
(
name
,
acro
,
locname
)
...
...
@@ -97,6 +96,7 @@ CREATE TABLE sch_org(
-- POSS: relationship organizations <=> keywords
-- POSS: relationship organizations <=> organizations
-- cf. doc/data_mining_exemples/org_to_orgs.sql
-- keyword/subject terms
...
...
static/js/comex_page_profile_controllers.js
View file @
a8ac0399
...
...
@@ -14,10 +14,10 @@
*/
// 3 exposed vars for inline js controls
var
teamCityDiv
=
document
.
getElementById
(
'
team_city
_div'
)
var
otherInstDiv
=
document
.
getElementById
(
'other_
org
_div'
)
// TODO make relative to
org
_type and move inline snippet to extended form obj
var
otherOrgTypeInput
=
document
.
getElementById
(
'other_
org
_type'
)
var
teamCityDiv
=
document
.
getElementById
(
'
lab_locname
_div'
)
var
otherInstDiv
=
document
.
getElementById
(
'other_
inst
_div'
)
// TODO make relative to
inst
_type and move inline snippet to extended form obj
var
otherOrgTypeInput
=
document
.
getElementById
(
'other_
inst
_type'
)
// reselecting current_user's info choices
function
setupSavedItems
(
uinfo
)
{
...
...
static/js/comex_page_reg_controllers.js
View file @
a8ac0399
...
...
@@ -39,8 +39,8 @@ var validateWithMessage = false
var
shortRegVersion
=
true
var
ignoredFields
=
[]
if
(
shortRegVersion
)
{
ignoredFields
=
[
'gender'
,
'home_url'
,
'
org
'
,
'hon_title'
,
'position'
,
'
org
_type'
,
ignoredFields
=
[
'gender'
,
'home_url'
,
'
inst_label
'
,
'hon_title'
,
'position'
,
'
inst
_type'
,
'hashtags'
]
}
...
...
@@ -68,7 +68,7 @@ function testAsYouGo() {
}
}
var
teamCityDivStyle
=
document
.
getElementById
(
'
team_city
_div'
).
style
var
teamCityDivStyle
=
document
.
getElementById
(
'
lab_locname
_div'
).
style
function
registerDoorsAndSubmit
(){
regfo
.
elMainMessage
.
innerHTML
=
"Registering with the test login portal<br/> and sending validation email..."
...
...
static/js/comex_user_shared.js
View file @
a8ac0399
...
...
@@ -61,11 +61,25 @@ var cmxClt = (function() {
[
"pic_file"
,
false
,
"pref"
,
"f"
,
"other_infos"
],
// ==> *scholars* table
[
"org"
,
false
,
"plsfill"
,
"t"
,
"org_infos"
],
[
"org_type"
,
false
,
"plsfill"
,
"m"
,
"org_infos"
],
[
"team_lab"
,
true
,
"plsfill"
,
"t"
,
"org_infos"
],
[
"org_city"
,
false
,
"pref"
,
"t"
,
"org_infos"
]
// ==> *affiliations* table
// org field
// => name, acro in one field "label": #lab_label, #inst_label
// => all other fields
// - are optional
// - if present, should be named: lab|inst + '_' + colname
// => TODO org details suggestions
// url, loc should have autofill when name or acro is chosen
// => POSS org <-> org suggestions
// once a lab is filled, we could propose the institution
[
"lab_label"
,
false
,
"plsfill"
,
"t"
,
"org_infos"
],
[
"lab_locname"
,
false
,
"pref"
,
"t"
,
"org_infos"
],
[
"inst_label"
,
false
,
"pref"
,
"t"
,
"org_infos"
],
[
"inst_type"
,
false
,
"pref"
,
"m"
,
"org_infos"
],
// ["lab_code", false, "pref", "t", "org_infos"],
// ["lab_url", false, "pref", "t", "org_infos"],
// ["inst_locname", false, "pref" , "t", "org_infos"],
// ["inst_url", false, "pref" , "t", "org_infos"],
// ==> *orgs* table via pretreatment org is inst or org is lab
]
// group "auto" === filled by controllers
...
...
templates/profile.html
View file @
a8ac0399
...
...
@@ -347,73 +347,15 @@
class=
"panel-body ccsection-uform-body panel-collapse collapse out"
role=
"tabpanel"
aria-expanded=
"false"
>
<div
class=
"question input-group"
>
<label
for=
"position"
class=
"smlabel input-group-addon"
>
* Job Position
</label>
<input
id=
"position"
name=
"position"
maxlength=
"30"
type=
"text"
class=
"form-control autocomp"
placeholder=
"titre"
onblur=
"cmxClt.makeBold(this)"
onfocus=
"cmxClt.makeNormal(this)"
value=
"{{ current_user.info.position }}"
>
</div>
<!-- ORG QUESTIONS -->
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"org"
class=
"smlabel input-group-addon"
>
Parent Institution
</label>
<input
id=
"org"
name=
"org"
maxlength=
"120"
type=
"text"
class=
"form-control autocomp"
placeholder=
'eg "CNRS" or "University of Oxford"'
value=
"{{ current_user.info.org }}"
>
</div>
</div>
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"org_type"
class=
"smlabel input-group-addon"
>
Institution Type
</label>
<select
id=
"org_type"
name=
"org_type"
class=
"custom-select form-control"
onchange=
"if(this.value=='other'){otherInstDiv.style.display = 'block'} else {otherInstDiv.style.display='none';otherOrgTypeInput.value=''}"
>
<option
selected
disabled
value=
""
>
Please select
</option>
<option
value=
"university"
>
University
</option>
<option
value=
"public R&D org"
>
Public sector R
&
D organization
</option>
<option
value=
"public other org"
>
Other public sector organization
</option>
<option
value=
"private org"
>
Private sector organization
</option>
<option
value=
"none"
>
None at the moment
</option>
<option
value=
"other"
onclick=
"otherInstDiv.style.display = 'block'"
>
Other
</option>
</select>
</div>
<!-- Other institution type <=> only if previous choice == 5 -->
<div
class=
"question conditional-q"
id=
"other_org_div"
>
<div
class=
"input-group"
>
<label
for=
"other_org_type"
class=
"smlabel input-group-addon"
>
Other type
</label>
<input
id=
"other_org_type"
name=
"other_org_type"
maxlength=
"120"
type=
"text"
class=
"form-control"
placeholder=
"Clarify here the type of your parent institution"
>
</div>
</div>
</div>
<!-- TEAM QUESTIONS -->
<div
class=
"question"
>
<div
class=
"input-group"
>
<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 }}"
>
</div>
</div>
<!-- Lab city <=> only for France -->
<div
class=
"question conditional-q"
id=
"team_city_div"
>
<div
class=
"input-group"
>
<label
for=
"org_city"
class=
"smlabel input-group-addon"
>
Lab city
</label>
<input
id=
"org_city"
name=
"org_city"
maxlength=
"50"
type=
"text"
class=
"form-control"
placeholder=
"Ville de votre institution"
value=
"{{ current_user.info.org_city }}"
>
</div>
</div>
<div
class=
"question input-group"
>
<label
for=
"position"
class=
"smlabel input-group-addon"
>
* Job Position
</label>
<input
id=
"position"
name=
"position"
maxlength=
"30"
type=
"text"
class=
"form-control autocomp"
placeholder=
"titre"
onblur=
"cmxClt.makeBold(this)"
onfocus=
"cmxClt.makeNormal(this)"
value=
"{{ current_user.info.position }}"
>
</div>
{% include 'questions/org_details.html' %}
</div>
<!-- /panel-body -->
<div
class=
"panel-footer ccsection-footer"
>
</div>
...
...
templates/questions/org_details.html
0 → 100644
View file @
a8ac0399
<!-- ORG QUESTIONS -->
<!-- lab or team and details -->
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"lab_label"
class=
"smlabel input-group-addon"
>
* Lab / Team / Dept
</label>
<input
id=
"lab_label"
name=
"lab_label"
maxlength=
"250"
type=
"text"
class=
"form-control"
placeholder=
"More detailed affiliation, if relevant"
value=
"{{ current_user.info.labs[0].tostring if current_user.info.labs|length > 0 }}"
>
</div>
</div>
<!-- lab locname <=> only for France -->
<div
class=
"question conditional-q"
id=
"lab_locname_div"
>
<div
class=
"input-group"
>
<label
for=
"lab_locname"
class=
"smlabel input-group-addon"
>
Lab city
</label>
<input
id=
"lab_locname"
name=
"lab_locname"
maxlength=
"50"
type=
"text"
class=
"form-control"
placeholder=
"Ville de votre institution"
value=
"{{ current_user.info.labs[0].locname if current_user.info.labs|length > 0 }}"
>
</div>
</div>
<!-- larger institution and details -->
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"inst_label"
class=
"smlabel input-group-addon"
>
Parent Institution
</label>
<input
id=
"inst_label"
name=
"inst_label"
maxlength=
"250"
type=
"text"
class=
"form-control autocomp"
placeholder=
'eg "CNRS" or "University of Oxford"'
value=
"{{ current_user.info.insts[0].tostring if current_user.info.insts|length > 0 }}"
>
</div>
</div>
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"inst_type"
class=
"smlabel input-group-addon"
>
Institution Type
</label>
<select
id=
"inst_type"
name=
"inst_type"
class=
"custom-select form-control"
onchange=
"if(this.value=='other'){otherInstDiv.style.display = 'block'} else {otherInstDiv.style.display='none';otherOrgTypeInput.value=''}"
>
<option
selected
disabled
value=
""
>
Please select
</option>
<option
value=
"university"
>
University
</option>
<option
value=
"public R&D org"
>
Public sector R
&
D organization
</option>
<option
value=
"public other org"
>
Other public sector organization
</option>
<option
value=
"private org"
>
Private sector organization
</option>
<option
value=
"none"
>
None at the moment
</option>
<option
value=
"other"
onclick=
"otherInstDiv.style.display = 'block'"
>
Other
</option>
</select>
</div>
<!-- Other institution type <=> only if previous choice == 5 -->
<div
class=
"question conditional-q"
id=
"other_org_div"
>
<div
class=
"input-group"
>
<label
for=
"other_inst_type"
class=
"smlabel input-group-addon"
>
Other type
</label>
<input
id=
"other_inst_type"
name=
"other_inst_type"
maxlength=
"120"
type=
"text"
class=
"form-control"
placeholder=
"Clarify here the type of your parent institution"
>
</div>
</div>
</div>
templates/registration_super_short_form.html
View file @
a8ac0399
...
...
@@ -160,20 +160,20 @@
<div
class=
"question"
>
<div
class=
"input-group"
>
<label
for=
"
team_lab
"
class=
"smlabel input-group-addon"
>
* Lab / Team / Dept
</label>
<input
id=
"
team_lab"
name=
"team_lab
"
maxlength=
"120"
<label
for=
"
lab_label
"
class=
"smlabel input-group-addon"
>
* Lab / Team / Dept
</label>
<input
id=
"
lab_label"
name=
"lab_label
"
maxlength=
"120"
type=
"text"
class=
"form-control"
placeholder=
"Your lab"
placeholder=
"
team_lab
"
>
placeholder=
"
lab_label
"
>
</div>
</div>
<!-- Lab city <=> only for France -->
<div
class=
"question conditional-q"
id=
"
team_city
_div"
>
<div
class=
"question conditional-q"
id=
"
lab_locname
_div"
>
<div
class=
"input-group"
>
<label
for=
"
org_city
"
class=
"smlabel input-group-addon"
>
Lab city
</label>
<input
id=
"
org_city"
name=
"org_city
"
maxlength=
"50"
<label
for=
"
lab_locname
"
class=
"smlabel input-group-addon"
>
Lab city
</label>
<input
id=
"
lab_locname"
name=
"lab_locname
"
maxlength=
"50"
type=
"text"
class=
"form-control"
placeholder=
"Ville de votre institution"
placeholder=
"
org_city
"
>
placeholder=
"
lab_locname
"
>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment