Ajax search predictor in Angularjs

Dynamic question predictor in AngularJs

Objective

We are using Flask framework for our dynamic question predictor when the user starts typing question in html text field, we have to kick one ajax event to fetch the relevant responses to be displayed.

So, our initial setup is on creating a webservice in Flask.In your views.py you have to create a webservice like the below one.

views.py in Flask application

@app.route('/s/', methods=('GET',))
def search_query():
    qs = request.args.get('query',None)  
    print "Args",qs
    return jsonify({'data':range(5)})

so, if you visit the url \s\?query=example you should get the json response

json response in browser

{'data':
       [0,1,2,3,4],
}

It is Reponse which is emitted from search_query view function. Here we know how to create a simple webservice in Python Flask.

Now, these webservice kicking process has to be started from angular side. Find some knowledge about AngularJs if you would like to have before proceeding.

$scope is the angular environment which contains all objects and it’s properties inside this $scope

function Search($scope, $http) {

       $scope.doAutoSearch = function() {

           if($scope.query)
               $http.get("/s/?query=" + escape($scope.query = $scope.query.toLowerCase())).then(function(r) {

                        alert(r.data.data+typeof r);

            }

        }

This Search function does visit the url(http://localhost:5001/s/?query=python) and the response will be alerted.

Here directly, I started defining the angularjs function without explaining about ng-app, ng-model, ng-controller, ng-change, ng-repeat.

<div ng-app="myApp">
    <input ng-change="doAutoSearch()" ng-model="query" autocomplete="off" placeholder="eg: Why do I need a Khatha?" type="text" value="">

</div>

This is my angularjs template.

query is the name that binds the user input text field value into angular scope attribute named query. So, if you type any text in the input field.

when you run this current setup,you should get the result in javascript alert box, otherwise, you are making some fundamental issue in either pythonnic side or javascript side.

After, you got the result in alert box,

Polishing the methodology

We shall polish this process further.

Angular template area:

<div ng-app="myApp">

         <div class="control-group{% if form.errors.title %} error{% endif %}" ng-controller="Search">
                <label class="control-label" for="title">Title: *</label>

                <input class="form-control" id="title" name="title" ng-change="doAutoSearch()" ng-model="query" autocomplete="off" placeholder="eg: Why do I need a Khatha?" size="50" type="text" value="">
                <li ng-repeat="result in results" style="list-style-type: none;">
                   {#% raw %#}
                   <p ng-bind-html-unsafe="result"></p>

                    {#% endraw %#}
                </li>

                {% for error in form.errors.title %}
                    <span class="help-inline">[{{error}}]</span><br>
                {% endfor %}

        </div>

        </div>

Modified template by adding the ng-bind-html-unsafe(to render the html tags in result) for appending the results to be displayed as list(li tag).
we are using one more directive ng-repeat.

Angularjs function:

function Search($scope, $http) {

            $scope.doAutoSearch = function() {
                if($scope.query)
                    $http.get("/s/?query=" + escape($scope.query = $scope.query.toLowerCase())).then(function(r) {

                        $scope.results = []
                        for(i=0;i<r.data.data.length;i++){
                            link = "<a href='/faq#"+r.data.ids[i]+"'>"+r.data.data[i]+"</a>";
                            $scope.results.push(link.replace(RegExp($scope.query, 'gi'), '<b>$&</b>'));
                        }
                    });
                else
                    $scope.results = [];
            }

        }; //function ends;

This is my polished working search function which does some href linking operation after it fetched results from ajax event.

One additional think i have done here if you scrutinize well.Since, I am using jinja2 template engine, I should change angularjs interpolation symbols to avoid the conflict between jinja2({{, }}) interpolation and angular interpolation

This following snippet does what we need.

Avoid interpolation conflict with jinja2:

angular.module('myApp', [], function ($interpolateProvider) {
            $interpolateProvider.startSymbol('{[');
            $interpolateProvider.endSymbol(']}');

        });

In views.py make sure you change the logic to return the list in proper order by querying from the database you are using.

return jsonify({'data':[str(i.question)for i in faqs], 'ids':[str(i.id)for i in faqs]})

All are set.Just the flow.

Result

I got this output.

angular js search predictor

Thanks

If you have any feedback on narration, technical thoughts, please do share me and help me to improve. my humble thanks
Advertisements

About Navaneethan

mixed feelings...
This entry was posted in angularjs, Flask, Python, Ubuntu and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s