I have two models:
class Studio(models.Model):
name = models.CharField("Studio", max_length=30, unique=True)
class Film(models.Model):
studio = models.ForeignKey(Studio, verbose_name="Studio")
name = models.CharField("Film Name", max_length=30, unique=True)
And I want to create a form for Film. The form should have a drop down for Studio, but allow the user to enter a new Studio if the one they need isn’t already in the database. First, if there’s a simpler way to implement this, let me know.
But what I’m trying to do is include a “+” icon next to the Studio dropdown. If this is clicked, it unhides a new field that allows the user to enter text for a new Studio. I want to include a “-” button next to the unhid field that rehides it if the user changes their mind. That’s where I’m getting stuck.
My form currently looks like this:
class SelectWithPlus(forms.Select):
def render(self, name, *args, **kwargs):
html = super(SelectWithPlus, self).render(name, *args, **kwargs)
plus = render_to_string("form/plus.html", {'field': name})
return html+plus
class DeSelectWithX(forms.CharField):
def render(self, name, *args, **kwargs):
html = super(DeSelectWithX, self).render(name, *args, **kwargs)
ex = render_to_string("form/ex.html", {'field': name})
return html+ex
class FilmForm(forms.Form):
required_css_class = 'required'
studio = forms.ModelChoiceField(Studio.objects, widget = SelectWithPlus)
new_studio = forms.CharField(max_length=30, required=False, label = "New Studio Name", widget = DeSelectWithX)
name = forms.CharField(max_length=30, label = "Film Name")
def __init__(self, *args, **kwargs):
super(MdlForm, self).__init__(*args,**kwargs)
self.fields['new_studio'].widget.attrs['class'] = 'hidden_studio_field'
The idea is that the studio field has a widget that adds a bit of html for a “+” icon:
<a
href="JavaScript:void()"
class="add-another"
id="add_id_{{ field }}">
<img src="http://mydbupload.s3.amazonaws.com/icon_addlink.gif" width="10" height="10" Border ="0" alt="Add New {{ field }}"/>
</a>
When this is clicked, it triggers jquery to show the fields named appropriately:
<script type="text/javascript">
$(document).ready(function() {
$(".hidden_studio_field").hide();
$('label[for="id_new_studio"]').hide();
});
$(function () {
$('#add_id_studio').click(function() {
$(".hidden_studio_field").show();
$('label[for="id_new_studio"]').show();
});
});
</script>
So I want to add a similar “-” button to the new_studio field. I tried to replicate the SelectWithPlus widget, but the one snag I’m hitting is that I can no longer use the bit of code that adds the class “hidden_studio_field” to that field. I get an error: ‘DeSelectWithX’ object has no attribute ‘attrs’
So short question: How do I add a css-type class to a field that is defined by a widget?
DeSelectWithXshould inherit fromforms.TextInput, notforms.CharField.