AJAX call to populate Select Widget - Python Django

3.3k Views Asked by At

I'm trying to get an ajax call (in django) to populate a select box on my web page based on the selected item of another. i'm new to python, django and jquery/javascript so I'm not too suprised it's not working.

I have the following form.py

class InputParametersForm(forms.ModelForm):

sqlConnection = SQLSeverConnection('MSSQLServerDataSource')
tableNames = {}
sqlQuery = sqlConnection.getTableNames()

tableNames = tuple((table, table) for table, in sqlQuery)
tableNames = tuple((str(table), str(table)) for table, in sqlQuery)
tableNames = tuple((table.encode(), table.encode()) for table, in sqlQuery)

TableName = forms.ChoiceField(widget=forms.Select(),
                              choices=tableNames)

ColumnName = forms.ChoiceField(widget=forms.Select())

StartDateTime = forms.DateField(widget=SelectDateWidget())

EndDateTime = forms.DateField(widget=SelectDateWidget())

class Meta:
    model = SelectionHistory
    fields = ("TableName", "ColumnName", "StartDateTime", "EndDateTime")

And view;

def InputParametersView(request):

context = RequestContext(request)
connection = SQLSeverConnection('MSSQLServerDataSource')

if request.method == 'POST':

    pdb.set_trace()

    if form.is_valid():
        form.save(commit=True)

        ChartData.objects().all().delete()
        this_XData = connection.getColumnData('DateTimeStamp', SelectionHistory.TableName[0], SelectionHistory.StartDateTime[0], SelectionHistory.EndDateTime[0])
        this_YData = connection.getColumnData(SelectionHistory.ColumnName[0], SelectionHistory.TableName[0], SelectionHistory.StartDateTime[0], SelectionHistory.EndDateTime[0])
        ChartData.XData = this_XData
        ChartData.YData = this_YData

        ChartData.save()

elif request.method == 'GET':

    pdb.set_trace()

    if request.is_ajax():

        pdb.set_trace()

        selected_table = request.GET['selected_table']
        columns = connection.getColumnTitles(selected_table)

        column_names = {}
        column_names = tuple((column, column) for column, in columns)
        column_names = tuple((str(column), str(column)) for column, in columns)
        column_names = tuple((column.encode(), column.encode()) for column, in columns)

        return HttpResponse(column_names)

    return render_to_response('input_parameters-ajax.html', {'form': InputParametersForm},  context)

And the following template - containing the script;

<html>

    {% load staticfiles %}

    <title>Input Parameters</title>

    <script src="{% static 'dgconnection/js/jquery-2.1.0.min.js' %}"></script>
    <script src="{% static 'dgconnection/bootstrap/js/bootstrap.min.js' %}"></script>

    <script>

        $("#id_TableName").change(function()
        {
            tableSelectionChanged();
        })

        function tableSelectionChanged()
        {
            var selected_table = $("#id_TableName").selectedIndex;
            $.get('/historicaldata/input_parameters/', {selected_table : selected_table}, function(column_names){
            $("#id_ColumnName').val(column_names);
            });
        }

    </script>

<body>
    <h1>What would you like to see?</h1>

    <form id="input_parameters" method="post" action="http://127.0.0.1:8000/historicaldata/chart_view/">
        {% csrf_token %}
        <ul>
            {{form.as_ul}}
        </ul>

        <input type="submit" value="submit" />
    </form>

</body>

I get the following web page with nothing populating the lower select box after changing the top one;

nothing in columnname select..

1

There are 1 best solutions below

0
On

I dont think you are structuring your ajax correctly. First of all I would use jquery, and put the ajax in a block. Here is an example of where I did the same thing you are doing.

http://munitag.herokuapp.com/

so when someone selects a bus stop it adds the options for the stops for that particular bus stop.

HTML

        <form role="form">
         <div class="form-group">
            <select id = "stop"class="form-control input-lg">
        <option>Please select a route</option>
                {% for x in stops %}
                <option >{{x}}</option>
                {% endfor %}

            </select>
              <select style="";"id ="stoplist" class="form-control input-lg"> </select>
          <select style="display:none;"id ="direction" class="form-control input-lg"> 
          <option>Inbound</option>
          <option>Outbound</option>
          </select>

     <button type="button" id = "tagbutton"  style="display:none;"onclick= "myFunction()"  class="btn btn-info navbar-btn">Tag</button>
      </div>
        </form>\

Then for ajax

{% block postscript %}

<script type="text/javascript">

 $(document).ready(function() {
  $("#stop").change(function(){
    document.getElementById("stoplist").style.display ="block";
    document.getElementById("tagbutton").style.display ="block";
    document.getElementById("direction").style.display ="block";

      $.ajax({
          type: 'POST',
          data:  {keyname:$('#stop option:selected').val()},
           success: function(resp){
            for (var i=0; i < resp['routestops'].length;++i){

              addOption(document.getElementById("stoplist"), resp['routestops'][i], resp['routestops'][i]);
            }

             }

      });
  });
}); 

 </script>

{% endblock postscript %}

The jquery is processing the successful post response, which is a list of stops, and is using the AddOption function to add these options to the select element.

here is the view to process the ajax when someone selects an option and changes the target element

if request.is_ajax():


    stop = request.POST.values()[0]

    routestops = stops[stop]['stops']
    r = {'routestops':routestops}


    return HttpResponse(json.dumps(r), mimetype="application/json")
else:

    return render(request, 'muni/home.html', payload)