0

My Scenario: My MVC controller is returning JSON data which is array of string

I tried all the possible solutions like twitter bootstrap typeahed for angular but nothing worked. I read documentation but it also dint work for me. Can anybody explain how to implement autocomplete step by step? I have implemented it using jQuery but I dont want to use jQuery as Angular doesnt know the DOM updates by jQuery.

2
  • 1
    You have some working examples right there in the documentation: angular-ui.github.io/bootstrap/#/typeahead Commented Dec 29, 2015 at 10:36
  • I tried that but it dint work too what I did was, I was successfully able to achieve it using Angular Material. Commented Dec 30, 2015 at 3:11

2 Answers 2

0

Finally I used Angular Material for the autocomplete and it works like a charm. Here are the steps to create autocomplete in Angularjs and MVC4

Step 1: Angular material has a dependency on
angular-animate.js
angular-aria.js
angular-messages.js

register these js files in your bundle config:

bundles.Add(new ScriptBundle("~/bundles/angularanimatejs").Include("~/Scripts/angular-animate.js"));
bundles.Add(new ScriptBundle("~/bundles/angularariajs").Include("~/Scripts/angular-aria.js"));
bundles.Add(new ScriptBundle("~/bundles/angularmessagesjs").Include("~/Scripts/angular-messages.js"));

Register two css files as well: bundles.Add(new StyleBundle("~/Content/angularmaterialcss").Include("~/Content/angular-material.css")); bundles.Add(new StyleBundle("~/Content/angularmateriallayoutcss").Include("~/Content/angular-material-layout.css"));

Now include these files in shared or your page:

@Styles.Render("~/Content/angularmaterialcss")
@Styles.Render("~/Content/angularmateriallayoutcss")
@Scripts.Render("~/bundles/cdnangularjs")
@Scripts.Render("~/bundles/cdnangularresourcejs")
@Scripts.Render("~/bundles/angularanimatejs")
@Scripts.Render("~/bundles/angularariajs")
@Scripts.Render("~/bundles/angularmessagesjs")
@Scripts.Render("~/bundles/angularmaterialjs")
@Scripts.Render("~/bundles/appjs")

Now in your cshtml page add html code:

<div class="autocompletedemoBasicUsage" ng-controller="DemoCtrl as ctrl" layout="column" ng-cloak="">
<md-content class="md-padding">
    <form ng-submit="$event.preventDefault()">
        <p>Use <code>md-autocomplete</code> to search for matches from local or remote data sources.</p>
        <md-autocomplete ng-disabled="ctrl.isDisabled" md-no-cache="ctrl.noCache" md-selected-item="ctrl.selectedItem" md-search-text-change="ctrl.searchTextChange(ctrl.searchText)" md-search-text="ctrl.searchText" md-selected-item-change="ctrl.selectedItemChange(item)" md-items="item in ctrl.querySearch(ctrl.searchText)" md-item-text="item.display" md-min-length="0" placeholder="What is your favorite US state?">
            <md-item-template>
                <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.display}}</span>
            </md-item-template>
            <md-not-found>
                No states matching "{{ctrl.searchText}}" were found.
                <a ng-click="ctrl.newState(ctrl.searchText)">Create a new one!</a>
            </md-not-found>
        </md-autocomplete>
        <br>
        <md-checkbox ng-model="ctrl.simulateQuery">Simulate query for results?</md-checkbox>
        <md-checkbox ng-model="ctrl.noCache">Disable caching of queries?</md-checkbox>
        <md-checkbox ng-model="ctrl.isDisabled">Disable the input?</md-checkbox>

        <p>By default, <code>md-autocomplete</code> will cache results when performing a query.  After the initial call is performed, it will use the cached results to eliminate unnecessary server requests or lookup logic. This can be disabled above.</p>
    </form>
</md-content>

write below code into your app.js file:

