Commit 031e4964 by Luciano Barletta

added checkbox and others

1 parent e5b86009
...@@ -58,51 +58,42 @@ def login(): ...@@ -58,51 +58,42 @@ def login():
def main(): def main():
data = [ data = [
{ {
"title" : "first", "title" : "general",
"fields" : [ "fields" : [
{ {
"title" : "1", "title" : "nombre",
"type" : "mail",
"placeholder" : "example@example.com",
},
{
"title" : "2",
"type" : "file",
"placeholder" : "999",
},
{
"title" : "3",
"type" : "checkbox",
"placeholder" : "999",
},
{
"title" : "4",
"type" : "text", "type" : "text",
"placeholder" : "Luciano",
"required" : True "required" : True
},
{
"title" : "mail",
"type" : "mail",
"placeholder" : "ejemplo@gmail.com",
} }
] ]
}, },
{ {
"title" : "second", "title" : "detalles",
"fields" : [ "fields" : [
{ {
"title" : "first", "title" : "género",
"type" : "select", "type" : "select",
"placeholder" : "nedea", "placeholder" : "Gènero",
"options" : [ "options" : [
"first", "Hombre",
"second", "Mujer",
"third" "#other"
] ]
}, },
{ {
"title" : "second", "title" : "Gusto",
"type" : "number", "type" : "checkbox",
"placeholder" : "999",
"options" : [ "options" : [
"first", "Hombres",
"second", "Mujeres",
"third"
"#other"
], ],
"required" : True "required" : True
} }
...@@ -113,7 +104,7 @@ def main(): ...@@ -113,7 +104,7 @@ def main():
"fields" : [] "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__": if __name__ == "__main__":
app.run("0.0.0.0") app.run("0.0.0.0")
\ No newline at end of file \ No newline at end of file
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){ function HabilitarTab(bc,tc,n){
if (typeof n != "number") return console.log("El entero es invalido"); if (typeof n != "number") return console.log("El entero es invalido");
...@@ -11,3 +25,16 @@ function HabilitarTab(bc,tc,n){ ...@@ -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 \ No newline at end of file
/**
* 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 \ No newline at end of file
html { html {
--Color: rgb(1, 194, 120);
font-family: 'Montserrat', sans-serif; font-family: 'Montserrat', sans-serif;
} }
...@@ -23,6 +23,7 @@ body { ...@@ -23,6 +23,7 @@ body {
} }
.BotonesContainer { .BotonesContainer {
min-height: 40px;
width: 100%; width: 100%;
height: 5%; height: 5%;
text-align: center; text-align: center;
...@@ -50,8 +51,8 @@ body { ...@@ -50,8 +51,8 @@ body {
border-radius: 5px 5px 0px 0px; border-radius: 5px 5px 0px 0px;
background-color: rgb(168, 168, 168); background-color: rgb(168, 168, 168);
border: none; border: none;
border-bottom: 2px solid rgb(120, 120, 120);
height: 100%; height: 100%;
margin: 0.1%;
} }
.BotonesActive{ .BotonesActive{
...@@ -68,7 +69,7 @@ body { ...@@ -68,7 +69,7 @@ body {
display: none; display: none;
height: auto; height: auto;
background-color: var(--Color); background-color: var(--Color);
overflow: scroll; overflow: hidden;
} }
.TabCard { .TabCard {
...@@ -87,78 +88,104 @@ body { ...@@ -87,78 +88,104 @@ body {
.TabTitle { .TabTitle {
text-align: center; text-align: center;
font-size: 5vw; font-size: 50px;
font-weight: bolder; font-weight: bolder;
padding: inherit; padding: inherit;
margin-bottom: 20px; margin-bottom: 20px;
border-bottom: 5px solid rgb(114, 126, 119); border-bottom: 3px solid rgb(120, 120, 120);
} }
.FieldsContainer { .FieldsContainer {
text-align: center;
margin: auto; margin: auto;
display: flex; display: flex;
flex-direction: column;
justify-content: space-around; justify-content: space-around;
width: 100%; width: 100%;
} }
.FieldTitles{ .Field {
width: 20%;
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
justify-content: space-evenly;
text-align: center;
margin: auto;
} }
.FieldTitles div { .FieldTitle {
font-size: 2vw; width: 20%;
text-align: center;
margin: auto;
font-size: 20px;
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
margin-top: 5vh; margin-top: 50;
margin-bottom: 5vh; margin-bottom: 50;
} }
.FieldInputs { .FieldInput {
width: 70%; width: 70%;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
display: flex;
flex-direction: column;
justify-content: space-evenly;
margin: auto; margin: auto;
} }
.FieldInputs input, .FieldInput input,
.FieldInputs select { .FieldInput select {
font-size: 2vw; width: 70%;
margin-top: 5vh; font-size: 20px;
margin-bottom: 5vh; margin-top: 50;
margin-bottom: 50;
} }
.FieldInputs select { .FieldInput select {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.FieldInputs input[type='checkbox'] { .FieldInput input[type='checkbox'] {
-webkit-appearance: none; -webkit-appearance: none;
width: 2vw; width: 30px;
height: 2vw; height: 30px;
background: white; background: white;
border-radius: 5px; border-radius: 5px;
border: 2px solid #555; border: 2px solid #555;
margin-top: 5vh;
margin-bottom: 5vh;
} }
.FieldInputs input[type='checkbox']:checked { .FieldInput input[type='checkbox']:checked {
background: rgb(91, 145, 255); background: rgb(91, 145, 255);
} }
@media (max-width: 600px) { .Checkbox {
.BotonResultCont { width: 46%;
margin: 1% auto; float: left;
height: 10%; padding: 1%;
vertical-align: baseline; }
align-content: center;
.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%;
} }
} }
/* /*
......
{% macro field(title,type,placeholder="",options=[],required=False) %} {% macro field(title,type,placeholder="",options=[],required=False) %}
{% if type == "select" %} <div class="Field">
<select {% if required %} required {% endif %}> <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> <option selected disabled hidden value="">{{ placeholder }}</option>
{% for option in options %} {% for option in options %}
{% if option == "#other" %}
<option value="Otro">Otro</option>
{% else %}
<option value="{{ option }}">{{ option }}</option> <option value="{{ option }}">{{ option }}</option>
{% endif %}
{% endfor %} {% endfor %}
</select> </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 %}> <input type="{{ type }}" placeholder="{{ placeholder }}" {% if required %} required {% endif %}>
{% endif %} {% endif %}
</div>
</div>
<hr class="Separator">
{% endmacro %} {% endmacro %}
\ No newline at end of file \ No newline at end of file
<html lang="en"> <html lang="en">
<head> <head>
<script src="{{url_for('static',filename='Scripts/construct.js')}}"></script>
<script src="{{url_for('static',filename='Scripts/ArmadoDeForm.js')}}"></script> <script src="{{url_for('static',filename='Scripts/ArmadoDeForm.js')}}"></script>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <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 rel="stylesheet" href="{{url_for('static',filename='Style/ArmadoDeForm.css')}}">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<title>Generador de Formularios</title> <title>Generador de Formularios</title>
...@@ -15,12 +13,12 @@ ...@@ -15,12 +13,12 @@
document.getElementById('BotonesContainer'), document.getElementById('BotonesContainer'),
document.getElementById('TabsContainer'), document.getElementById('TabsContainer'),
0 0
)"> ), document.documentElement.style.setProperty('--Color','{{ color }}')">
<h1 style="margin: 2% 0% 2% 0; font-size: 5vw;"> {{ title|title }}</h1> <h1 style="margin: 2% 0% 2% 0; font-size: 5vw;"> {{ title|title }}</h1>
<section id="BotonesContainer" class="BotonesContainer"> <section id="BotonesContainer" class="BotonesContainer">
{% set m = tabs|length %} {% set m = tabs|length %}
{% for i in range(m) %} {% 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( onclick="HabilitarTab(
document.getElementById('BotonesContainer'), document.getElementById('BotonesContainer'),
document.getElementById('TabsContainer'), document.getElementById('TabsContainer'),
......
...@@ -7,19 +7,9 @@ ...@@ -7,19 +7,9 @@
{% from "field.html" import field %} {% from "field.html" import field %}
<div class="FieldsContainer"> <div class="FieldsContainer">
<div class="FieldTitles">
{% for f in fields %} {% 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 %} {% 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> </div>
<input type="button", value="Back">
<input type="button", value="Next">
{% endmacro %} {% endmacro %}
\ No newline at end of file \ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!