milan
milan

Reputation: 2417

How could i display search result based on filtered value provided by user?

I have developed filter system where it provides 3 options such as property type, number of rooms, and maximum price. Every time they select filter options the user will get their search result instantly. For example, if a user has selected property type of Apartment and number of rooms as 4 and maximum price of 12000 then the user will get those rents whose property type is apartment with 4 rooms of 12000 mark. I developed the front-end part with React.js and could fetch user selected data successfully. I have also passed data to ajax but I have no idea how should I display the search results based on filtered value provided by user with no page loading.

Ajax code

$.ajax({
  type: 'GET',
  url: '/filter/space/',
  data{property:propertySelectedValue, room:roomSelectedValue, price:maxPrice},
  success: function(data){
    console.log(data['fields']);
  },
  error: function(XMLHttpRequest, textStatus, errorThrown){
    console.error("Status: " + textStatus); alert("Error: " + errorThrown);
  },
});

Views.py

class FilterSpace(View):
    def get(self,request,*args,**kwargs):
        property = request.GET.get('property',None)
        room = request.GET.get('room', None)
        price = request.GET.get('price', None)
        rental = Rental.objects.all()
        if room:
            rental = rental.filter(room=room)
            print('rental',rental)
        if price:
            rental = rental.filter(price__lte=price)
        if property:
            rental = rental.filter(property=property)
        rental_json =  serializers.serialize('json',rental)
        print('rental_json',rental_json)
        return HttpResponse(rental_json,content_type="application/json")

Upvotes: 10

Views: 687

Answers (4)

Adam S.
Adam S.

Reputation: 306

In my opinion, its clearer to have the logic and rendering taking place in django using AJAX to retrieve and place the rendered html. Here is a sketch of the code

Here is the view that passes the set of rentals to an html template

def ajax_rental_search(request):
    search_text = 'missing'

    if request.method == "GET":
        search_text = request.GET.get("search_text", "missing")

    # DEBUG: THIS CAN CHECK THE CONNECTION
    # return HttpResponse('SERVER RESPONSE: search_text: ' + search_text)

    if search_text != 'missing':
        rentals = Rental.objects # add filters etc. 

    context = {
        "rentals": rentals
    }

    return render(request, "rentals_search_response.html", context)

Here is the key part, the jquery, ajax request:

    function rentalSearch() {
        const search_text = content_search_input');

        $.ajax({
            type: "GET",
            url: < rental_search_url >,
            data: {
                'search_text': search_text,
            },
            success: function (serverResponse_data) {
                // console.log('search success: ' + serverResponse_data);
                $('#rentals_content').html(serverResponse_data);  
                // rentals_content is an existing div on page
            },
            error: function (serverResponse_data) {
                console.log('error:' + serverResponse_data)
            }
        });
    }

Then you can style the displayed rentals as you wish knowing that they are all going to passed to the sub template. Thats it

Upvotes: 0

Vedran
Vedran

Reputation: 1150

You can clear up your view by doing something like this:

class MyView(View):
    def get(self, request):
        results = Rental.objects.filter(**request.GET)
        return serializers.serialize('json', results)

and when you get the data back in your AJAX request, in the success part just clear your table and iterate over the results and append rows to the now empty table with your data.

Upvotes: 0

Ian Kirkpatrick
Ian Kirkpatrick

Reputation: 1960

One thing you might consider doing is rendering the html to a string (django - render_to_string not working) on the server side and send that back in an ajax response along with the data. then replace the html where the list is contained with that rendered by the server.

Django:

def get_list(request, *args, **kwargs):
    items = Items.objects.filter(...)
    html = ""
    items = [] # actual data
    context = {
        "item_list": items,
        ...
    }

    for item in items:
        html = html + render_to_string(list_html_template, context, context_instance=RequestContext(request))
        items.append(item.to_json()) # You have to define this if you want it.

    return JsonResponse({
        "list_html": html,
        "items_data": itmes
    })

Template (list_html_template):

{% for item in item_list %}
<!-- render item here... -->
{% endfor %}

Javascript:

$.ajax({
    url: "url_for_get_list_view",
    dataType: "json",
    ...
    success: function(json) {
        $(list_container).html(json.list_html); // Will replace any current html in this container (i.e. refresh the list).
        /* You can also do stuff with json.items_data if you want. */
    }
});

Upvotes: 1

Marco Munari
Marco Munari

Reputation: 142

for efficiency in the python you should find the way to filter once with all the parameters instead of filter the filtered of the filtered, but this is not essential to see result.

inside success: function(data){ you should use jQuery to put data into the page, you might start with something like

function data2html(data) {
   ...// use .map and .join
}
$("#divid").append(data2html(data))

Upvotes: 0

Related Questions