views:

532

answers:

4

I have an inline model formset, and I'd like to make fields non-editable if those fields already have values when the page is loaded. If the user clicks an "Edit" button on that row, it would become editable and (using JavaScript) I would replace the original widgets with editable ones. I'd like to do something like this when loading the page:

for field in form.fields:
    if field.value:
        # display as text
    else:
        # display as my standard editable widget for this field

I see that inlineformset_factory has an argument called formfield_callback. I suspect that this could be useful, but so for I haven't found any documentation for it. Can anyone point me to some useful documentation for this, and how it can help me solve this problem?

A: 

I think you might be able to override the init function of your form that is used in a formset. There you could check for initial_data, and dynamically build your forms like you're hoping to do. At least, it sounds plausible in my head.

f4nt
Well, I'd need to check for an instance object, not initial_data, but I see what you're saying. Problem is, what do I do from there? How do I modify field widgets from within the ModelForm's __init__ method?
Jeff
Never mind. self.fields['fieldname'].widget...
Jeff
A: 

I had a question where I wanted to "Auto-generate form fields", can found a solution for dynamically creating forms, it may help:

http://stackoverflow.com/questions/1409192/auto-generate-form-fields-for-a-form-in-django

It's not clean and there's probably a better way to handle this.

How about just sending the data as editable (normal formset) from django and do the value check with javascript, using javascript to toggle the widgets?

monkut
Yeah, using JavaScript is my fallback. I'd prefer not to do that, though, if I can construct the forms as I want them on the server. I should be able to do that; it's just a matter of finagling django into allowing me that kind of customization.
Jeff
A: 

This one stumped me for a bit too. Hopefully this is what you're looking for.

{{ formset.management_form }} {% for form in formset.forms %} {{ form.id }} {{ form.FirstName }} {{ form.instance.LastName }} {% endfor %}

Aaron C. de Bruyn
A: 

This thread is a bit old, but for anyone looking:

in the form:

myfield=forms.CharField( widget=forms.TextInput(attrs={'class':'disabled', 'readonly':'readonly'}))

The "readonly" is an HTML attribute that makes the form uneditable. "disabled" is a CSS class as you'll want to modify the default styling, also it makes the jQuery simpler.

To make readonly inputs editable when clicked, here's a jQuery example:

$('input.disabled').click(function(){
    $(this).removeAttr('readonly').removeClass('disabled');
});
Rich