1

I have the following forms.py with radiobutton and other fields in it. Based on the selection of radio button, I should enable or disable other fields in the form.

Forms.py

class SampleForm(forms.ModelForm):
      option = forms.TypedChoiceField(choices=BoolChoices, widget=forms.RadioSelect(renderer=HorizontalRadioRenderer,attrs={'onchange':'check_status()'}), coerce=int,)
      otherFields = forms.IntegerField(
            widget=forms.TextInput(attrs={'size': 7, 'disabled':True}))
      .....
      .....
      class Meta:
        model = Sample
      class Media:
           js = ('checkoption.js'),

My question is should I use templates (extending admin/base_site.html) or just add templates dir under myapp/templates/myapp/template.html

In such cases if i'm using the following template.html and views.py

<form action="{% url myapp.views.check_option %}" method="POST">{% csrf_token %}
{{ form_as_p }} 
<input id="submit" type="button" value="Click" />

def check_option(request):
if request.method == 'GET':
    form = SsmpleForm()
else:
    form = SampleForm(request.POST)

if form.is_valid():
    opt = form.cleaned_data['option']
    if opt == 1:
        form.fields['otherFields'].widget.attrs['enabled'] = True
return render_to_response('verinc/template.html', {'form' : form,},context_instance=RequestContext(request))

Now how to map radio selection to this view? Is there any other solution to design this task in django.

Attempted to try with Ajax

$(document).ready(function(){
function check_status(){
    $.get("{% url myapp.views.check_option %}", function(data){
        console.log(data);
}
}
})(django.jQuery);
arulmr
  • 8,620
  • 9
  • 54
  • 69
Ria
  • 225
  • 1
  • 7
  • 18
  • What do you mean by `how to *map* radio selection to this view?` – Bibhas Debnath Mar 31 '14 at 09:01
  • I mean, to call the function defined in view check_option() when a radio button is clicked – Ria Mar 31 '14 at 09:09
  • `check_option` is the view. It'll be executed when you submit the form. – Bibhas Debnath Mar 31 '14 at 09:26
  • ok.. However i need to run the function for radio button click option. Is that possible? – Ria Mar 31 '14 at 09:33
  • Then you want an AJAX view that you can call onchange of the radio button field. But then that view should also respond likewise. Your view is directly rendering a template. What would it return if you send it a fraction of the form upon clicking a radio button? – Bibhas Debnath Mar 31 '14 at 09:39
  • Actually it is to get user input for manual or automatic calculation purpose based on the radio btn selected. And, also tried with ajax (edited in my question), but am making a mess somewhere, its not working. – Ria Mar 31 '14 at 11:41
  • You need to break down your problem. It's too broad to be answered here unless you describe clearly what you want to do. You said once that your question is about placing templates, but then at the end your question is how to submit a form in change of a radio button. – Bibhas Debnath Mar 31 '14 at 11:46
  • I tried using Ajax, javascript for onchange(), but it didnt work around. Thought of using templates, so that i could post request to view.py. My problem is to use radio btn click event to enable or disable other input fields in the same form displayed in django admin – Ria Mar 31 '14 at 11:51

2 Answers2

0

Have a look at the answer I gave to another question: How to render django form differently based on what user selects?

It handles the same situation, but instead of chcekboxes it is a dropdown menu. But that ia really irrelevant.

The point is:

The view should define the behavior of your form and not the template nor javascript, which should only be used to modify things that are already "allowed" by the view.

Otherwise a malicious user could make fields visible and edit them without your consent which might lead to wonky results.

But you will be able to get the right behavior because the form will be repopulated with the already given input.

You can use AJAX to get some seamless behavior, but the process will remain the same: SUbmit Form -> Call View -> Return rendered output. The only thing that's different is you will replace the form inline instead of reloading the whole html page.

Community
  • 1
  • 1
Dr.Elch
  • 2,105
  • 2
  • 17
  • 23
0

You want something like this in your template file that renders the form:

<script>
    window.onload = function() {
        // Initial display based on default message_type 1
        document.getElementById("id_title").style['display'] = 'block';
        document.getElementById("id_body").style['display'] = 'block';
        document.getElementById("id_data").style['display'] = 'none';

        // Get the radio input elements
        message_types = document.getElementsByName("message_type");
        message_types.forEach(function(message_type) {
            message_type.addEventListener("change", function() {
                if (message_type.value == 1) {
                    document.getElementById("id_title").style['display'] = 'block';
                    document.getElementById("id_body").style['display'] = 'block';
                    document.getElementById("id_data").style['display'] = 'none';
                } else {
                    document.getElementById("id_title").style['display'] = 'none';
                    document.getElementById("id_body").style['display'] = 'none';
                    document.getElementById("id_data").style['display'] = 'block';              
                }
            });
        });
    }
</script>

Note that Django prefixes the names given in the form definition with "id_" to create the ids for the elements. The form class in this example contains fields named title, body, and data. In your example, it would be id_option and id_otherFields, etc..

Inversus
  • 3,125
  • 4
  • 32
  • 37