Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Luciano Barletta
/
mini-web
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit 031e4964
authored
2019-12-04 16:49:38 +0000
by
Luciano Barletta
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
added checkbox and others
1 parent
e5b86009
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
161 additions
and
243 deletions
deploy.py
static/Scripts/ArmadoDeForm.js
static/Scripts/construct.js
static/Style/ArmadoDeForm.css
templates/field.html
templates/form.html
templates/tab.html
deploy.py
View file @
031e496
...
...
@@ -58,51 +58,42 @@ def login():
def
main
():
data
=
[
{
"title"
:
"
first
"
,
"title"
:
"
general
"
,
"fields"
:
[
{
"title"
:
"1"
,
"type"
:
"mail"
,
"placeholder"
:
"example@example.com"
,
},
{
"title"
:
"2"
,
"type"
:
"file"
,
"placeholder"
:
"999"
,
},
{
"title"
:
"3"
,
"type"
:
"checkbox"
,
"placeholder"
:
"999"
,
},
{
"title"
:
"4"
,
"title"
:
"nombre"
,
"type"
:
"text"
,
"placeholder"
:
"Luciano"
,
"required"
:
True
},
{
"title"
:
"mail"
,
"type"
:
"mail"
,
"placeholder"
:
"ejemplo@gmail.com"
,
}
]
},
{
"title"
:
"
second
"
,
"title"
:
"
detalles
"
,
"fields"
:
[
{
"title"
:
"
first
"
,
"title"
:
"
género
"
,
"type"
:
"select"
,
"placeholder"
:
"
nedea
"
,
"placeholder"
:
"
Gènero
"
,
"options"
:
[
"
first
"
,
"
second
"
,
"
third
"
"
Hombre
"
,
"
Mujer
"
,
"
#other
"
]
},
{
"title"
:
"second"
,
"type"
:
"number"
,
"placeholder"
:
"999"
,
"title"
:
"Gusto"
,
"type"
:
"checkbox"
,
"options"
:
[
"first"
,
"second"
,
"third"
"Hombres"
,
"Mujeres"
,
"#other"
],
"required"
:
True
}
...
...
@@ -113,7 +104,7 @@ def main():
"fields"
:
[]
}
]
return
render_template
(
"form.html"
,
tabs
=
data
,
title
=
"Formulario de Prueba"
)
return
render_template
(
"form.html"
,
tabs
=
data
,
title
=
"Formulario de Prueba"
,
color
=
"#33aaff"
)
if
__name__
==
"__main__"
:
app
.
run
(
"0.0.0.0"
)
\ No newline at end of file
static/Scripts/ArmadoDeForm.js
View file @
031e496
var
getAncestorByAttribute
=
(
elem
,
attr
,
val
)
=>
{
while
(
elem
.
getAttribute
(
attr
)
!=
val
||
elem
==
null
)
elem
=
elem
.
parentElement
;
return
elem
;
}
var
getDescendantByAttribute
=
(
elem
,
attr
,
val
)
=>
{
if
(
elem
==
null
||
elem
.
getAttribute
(
attr
)
==
val
)
return
elem
;
return
Array
.
from
(
elem
.
children
).
reduce
(
(
a
,
b
)
=>
{
let
x
=
getDescendantByAttribute
(
a
,
attr
,
val
);
let
y
=
getDescendantByAttribute
(
b
,
attr
,
val
);
return
x
==
null
?
y
:
x
;
},
null
);
}
function
HabilitarTab
(
bc
,
tc
,
n
){
if
(
typeof
n
!=
"number"
)
return
console
.
log
(
"El entero es invalido"
);
...
...
@@ -11,3 +25,16 @@ function HabilitarTab(bc,tc,n){
}
}
}
function
Otro
(
otroselect
){
let
inputs
=
getAncestorByAttribute
(
otroselect
,
"class"
,
"FieldInput"
);
let
other
=
getDescendantByAttribute
(
inputs
,
"class"
,
"Other"
);
if
(
otroselect
.
nodeName
==
"SELECT"
){
if
(
otroselect
.
selectedOptions
[
0
].
value
==
"Otro"
)
other
.
style
.
display
=
"block"
;
else
other
.
style
.
display
=
"none"
;
}
else
{
if
(
otroselect
.
checked
)
other
.
style
.
display
=
"block"
;
else
other
.
style
.
display
=
"none"
;
}
}
\ No newline at end of file
static/Scripts/construct.js
deleted
100644 → 0
View file @
e5b8600
/**
* Lambdas
*/
var
accessNumber
=
e
=>
{
if
(
e
.
childElementCount
==
0
)
return
0
;
if
(
e
.
children
[
0
].
childElementCount
==
0
)
return
0
;
return
e
.
children
[
0
].
children
[
0
];
}
var
getAncestorByAttribute
=
(
elem
,
attr
,
val
)
=>
{
while
(
elem
.
getAttribute
(
attr
)
!=
val
||
elem
==
null
)
elem
=
elem
.
parentElement
;
return
elem
;
}
var
getDescendantByAttribute
=
(
elem
,
attr
,
val
)
=>
{
if
(
elem
==
null
||
elem
.
getAttribute
(
attr
)
==
val
)
return
elem
;
return
Array
.
from
(
elem
.
children
).
reduce
(
(
a
,
b
)
=>
{
let
x
=
getDescendantByAttribute
(
a
,
attr
,
val
);
let
y
=
getDescendantByAttribute
(
b
,
attr
,
val
);
return
x
==
null
?
y
:
x
;
},
null
);
}
/**
* Armado de formulario
*/
function
removeTab
(
button
){
let
tabs
=
document
.
getElementById
(
'tabs'
)
tabs
.
removeChild
(
getAncestorByAttribute
(
button
,
'name'
,
'Tab'
)
)
if
(
tabs
.
childElementCount
==
0
){
document
.
getElementById
(
"ContinuarText"
).
style
.
display
=
'none'
;
document
.
getElementById
(
"ContinuarButton"
).
style
.
display
=
'none'
;
}
}
function
addField
(
b
,
n
){
let
newfield
=
document
.
createElement
(
"div"
);
newfield
.
setAttribute
(
"name"
,
"Field"
);
newfield
.
innerHTML
=
document
.
getElementById
(
"fieldTemplate"
).
innerHTML
;
accessNumber
(
newfield
).
setAttribute
(
"value"
,
n
);
// swap
let
container
=
b
.
parentElement
;
container
.
appendChild
(
newfield
);
container
.
appendChild
(
b
);
}
function
addTab
(
t
,
n
){
document
.
getElementById
(
"ContinuarText"
).
style
.
display
=
'block'
;
document
.
getElementById
(
"ContinuarButton"
).
style
.
display
=
'block'
;
let
newtab
=
document
.
createElement
(
"div"
);
newtab
.
setAttribute
(
"name"
,
"Tab"
);
newtab
.
innerHTML
=
document
.
getElementById
(
"tabTemplate"
).
innerHTML
;
accessNumber
(
newtab
).
setAttribute
(
"value"
,
n
);
t
.
appendChild
(
newtab
);
}
/**
* Lectura de información y formateado
*/
function
processField
(
field
){
let
data
=
field
.
children
[
0
];
return
{
'Title'
:
data
.
children
[
1
].
value
,
'Input'
:
data
.
children
[
2
].
selectedOptions
[
0
].
value
,
'Required'
:
data
.
children
[
3
].
checked
,
};
}
function
processTab
(
tab
){
let
dict
=
[];
let
container
=
getDescendantByAttribute
(
tab
,
"name"
,
"Field"
);
if
(
container
==
null
)
return
dict
;
container
=
container
.
parentElement
;
for
(
let
i
=
0
;
i
<
container
.
children
.
length
;
i
++
){
if
(
container
.
children
[
i
].
getAttribute
(
"name"
)
==
"Field"
)
{
dict
.
push
(
processField
(
container
.
children
[
i
]));
}
}
return
dict
;
}
function
generate
(
tabs
){
let
dict
=
[];
for
(
let
i
=
0
;
i
<
tabs
.
children
.
length
;
i
++
)
{
let
c
=
tabs
.
children
[
i
];
if
(
c
.
getAttribute
(
"name"
)
==
"Tab"
)
{
dict
.
push
({
"Title"
:
getDescendantByAttribute
(
c
,
"class"
,
"TabTitle"
).
value
,
"Fields"
:
processTab
(
c
),
});
}
}
console
.
log
(
JSON
.
stringify
(
dict
));
return
dict
;
}
function
sortChildren
(
container
,
number
){
let
fixinput
=
a
=>
number
(
a
).
nodeName
==
"INPUT"
&&
number
(
a
).
type
==
"number"
?
parseInt
(
number
(
a
).
value
)
:
Infinity
;
Array
.
from
(
container
.
children
).
sort
(
(
a
,
b
)
=>
fixinput
(
a
)
<
fixinput
(
b
)
?
-
1
:
fixinput
(
a
)
>
fixinput
(
b
)
?
1
:
0
).
forEach
(
c
=>
container
.
appendChild
(
c
)
)
}
function
maxChild
(
container
,
number
){
let
fixinput
=
a
=>
number
(
a
).
nodeName
==
"INPUT"
&&
number
(
a
).
type
==
"number"
?
parseInt
(
number
(
a
).
value
)
:
0
;
if
(
container
.
childElementCount
==
0
)
return
0
;
let
max
=
Array
.
from
(
container
.
children
).
reduce
(
(
a
,
b
)
=>
fixinput
(
a
)
>
fixinput
(
b
)
?
a
:
b
);
return
fixinput
(
max
);
}
function
validate
(
obj
){
const
internal
=
"Hubo un error en la generación del formulario"
;
if
(
typeof
obj
!=
"object"
)
return
triggerError
(
internal
,
"not object"
);
for
(
let
t_it
=
0
;
t_it
<
obj
.
length
;
t_it
++
)
{
let
tab
=
obj
[
t_it
];
if
(
"Title"
in
tab
&&
"Fields"
in
tab
){
if
(
typeof
tab
.
Title
!=
"string"
)
return
triggerError
(
internal
,
"wrong type in tab title"
);
if
(
typeof
tab
.
Fields
!=
"object"
)
return
triggerError
(
internal
,
"wrong type in tab fields"
);
if
(
tab
.
Title
==
""
)
return
triggerError
(
"La tab "
+
(
t_it
+
1
)
+
" necesita un título"
,
"empty tab title"
);
if
(
tab
.
Fields
.
length
==
0
)
return
triggerError
(
"La tab "
+
(
t_it
+
1
)
+
" requiere campos"
,
"empty tab fields"
);
for
(
let
f_it
=
0
;
f_it
<
tab
.
Fields
.
length
;
f_it
++
)
{
let
field
=
tab
.
Fields
[
f_it
];
if
(
"Title"
in
field
&&
"Input"
in
field
&&
"Required"
in
field
)
{
if
(
typeof
field
.
Title
!=
"string"
)
return
triggerError
(
internal
,
"wrong type in field title"
);
if
(
typeof
field
.
Input
!=
"string"
)
return
triggerError
(
internal
,
"wrong type in field input"
);
if
(
typeof
field
.
Required
!=
"boolean"
)
return
triggerError
(
internal
,
"wrong type in field required"
);
if
(
field
.
Title
==
""
)
return
triggerError
(
"El campo "
+
(
f_it
+
1
)
+
" del tab "
+
(
t_it
+
1
)
+
" necesita un título"
,
"empty field title"
);
if
(
field
.
Input
==
""
)
return
triggerError
(
"El campo "
+
(
f_it
+
1
)
+
" del tab "
+
(
t_it
+
1
)
+
" necesita un input"
,
"empty field input"
);
}
else
{
return
triggerError
(
internal
,
"field lacks property"
)
}
}
}
else
{
return
triggerError
(
internal
,
"tab lacks property"
)
}
}
}
function
triggerError
(
type
,
log
){
let
out
=
"triggerError => \nerror_message = "
+
type
;
if
(
log
)
out
+=
"\nlog_message = "
+
log
;
console
.
log
(
out
);
document
.
getElementById
(
"ErrorMessage"
).
innerText
=
type
;
}
\ No newline at end of file
static/Style/ArmadoDeForm.css
View file @
031e496
html
{
--Color
:
rgb
(
1
,
194
,
120
);
font-family
:
'Montserrat'
,
sans-serif
;
}
...
...
@@ -23,6 +23,7 @@ body {
}
.BotonesContainer
{
min-height
:
40px
;
width
:
100%
;
height
:
5%
;
text-align
:
center
;
...
...
@@ -50,8 +51,8 @@ body {
border-radius
:
5px
5px
0px
0px
;
background-color
:
rgb
(
168
,
168
,
168
);
border
:
none
;
border-bottom
:
2px
solid
rgb
(
120
,
120
,
120
);
height
:
100%
;
margin
:
0.1%
;
}
.BotonesActive
{
...
...
@@ -68,7 +69,7 @@ body {
display
:
none
;
height
:
auto
;
background-color
:
var
(
--Color
);
overflow
:
scroll
;
overflow
:
hidden
;
}
.TabCard
{
...
...
@@ -87,78 +88,104 @@ body {
.TabTitle
{
text-align
:
center
;
font-size
:
5
vw
;
font-size
:
5
0px
;
font-weight
:
bolder
;
padding
:
inherit
;
margin-bottom
:
20px
;
border-bottom
:
5px
solid
rgb
(
114
,
126
,
119
);
border-bottom
:
3px
solid
rgb
(
120
,
120
,
120
);
}
.FieldsContainer
{
text-align
:
center
;
margin
:
auto
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-around
;
width
:
100%
;
}
.FieldTitles
{
width
:
20%
;
.Field
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-evenly
;
text-align
:
center
;
margin
:
auto
;
justify-content
:
space-between
;
}
.FieldTitles
div
{
font-size
:
2vw
;
.FieldTitle
{
width
:
20%
;
text-align
:
center
;
margin
:
auto
;
font-size
:
20px
;
font-weight
:
bold
;
text-align
:
center
;
margin-top
:
5
vh
;
margin-bottom
:
5
vh
;
margin-top
:
5
0
;
margin-bottom
:
5
0
;
}
.FieldInput
s
{
.FieldInput
{
width
:
70%
;
text-align
:
center
;
font-weight
:
bold
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-evenly
;
margin
:
auto
;
}
.FieldInputs
input
,
.FieldInputs
select
{
font-size
:
2vw
;
margin-top
:
5vh
;
margin-bottom
:
5vh
;
.FieldInput
input
,
.FieldInput
select
{
width
:
70%
;
font-size
:
20px
;
margin-top
:
50
;
margin-bottom
:
50
;
}
.FieldInput
s
select
{
.FieldInput
select
{
text-overflow
:
ellipsis
;
}
.FieldInput
s
input
[
type
=
'checkbox'
]
{
.FieldInput
input
[
type
=
'checkbox'
]
{
-webkit-appearance
:
none
;
width
:
2vw
;
height
:
2vw
;
width
:
30px
;
height
:
30px
;
background
:
white
;
border-radius
:
5px
;
border
:
2px
solid
#555
;
margin-top
:
5vh
;
margin-bottom
:
5vh
;
}
.FieldInput
s
input
[
type
=
'checkbox'
]
:checked
{
.FieldInput
input
[
type
=
'checkbox'
]
:checked
{
background
:
rgb
(
91
,
145
,
255
);
}
@media
(
max-width
:
600px
)
{
.BotonResultCont
{
margin
:
1%
auto
;
height
:
10%
;
vertical-align
:
baseline
;
align-content
:
center
;
.Checkbox
{
width
:
46%
;
float
:
left
;
padding
:
1%
;
}
.Checkbox
div
{
width
:
50%
;
float
:
left
;
vertical-align
:
middle
;
line-height
:
30px
;
}
.Checkbox
input
[
type
=
"checkbox"
]
{
margin-top
:
0
;
margin-bottom
:
0
;
}
.CheckboxTitle
{
font-size
:
20px
;
}
.Separator
{
width
:
85%
;
margin
:
auto
;
}
.Other
{
display
:
none
;
}
@media
(
max-width
:
500px
)
{
.Checkbox
{
width
:
98%
;
}
}
/*
...
...
templates/field.html
View file @
031e496
{% macro field(title,type,placeholder="",options=[],required=False) %}
{% if type == "select" %}
<select
{%
if
required
%}
required
{%
endif
%}
>
<div
class=
"Field"
>
<div
class=
"FieldTitle"
>
{{ title|title }}
</div>
<div
class=
"FieldInput"
>
{% if type == "select" %}
<select
onchange=
"Otro(this)"
{%
if
required
%}
required
{%
endif
%}
>
<option
selected
disabled
hidden
value=
""
>
{{ placeholder }}
</option>
{% for option in options %}
{% if option == "#other" %}
<option
value=
"Otro"
>
Otro
</option>
{% else %}
<option
value=
"{{ option }}"
>
{{ option }}
</option>
{% endif %}
{% endfor %}
</select>
<input
type=
"text"
class=
"Other"
>
{% elif type == "checkbox" %}
{% if options|length == 0 %}
<input
type=
"checkbox"
{%
if
required
%}
required
{%
endif
%}
>
{% endif %}
{% for option in options %}
{% if option == "#other" %}
<div
class=
"Checkbox"
>
<div
class=
"CheckboxTitle"
>
Otro
</div>
<div>
<input
type=
"checkbox"
onclick=
"Otro(this)"
{%
if
required
%}
required
{%
endif
%}
>
</div>
</div>
{% else %}
<div
class=
"Checkbox"
>
<div
class=
"CheckboxTitle"
>
{{ option|title }}
</div>
<div>
<input
type=
"checkbox"
{%
if
required
%}
required
{%
endif
%}
>
</div>
</div>
{% endif %}
{% endfor %}
<input
type=
"text"
class=
"Other"
>
{% else %}
{% else %}
<input
type=
"{{ type }}"
placeholder=
"{{ placeholder }}"
{%
if
required
%}
required
{%
endif
%}
>
{% endif %}
{% endif %}
</div>
</div>
<hr
class=
"Separator"
>
{% endmacro %}
\ No newline at end of file
templates/form.html
View file @
031e496
<html
lang=
"en"
>
<head>
<script
src=
"{{url_for('static',filename='Scripts/construct.js')}}"
></script>
<script
src=
"{{url_for('static',filename='Scripts/ArmadoDeForm.js')}}"
></script>
<meta
charset=
"UTF-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<link
rel=
"stylesheet"
href=
"{{url_for('static',filename='Style/Templates.css')}}"
>
<link
rel=
"stylesheet"
href=
"{{url_for('static',filename='Style/ArmadoDeForm.css')}}"
>
<link
href=
"https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel=
"stylesheet"
>
<title>
Generador de Formularios
</title>
...
...
@@ -15,12 +13,12 @@
document.getElementById('BotonesContainer'),
document.getElementById('TabsContainer'),
0
)"
>
)
, document.documentElement.style.setProperty('--Color','{{ color }}')
"
>
<h1
style=
"margin: 2% 0% 2% 0; font-size: 5vw;"
>
{{ title|title }}
</h1>
<section
id=
"BotonesContainer"
class=
"BotonesContainer"
>
{% set m = tabs|length %}
{% for i in range(m) %}
<button
id=
"Boton{{i}}"
class=
"Botones"
style=
"width: {{
(100 - (0.2 * m)) /
m }}%;"
<button
id=
"Boton{{i}}"
class=
"Botones"
style=
"width: {{
100/
m }}%;"
onclick=
"HabilitarTab(
document.getElementById('BotonesContainer'),
document.getElementById('TabsContainer'),
...
...
templates/tab.html
View file @
031e496
...
...
@@ -7,19 +7,9 @@
{% from "field.html" import field %}
<div
class=
"FieldsContainer"
>
<div
class=
"FieldTitles"
>
{% for f in fields %}
<div>
{{ f['title']|title }}
</div>
{{ field(title=f['title'], type=f['type'], placeholder=f['placeholder'], options=f['options'], required=f['required']) }}
{% endfor %}
</div>
<div
class=
"FieldInputs"
>
{% for f in fields %}
{{ field(type=f['type'], placeholder=f['placeholder'], options=f['options'], required=f['required']) }}
{% endfor %}
</div>
</div>
<input
type=
"button"
,
value=
"Back"
>
<input
type=
"button"
,
value=
"Next"
>
{% endmacro %}
\ No newline at end of file
Write
Preview
Styling with
Markdown
is supported
Attach a file
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 post a comment