From adea1606b46a02dc7769ed0a1904f3f285d90a71 Mon Sep 17 00:00:00 2001 From: Felipe Vieira Date: Fri, 9 Dec 2011 11:31:52 +0000 Subject: [PATCH] mostrando/escondendo perguntas dependentes --- .../diagnosticos_categorias_form.js | 51 +++++++++++++++- sigi/apps/diagnosticos/forms.py | 12 ++-- sigi/apps/diagnosticos/widgets.py | 61 +++++++++++++++++++ 3 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 sigi/apps/diagnosticos/widgets.py diff --git a/media/js/diagnosticos/diagnosticos_categorias_form.js b/media/js/diagnosticos/diagnosticos_categorias_form.js index 9888404..de6f848 100644 --- a/media/js/diagnosticos/diagnosticos_categorias_form.js +++ b/media/js/diagnosticos/diagnosticos_categorias_form.js @@ -35,15 +35,60 @@ $('#page').live('pageinit', function(event){ }); // remove a resposta vazia da interface - $("div.ui-radio span.ui-btn-text:contains('---------')").parentsUntil("ul").hide() + $("div.ui-radio span.ui-btn-text:contains('---------')").parentsUntil("ul").hide(); // para todo input do from registra um evento // ao modificar o campo $("div.ui-field-contain textarea, div.ui-field-contain input, div.ui-field-contain select").change(function () { + // mostra ou esconde uma pergunta dependente + var id_to_open = [] + var id_to_close = [] + $('input[name=' + $(this).attr('name') + ']').each(function () { + schema = $(this); + schema_to_open = schema.attr('schema_to_open'); + if (schema_to_open) { + if (schema.is(':checked')) + id_to_open.push(schema_to_open) + else + id_to_close.push(schema_to_open) + } + }); + + for (var i in id_to_close) { + id = id_to_close[i] + // Evita apagar uma pergunta caso ela possa + // ser exibida por outra questão + if (id_to_open.indexOf(id_to_close[i]) == -1) { + // limpa o valor para não salva-lo + // no submit do form + $("#" + id + " input").val(''); + $("#" + id).slideUp(); + } + } + + // Exibe as perguntas que devem estar disponiveis + for (var i in id_to_open) { + id = id_to_open[i] + $("#" + id).slideDown(); + } + $.ajax({ data: $('#diagnostico').serializeArray() - }) - }) + }); + + }); + + $('input[schema_to_open]').each(function () { + schema = $(this); + schema_to_open = $("#" + schema.attr('schema_to_open')); + schema_to_open.hide(); + }); + + $('input[schema_to_open]:checked').each(function () { + schema = $(this); + schema_to_open = $("#" + schema.attr('schema_to_open')); + schema_to_open.show(); + }); // se carregou o js sem erros mostra as perguntas $("#waiting").hide(); diff --git a/sigi/apps/diagnosticos/forms.py b/sigi/apps/diagnosticos/forms.py index fa5cdb3..8eda91a 100644 --- a/sigi/apps/diagnosticos/forms.py +++ b/sigi/apps/diagnosticos/forms.py @@ -3,17 +3,17 @@ from copy import deepcopy from django import forms from django.forms.forms import BoundField -from django.forms import (BooleanField, CharField, CheckboxSelectMultiple, - DateField, FloatField, ModelChoiceField, - ModelMultipleChoiceField, RadioSelect, Textarea) +from django.forms import (BooleanField, CharField, DateField, + FloatField, ModelChoiceField, Textarea, + ModelMultipleChoiceField) from django.contrib.contenttypes.generic import generic_inlineformset_factory from sigi.apps.casas.models import CasaLegislativa, Funcionario from sigi.apps.contatos.models import Telefone from sigi.apps.diagnosticos.models import Diagnostico +from sigi.apps.diagnosticos.widgets import EavCheckboxSelectMultiple, EavRadioSelect from eav.forms import BaseDynamicEntityForm from eav.fields import RangeField - class DiagnosticoForm(BaseDynamicEntityForm): """Classe responsável por contruir o formulário, vinculando ao modelo Diagnostico @@ -39,8 +39,8 @@ class DiagnosticoMobileForm(BaseDynamicEntityForm): } FIELD_EXTRA = { - 'one': {'widget': RadioSelect}, - 'many': {'widget': CheckboxSelectMultiple}, + 'one': {'widget': EavRadioSelect}, + 'many': {'widget': EavCheckboxSelectMultiple}, } FIELD_WIDGET = { diff --git a/sigi/apps/diagnosticos/widgets.py b/sigi/apps/diagnosticos/widgets.py new file mode 100644 index 0000000..a9d630b --- /dev/null +++ b/sigi/apps/diagnosticos/widgets.py @@ -0,0 +1,61 @@ +from itertools import chain +from django.forms.widgets import CheckboxInput, CheckboxSelectMultiple, RadioSelect, RadioFieldRenderer, RadioInput +from django.utils.html import conditional_escape +from django.utils.encoding import force_unicode +from django.utils.safestring import mark_safe +from sigi.apps.diagnosticos.models import Escolha + +class EavCheckboxSelectMultiple(CheckboxSelectMultiple): + def render(self, name, value, attrs=None, choices=()): + if value is None: value = [] + final_attrs = self.build_attrs(attrs, name=name) + output = [u'') + return mark_safe(u'\n'.join(output)) + +class EavRadioFieldRenderer(RadioFieldRenderer): + def __iter__(self): + for i, choice in enumerate(self.choices): + final_attrs = self.attrs.copy() + + # Caso exista uma pergunta para abrir + # adiciona um atripbuto no checkbox + if choice[0]: + schema_to_open = Escolha.objects.get(pk=choice[0]).schema_to_open + if schema_to_open: + final_attrs['schema_to_open'] = schema_to_open.name + + yield RadioInput(self.name, self.value, final_attrs, choice, i) + + def __getitem__(self, idx): + choice = self.choices[idx] + + final_attrs = self.attrs.copy() + + # Caso exista uma pergunta para abrir + # adiciona um atripbuto no checkbox + schema_to_open = Escolha.objects.get(pk=self.value).schema_to_open + if schema_to_open: + final_attrs['schema_to_open'] = schema_to_open.name + + return RadioInput(self.name, self.value,final_attrs, choice, idx) + +class EavRadioSelect(RadioSelect): + renderer = EavRadioFieldRenderer +