Respuesta: Problemas con widgets Hola, ya pude agregar la opcion "otros" en un checkbox, pero ahora aparece otro error es que cada vez que escribo algo en otros me aparece como un nuevo elemento checkbox. como podria solucionarlo.
# coding=utf-8
from __future__ import unicode_literals
from itertools import chain
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.forms.widgets import CheckboxSelectMultiple
from django.forms.widgets import CheckboxInput, TextInput
class CheckboxSelectOther(CheckboxSelectMultiple):
def render(self, name, value, attrs=None, choices=()):
if value is None: value = []
has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name)
output = ['<ul>']
# Normalize to strings
str_values = set([force_text(v) for v in value])
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
# If an ID attribute was given, add a numeric index as a suffix,
# so that the checkboxes don't all have the same ID attribute.
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
label_for = format_html(' for="{0}"', final_attrs['id'])
else:
label_for = ''
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
option_value = force_text(option_value)
rendered_cb = cb.render(name, option_value)
option_label = force_text(option_label)
output.append(format_html('<li><label{0}>{1} {2}</label></li>',
label_for, rendered_cb, option_label))
label_for = ''
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
label_for = format_html(' for="{0}"', final_attrs['id'])
output.append(self.crear_otro_texto(name, final_attrs, label_for, str_values))
output.append('</ul>')
return mark_safe('\n'.join(output))
def crear_otro_texto(self, name, final_attrs, label_for, str_values):
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
option_value = force_text(-1)
rendered_cb = cb.render(name, option_value)
option_label = force_text("Otro")
tb = TextInput()
rendered_tb = tb.render(name + "-otro", "")
return format_html('<li><label{0}>{1} {2} {3}</label></li>', label_for, rendered_cb, option_label, rendered_tb)
def value_from_datadict(self, data, files, name):
values = super(CheckboxSelectOther, self).value_from_datadict(data, files, name)
if "-1" in values and (name + "-otro") in data:
indice = values.index('-1')
values[indice] = data[name + "-otro"]
return values |