(function ()
{
'use strict';
angular
.module('StockMarketApp', ['ngMaterial', 'ngMessages'])
.controller('DemoCtrl', DemoCtrl);

function DemoCtrl($timeout, $q, $log)
{
    var self = this;

    self.simulateQuery = false;
    self.isDisabled = false;
    // list of `state` value/display objects
    self.states = loadAll();
    self.querySearch = querySearch;
    self.selectedItemChange = selectedItemChange;
    self.searchTextChange = searchTextChange;

    self.newState = newState;

    function querySearch(query)
    {
        var results = query ? self.states.filter(createFilterFor(query)) : self.states,
        deferred;
        if (self.simulateQuery)
        {
            deferred = $q.defer();
            $timeout(function ()
            {
                deferred.resolve(results);
            }, Math.random() * 1000, false);
            return deferred.promise;
        } else
        {
            return results;
        }
    }

    function searchTextChange(text)
    {
        $log.info('Text changed to ' + text);
    }

    function selectedItemChange(item)
    {
        $log.info('Item changed to ' + JSON.stringify(item));
    }

    function loadAll()
    {
        var allStates = 'Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware,\
            Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana,\
            Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana,\
            Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina,\
            North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,\
            South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia,\
            Wisconsin, Wyoming';

        return allStates.split(/, +/g).map(function (state)
        {
            return 
            {
                value: state.toLowerCase(),
                display: state
            };
        });
    }

    function createFilterFor(query) 
    {
        var lowercaseQuery = angular.lowercase(query);
        return function filterFn(state) 
        {
            return (state.value.indexOf(lowercaseQuery) === 0);
        };
    }
}
})();

Angularjs Material Autocomplete demo's-Angular Material Autocomplete

Once you have a demo running autocomplete file then modify it according to your need.

For bootstrap type ahead another link-bootstrap typeahed

Sign up to request clarification or add additional context in comments.

Comments

0

Finally I was able to develop angular autocomplete text box using bootstrap typeahead.

To develop angular bootstrap typeahead with your service returning JSON data below are the steps: You need to register:
jquery.js
bootstrap.js
angular.js

And to use bootstrap you need to add angular bootstrap dependency javascript file:
ui-bootstrap-tpls-0.14.3.js

In your bundle config register below files:

        bundles.Add(new ScriptBundle("~/bundles/cdnjquery").Include("~/Scripts/jquery2.1.4.js"));
        bundles.Add(new ScriptBundle("~/bundles/cdnbootstrapjs").Include("~/Scripts/bootstrap.min.js"));
        bundles.Add(new ScriptBundle("~/bundles/cdnangularjs").Include("~/Scripts/angular1.4.5.js"));
        bundles.Add(new ScriptBundle("~/bundles/cdnangularresourcejs").Include("~/Scripts/angular-resource.js"));
        bundles.Add(new ScriptBundle("~/bundles/appjs").Include("~/Scripts/app.js"));

        bundles.Add(new ScriptBundle("~/bundles/angularbootstrapjs").Include("~/Scripts/ui-bootstrap-tpls-0.14.3.js"));
        bundles.Add(new StyleBundle("~/Content/bootstrapcss").Include("~/Content/bootstrap.css"));

In your cshtml file add below code:

Render scripts and css in your shared or respective .cshml file:

@Styles.Render("~/Content/bootstrapcss")
@Scripts.Render("~/bundles/cdnjquery")
@Scripts.Render("~/bundles/cdnbootstrapjs")
@Scripts.Render("~/bundles/cdnangularjs")
@Scripts.Render("~/bundles/angularbootstrapjs")
@Scripts.Render("~/bundles/appjs")

Write below code in your respective cshtml file:

<h4>Get Quote</h4>
<pre>Model: {{selected | json}}</pre>
<input type="text" ng-model="selected" uib-typeahead="stock.NAME_OF_COMPANY for stock in stocks | filter:$viewValue | limitTo:8" class="form-control">

Now write below code in your app.js file:

var StockMarketApp = angular.module("StockMarketApp", ["ngResource", "ui.bootstrap"]);

StockMarketApp.controller('StockController', function ($scope, $http) {
  $scope.stocks = undefined;

   $scope.fnGetQuoteDataForAutoComplete = function () {
    //$scope.getQuote = 'dhfl';
    $http.get("/EquityList/GetStockNamesForAutoComplete")
            .success(function (data, status, headers, config) {
                $scope.stocks = angular.fromJson(data)
            })
        .error(function (data, status, headers, config) {
        });
  };
});

My JSON data contains:
data.SYMBOL
data.NAME_OF_COMPANY

I want to display data.NAME_OF_COMPANY, so if you check in chtml code, I have written:
uib-typeahead="stock.NAME_OF_COMPANY for stock in stocks.

In this way you can create a typeahead using angularjs and bootstrap.

Hope this helps someone who is stumbled upon this like me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.