Estimados,
sigo en mi camino de aprendizaje de web2py y ahora estoy tratando de hacer un formulario para completar unos varios datos en una tabla.
Tengo en el modelo lo siguiente:
db.define_table('general_date',
Field('type', required=True, requires=IS_IN_SET(GENERAL_DATE_TYPE), label=T("Date Type")),
Field('year', 'integer', length=4, required=True, requires=IS_IN_SET(['2013', '2014', '2015', '2016', '2017', '2018']), label=T("Year")),
Field('date', 'date', required=True, requires=IS_DATE(DATE_FORMAT), label=T("Date")),
Field('start_time', 'time', requires=IS_EMPTY_OR(IS_TIME()), label=T("Start Time")),
Field('end_time', 'time', requires=IS_EMPTY_OR(IS_TIME()), label=T("End Time")),
auth.signature
) donde
GENERAL_DATE_TYPE es una lista con los valores que puede tomar.
GENERAL_DATE_TYPE = ['reunion1', 'reunion2', 'asamblea', 'examen', 'encuesta']La idea es tener por año un conjunto único de datos, es decir, sólo uno de los definidos en
GENERAL_DATE_TYPE. Así en 2013 tenemos una reuníon1, una reunión2, una asamblea, un examen y una encuesta. Lo mismo para el 2014 y así sucesivamente. También se podría pensar en algo como una lista de feriados...
Entonces en el controlador tengo todo el formulario. Que tiene un campo año que me deja elegir entre la lista de años posibles definida en el modelo y a partir de ahí completa los valores que existen. Hasta ahora eso lo tengo funcionando pero para el año actual. El tema es si quiero hacer algún cambio en otros años, no sé como hacer el update de los valores del formulario sin que me falle o no funcione. He aquí el controlador...
def new_dates():
## Creo el formulario para la selección del año.
form = SQLFORM.factory(db.general_date.year)
## Para cada tipo de fecha posible en un año, genero los campos a completar y lo agrego al formulario anterior.
for date_type in GENERAL_DATE_TYPE:
fila = TR(LABEL(B(date_type)))
fila += TR(LABEL(T("Date")+":"), INPUT(_name=date_type.replace(' ','_')+'_date', _class="date", requires=IS_EMPTY_OR(IS_DATE(DATE_FORMAT))), _id=date_type.replace(' ','_')+"_date__row")
fila += TR(LABEL(T("Start Time")+":"), INPUT(_name=date_type.replace(' ','_')+'_start_time', _class="time", requires=IS_EMPTY_OR(IS_TIME())), _id=date_type.replace(' ','_')+"_start_time__row")
fila += TR(LABEL(T("End Time")+":"), INPUT(_name=date_type.replace(' ','_')+'_end_time', _class="time", requires=IS_EMPTY_OR(IS_TIME())), _id=date_type.replace(' ','_')+"_end_time__row")
form[0].insert(-1, fila)
## Si no envié ningún año, que automáticamente seleccione el año actual en el momento de cargar la página.
if not request.vars.year:
form.vars.year = request.now.year
else:
form.vars.year = request.vars.year
## Con el año seleccionado busco en la tabla los valores que haya correspondientes a ese año y completo los campos del formulario.
data = db(db.general_date.year==form.vars.year).select(db.general_date.type, db.general_date.date, db.general_date.start_time, db.general_date.end_time)
## Completo los campos que contienen datos.
for row in data:
fieldtype = row.type
fieldtype = fieldtype.replace(' ', '_')
form.vars[fieldtype+'_date'] = row.date.strftime(DATE_FORMAT)
if not row.start_time:
form.vars[fieldtype+'_start_time'] = row.start_time
if not row.end_time:
form.vars[fieldtype+'_end_time'] = row.end_time
## Si el formulario valida construyo la consulta de inserción.
if form.validate():
for field, value in form.vars.items():
fieldtype = ""
date = ""
start_time = ""
end_time = ""
if not value:
continue
elif "_date" in field:
fieldname = field.split("_date")
fieldtype = fieldname[0].replace('_', ' ')
date = value
start_time = form.vars[fieldname[0]+"_start_time"]
end_time = form.vars[fieldname[0]+"_end_time"]
elif "_start_time" in field:
continue
elif "_end_time" in field:
continue
elif "year" in field:
continue
else:
pass
## Me fijo que el tipo de fecha y el año coincidan para sobrescribir ese campo y no generar uno nuevo.
## Si no existe, creamos uno nuevo con los valores.
db.general_date.update_or_insert((db.general_date.type==fieldtype)&(db.general_date.year==form.vars.year), type=fieldtype, year=form.vars.year, date=date, start_time=start_time, end_time=end_time)
response.flash = T("new record inserted")
return dict(form=form)
Tal vez haya una manera más fácil de hacerlo y sólo me dediqué a complicarme la vida. No lo sé, pero no se me ocurrió otra manera... Por ahora como lo tengo mínimamente funciona. El problema es que quiero hacer que cuando elijo de la lista desplegable del año un año diferente al actual que se actualice sólo sin tener que apretar ningún botón... cómo puedo hacerlo? Intenté con algo de jQuery (que no conozco y me limito a hacer un poco de copy-paste e intentar) pero tampoco tuve éxito.