Change tenant status field

I have tenant change view as below outside of admin (not using Django admin):

class TenantChangeView(UpdateView):
    model = Tenant
    template_name = 'change-form.html'
    form_class = TenantChangeForm
    ......

and the form as

class TenantChangeForm(forms.ModelForm):
    class Meta:
        model = Tenant
        fields = ('name', 'slug', 'status',)

    def __init__(self, *args, **kwargs):
        super(TenantChangeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            'name',
            Row(
                Column('slug'),
                Column('status'),
            ),
            Submit('submit', 'Update'),
        )

The change-form.html is pretty much just a form skeleton, nothing about fields.
The status field has 4 valid values, say, active, trial, reported, inactive. I want to add 2 features:

  1. When the current status value is ‘inactive’, I want all other fields on the page not editable, only status can be changed. Any other status value allow changing all fields.
  2. On submit with status change, or when status is changed, I want to pop up or display a window and/or text field ask user a reason for the status change, and save the reason into database table.
    How to achieve them?

Can someone change the current status from “inactive” to “active”? If so, are they then immediately able to update the other fields? (Or do they need to save the status change first?)

Also, what do you want to have happen if a field is changed, and then the status is changed from “active” to “inactive”?

Either way, you’ll need to implement the client side using JavaScript. You’ll need to change the attributes of those fields and manage the modal dialog.

Yes, can change from inactive to active. When I said not allow to edit other fields when status is ‘inactive’, the ‘current’ actually refer to database saved or form original displayed status value. So when status is changed from ‘inactive’ to ‘active’, other fields should still not editable. They need to save the status change first.
If this is hard to implement, or you think it’s not common to do this, I can give up on this. Just feel it doesn’t make sense to allow user make other changes when the status is ‘inactive’. Not so desired.
To your second question, this change should still require a change reason, but can be submitted with other changed fields as normal. And should be still able to make other field changes since the original form ‘status’ value is not ‘inactive’.
For my second wished feature, I don’t want the modal shown up unless the status is changed. But where to make this check? I thought I’d check in field clean method, but then realized I may not have the original value to compare there. I thought about either use modal or a reason form field, but both need to conditionally shown on the status comparison. I don’t know where and how to do it.

That makes it easier. In that case, you don’t need to use JavaScript for this. You can disable the form fields in your form depending upon the status.

There are a number of different ways to do this, all using JavaScript.
I would probably do this one of these two ways.

  • Set a different variable to the original status code. Then, when the submit button is pressed, check the current value of the status field to see if it has changed. If it has, present the modal box for the input and include that in the submitted data.

  • Capture the “Change” event on the status field. If that changes, display the modal box at that time.

How to specifically do this is going to depend greatly upon what JavaScript frameworks you may be using.

Was able to finish the one that disable other fields when status is inactive. Also able to check the status values with clean method.
But still struggling on showing/hiding reason field when status changes. My form class is now become as

class TenantChangeForm(forms.ModelForm):
    change_reason = forms.CharField(
        widget=forms.Textarea(),
        label='Status Change Reason',
        required=False,
    )

    class Meta:
        model = Tenant
        fields = ('name', 'slug', 'status',)

    def __init__(self, *args, **kwargs):
        super(TenantChangeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            'name',
            Row(
                Column('slug'),
                Column('status', 'change_reason'),
            ),
            Submit('submit', 'Update'),
        )

Now the issue becomes, how to hide field ‘change_reason’ when status field value is not changed from its initial value, and show field when the status value is different from initial value?
I saw the field can be hidden initially within form init() as below

    Column('status', Field('change_reason', type='hidden'),

but I don’t know when needed, how to switch between hide and show.

To my surprise, I stuck on the creation of on-change listener of the ‘status’ field. I thought it was an easy task, but ended up with no code worked. I even directly added listener on the template file, no help. I burnt out and gave up. Thanks.