0

I'm trying to implement a search bar to query my database and show only the matches. When I hit submit it just gives me back 'SEARCH', which is what I set as the default instead of printing an error.

ajax.py

...
def chunkSearcher(request):
test = request.GET.get('search_box', "SEARCH")
print(test)
....

Searcher.html

<form type="get" action="." style="margin: 0">
<input  id="search_box" type="text" name="search_box"  value="Search..." >
<button id="search_submit" type="submit" >Submit</button>

urls.py

 url(r'^ajax/chunk/Searcher/$',
    ajax.chunkSearcher, name='chunkSearcher')

views.py (It actually works here for some reason but it won't recognize the same two lines of code in my ajax code

def searcher(request):
# test = request.GET.get('search_box', "SEARCH")
# print(test)
this_main = Searcher(
    request          = request,
    num_elements     = Candidate.objects.all().count(),
    size             = 'col-xs-12',
    title            = 'Search',
    modelname        = 'Searcher',
    listing_fields   = [
        {'readable_name': 'Name',   'model_attribute': 'full_name()', 'subtext_model': 'email', 'color': 'False'},
        {'readable_name': 'Status', 'model_attribute': 'get_status_display()', 'color': 'True'},
        {'readable_name': 'Automated Status', 'model_attribute': 'get_auto_status()', 'color': 'True'},
        {'readable_name': 'Submitter', 'model_attribute': 'submitter', 'color': 'True'},
    ],
    listing_actions  = [
        {'tooltip': 'Search',  'color': 'success', 'icon': 'plus', 'permission': 'prog_port.add_candidate', 'modal': 'candidateform', 'controller': 'addCandidate'},
    ],
)

context = {
    'nav'    : Nav(request),
    'main'   : this_main,
    'fb'     : TestFeedback()
}
return render(request, 'prog_port/base.html', context)

widgets.py

class Searcher:
def __init__(self, request,
                   num_elements,
                   size                         = 'col-xs-12',
                   modelname                    = None,
                   title                        = None,
                   listing_fields               = None,
                   listing_actions              = None):#!!

    self.template = 'prog_port/widgets/Searcher.html'
    self.size = size
    self.modelname = modelname
    self.num_elements = num_elements
    self.num_pages = int(math.ceil( num_elements / 25.0))
    self.title = title
    self.listing_fields  = [x['readable_name'] for x in listing_fields]
    self.listing_actions = listing_actions

    for action in self.listing_actions:
        action['restricted'] = False
        if 'permission' in action:
            if not request.user.has_perm(action['permission']):
                action['restricted'] = True
Mike A.
  • 175
  • 3
  • 16
  • What happens if you change the `action` attribute of your form to point at the URL of your ajax view? – souldeux Aug 08 '16 at 18:50
  • @souldeux When I change the action to `action="/ajax/chunk/Searcher"` the text that I entered in the box actually spits out into my terminal but the page doesn't load. **Before** `SEARCH [08/Aug/2016 13:18:54] "GET /ajax/chunk/Searcher/?page=1&orderby=0%3Basc HTTP/1.1" 200 4467` **After** `[08/Aug/2016 14:12:30] "GET /ajax/chunk/Searcher/?page=1&orderby=0%3Basc HTTP/1.1" 200 4243 [08/Aug/2016 14:12:37] "GET /ajax/chunk/Searcher?search_box=Test+Search HTTP/1.1" 301 0 Test Search [08/Aug/2016 14:12:37] "GET /ajax/chunk/Searcher/?search_box=Test+Search HTTP/1.1" 200 4240` – Mike A. Aug 08 '16 at 19:15

1 Answers1

0

Getting this working without Ajax would be a bit quicker to start. When the action attribute of your form is pointed towards the URL of the current page (rather than towards the URL of your ajax view), the GET request is sent to the view that corresponds to that page's URL - your searcher view in your case. That's why you were able to get the expected values to print when you had those two lines in that view.

Importantly, since the searcher view is the one rendering your page, having access to your search_box value in that view lets you filter or otherwise manipulate the queryset being passed into the view's context and ultimately display only the restricted/filtered items you want shown.

A separate Ajax view doesn't have access to all of that stuff right off of the bat. To dynamically update your search results with a separate Ajax view, that view will need to respond to your request with all of the information necessary to re-render the page appropriately. Practically speaking, that usually means one of two things:

  1. Your search results are displayed within a div or other defined content area, and your Ajax view returns the HTML necessary to populate that content area with the appropriate stuff, or

  2. Your initial view renders its template based on some serialized JSON, and your Ajax view provides updated information in that format which is then used to re-render the template.

This is a good starting point for getting the hang of ajax with django. Notice in the example code given how the view responds to the ajax call with some data (a HTTPResponse or a rendered template), and how that data is then used in the success/failure functions.

If your ajax view returned the HTML necessary to render search results, you could use your success function to update the search results div (or table or whatever) on your page with that new HTML. For example:

views.py

def index(request):
    return render(request, "index.html")

def ajax_update(request):
    return HttpResponse("<h1>Updated Header</h1>")

index.html

...
<div id="update_this_header">
    <h1>Old header</h1>
</div>
<button id='updater'>
...
<script>
$("#updater").click(function() {
    $.ajax({
        url: #url to ajax_update view
        success : function(data) {
            $("#update_this_header").html(data)
        },
        failure : function(data) {
           ...
        }
    });
});
</script>

Now clicking the updater button should update the contents of the update_this_header div with the HTML returned in the HttpResponse from our ajax_update view (I admit I didn't test this, forgive me if there's a typo). Updating your search results works the same way; you just need to do more processing in your ajax view to respond with the correct HTML.

I hope this helps make things somewhat clearer; please let me know if I can (try to) explain anything more fully. The important takeaway here is that an ajax view will provide you with Some Data. It's up to you to make sure your template can take that data and properly display it.

Community
  • 1
  • 1
souldeux
  • 3,615
  • 3
  • 23
  • 35