Hola, pude agregar la opción "otros" en un checkbox de selección múltiple, pero ahora aparece otro error es que cada vez que hago el check y escribo algo en otros me aparece como un nuevo elemento checkbox. como podría solucionarlo?. Espero cualquier sugerencia, Gracias!
# 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