AngularJS boostrap dropdownmenu linked to input field keypress for autocomplete - angularjs

I am a beginner to angulajs. I am trying to write this code that would display google search suggestions for a search field when i am typing in letters of my search text.
This is how I have done this inside the boostrap 3 navbar:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<div class="col-sm-4 col-md-4 pull-right dropdown" ng-controller="SearchCtrl">
<div class="navbar-form input-group">
<input type="text" class="form-control" placeholder="Search" name="q" id="dropdownMenu1" ng-model="text" ng-keyup="suggest()" data-toggle="dropdown">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="result in results">{{result}}</li>
</ul>
</div>
</div>
</div>
</div>
And correspondingly the AngularJS code:
app.controller('SearchCtrl', function ($scope, $http) {
$scope.suggest = function() {
var url = "http://google.com/complete/search?callback=JSON_CALLBACK&output=firefox&q=" + $scope.text;
$http.jsonp(url).success(function(data) {
$scope.results = data[1];
});
};
});
But for some reason the dropdown of suggestion is not showing up.
I monitor in debug console and see that request goes through just fine returning the suggestions, so no javascript error.
Any suggestion if how to make this work as it should (in both, bootstrap and angularjs) is appreciated.
Cheers :))
P.S. In debug I see the dropdown is created and populated just fine when I type "welcome" word:

Related

On clicking Search Button, display result in the next page

I searched for the solution but could not find the exact solution so posted here.
I have a search bar in the header menu. When search content is typed and clicked on search button, the result needs to be display in a new page (eg. result.html). API is used to fetch the searched result.
I have added js pseudo code below which will explain what I intend to do.
Thank you for the suggestion.
navigation
<nav class="navbar navbar-default navbar-fixed-top navbar-search-box animate" role="navigation">
<div class="row">
<div class="collapse navbar-collapse" >
<ul class="nav navbar-nav" id="main-nav">
<li> ... </li>
<li>
<div class="search-bar-search animate">
<div class="container" ng-controller="searchCtrl">
<div class="input-group">
<input type="text" class="form-control" id="q" ng-model="q" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" ng-click="search()">Search</button>
</span>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</nav>
Search.js
var app = angular.module('myApp', ['ngRoute']);
app.service('searchService', function($http) {
this.getResult = function(q) {
// o/p is in JSON format
return $http.get('http://mydomainname/api/search/'+q);
}
});
app.controller('searchCtrl', function ($scope, searchService){
$scope.search = function (){
var q = $scope.q;
searchService.getResult(q).then(function (response){
$scope.result = response.data;
// redirect to new template (result.html) and display result
...
...
});
};
});

I am using ng-click and ng-show for pagination

I am using ng-click and ng-show for pagination. In this case it keeps on creating new pages in both direction when ever buttons are clicked i.e it keeps on creating blank pages. It should stop at first and last page respectively. Here I have created three sub-pages for pagination the buttons should play only for this three sub pages.
Looking forward for any help.
thank you.
<div class="container" ng-app="tabApp">
<div class="row" ng-controller="TabController">
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li>
<a href ng-click="setTab(tab+1)" class="btn btn-primary btn-lg" role="button">Next</a>
</li>
<li>
<a href ng-click="setTab(tab-1)" class="btn btn-primary btn-lg" role="button">Back</a>
</li>
</ul>
</div>
<div class="col-md-8">
<div class="jumbotron">
<div ng-show="isSet(1)">
<h1>Home page</h1>
<p>Welcome to the website!</p>
<p><a class="btn btn-primary btn-lg" role="button">Learn more</a></p>
</div>
<div ng-show="isSet(2)">
<h1>Profile page</h1>
<p>Profile information</p>
</div>
<div ng-show="isSet(3)">
<h1>Messages</h1>
<p> Some messages </p>
</div>
</div>
</div>
</div>
</div>
<script>
angular.module('tabApp', [])
.controller('TabController', ['$scope', function($scope) {
$scope.tab = 1;
$scope.setTab = function(newTab) {
$scope.tab = newTab;
};
$scope.isSet = function(tabNum) {
return $scope.tab === tabNum;
};
}]);
</script>
I have created a codepen

How to access a ngform name from controller?

I need to check if the elements on the current html page (being rendered using ui-view) are dirty or pristine before I navigate to next tab.
Parent page:
<div class="inner-menu">
<nav>
<div>
<ul class="nav nav-tabs edit-menu" role="tablist">
<!-- location 1 -->
<li ng-repeat="innerTab in innerTabListArr" ng-click="switchTab($index, $event)">
<a role="tab" data-toggle="tab" href="">{{innerTab.text}}</a>
</li>
</ul>
</div>
</nav>
<div ui-view="innerTabHolder" name="currForm"></div>
</div>
and the HTML template that will be rendered to innerTabHolder view is :
<div class="edit-general" id="General">
<div class="modal-dialog modal-lg">
<form class="form-horizontal" name="generalForm">
<label for="inputL3" class="control-label">Text</label>
<div class="col-sm-4">
<input type="text" class="form-control" ng-model="gn.myMdl">
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-10">
<!-- location 2 -->
<button class="btn" type="button" ng-click="switchTab(generalForm, $event)"> BCK </button>
<button class="btn" type="button" ng-click="saveGen()">Save Above</button>
<button class="btn" type="button" ng-click="switchTab(generalForm, $event)"> FWD </button>
</div>
</div>
</div>
</form>
</div>
</div>
There are multiple tabs that will get rendered into the view. And this is the controller I have:
myApp.controller('compTabCtrl',[ '$rootScope', '$scope', '$state', 'mainWebService',
function($rootScope, $scope, $state, mainWebService){
$scope.innerTabListArr = [{"text" : "Tab 1"},{"text" : "Tab 2"}];
$scope.switchInnerTab = function(tabId, event){
};
}]);
Ok, so this is basic outline and I believe, I have covered all parts. Now, my issue is I am not able to pass the form : "generalForm" into switchTab function at location 1 where as I can do the same at location 2.
I am using the form's $dirty and $pristine to check if the user has made any changes to the form. So, while clicking on the tab for navigation, the form becomes undefined.
How do I access the $dirty property of sub-view in controller.
Plunker for demo :
https://plnkr.co/edit/06F5JfXltinyxrZbbc14?p=preview
When you are trying to access the variable always use $scope
access curForm using
$scope.curForm.$dirty

Service (factory) error - json api not displaying data

I have spent like a good 4 to 6 hours on trying to solve my issue - maybe I am looking at it completely wrong.
controller.js file:
'use strict';
/* Controllers */
var bookControllers = angular.module('bookControllers', []);
bookControllers.controller('BookListCtrl', ['$scope', 'Book',
function($scope, Book) {
$scope.books = Book.query();
$scope.orderProp = 'name';
}]);
bookControllers.controller('BookDetailCtrl', ['$scope', '$routeParams', 'Book',
function($scope, $routeParams, Book) {
$scope.book = Book.get({bookId: $routeParams.bookId}, function(book) {
$scope.mainImageUrl = book.avatar;
});
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
};
}]);
My service.js file
'use strict';
/* Services */
var bookServices = angular.module('bookServices', ['ngResource']);
bookServices.factory('Book', ['$resource',
function($resource){
return $resource('https://api.myjson.com/bins/1oofv', {}, {
query: {method:'GET', params:{bookId:'bookId'}, isArray:true}
});
}]);
So what is happening.
My SHOW file - which displays all books within my book.json file which I have hosted on myjson displays all the content I need.
It displays all thumbnails accordingly with the following html:
<div class="container">
<!--Nav Bar-->
<div class="row">
<div class="col-md-4">
Find me the best
<select ng-model="orderProp" class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
</div>
<div class="col-md-4">
Books about
<select ng-model="orderProp" class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
<option ng-repeat="book in books" value="">{{ book.genre.name }}</option>
</select>
</div>
<div class="col-md-4">
<div class="input-group">
<input ng-model="query" type="text" class="form-control" placeholder="Search books">
<span class="input-group-btn">
<button class="btn btn-default" type="button"><span class="glyphicon glyphicon-search" ></span></button>
</span>
</div>
</div>
</div>
<!--Body content-->
<div class="row">
<div class="col-md-4" ng-repeat="book in books | filter:query | orderBy:orderProp">
<div class="thumbnail" id="books">
<img ng-src="{{ book.cover }}">
<div class="caption">
<h4>{{ book.name }}</h4>
<h5>{{ book.author.name }}</h5>
<span class="glyphicon glyphicon-heart likes">{{ book.likes }}</span>
<span style="float: right;">{{ book.published | date:'yyyy-MM-dd' }}</span>
</div>
</div>
</div>
</div>
</div>
This is all fine - now when I click a specific book or author I am expecting the app to nav to the next page a detail ALL the details I need in the following template (but it doesn't):
<div class="container">
<div class="row">
<header>
<h1></h1>
<h4></h4>
<p></p>
<h6>Categories:</h6>
<span>{{ book.genre.category }}</span>
</header>
</div>
<div class="row">
<h3>Introduction</h3>
<h1></h1>
<p></p>
<div class="line-sep"></div>
<img ng-src="{{ avatar }}" class="img-round" />
<h2></h2>
</div>
<div class="row">
<h1>Similar reading</h1>
<p></p>
<div class="col-md-4">
<div class="thumbnail" id="books">
<img ng-src="http://placehold.it/350x500">
<div class="caption">
<h4>Lorem Ipsum Dolar Asar</h4>
<h5>By Mr Lorem Ipsum</h5>
<span class="glyphicon glyphicon-heart likes">1032</span>
<span style="float: right;">3 days ago</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail" id="books">
<img ng-src="http://placehold.it/350x500">
<div class="caption">
<h4>Lorem Ipsum Dolar Asar</h4>
<h5>By Mr Lorem Ipsum</h5>
<span class="glyphicon glyphicon-heart likes">1032</span>
<span style="float: right;">3 days ago</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail" id="books">
<img ng-src="http://placehold.it/350x500">
<div class="caption">
<h4>Lorem Ipsum Dolar Asar</h4>
<h5>By Mr Lorem Ipsum</h5>
<span class="glyphicon glyphicon-heart likes">1032</span>
<span style="float: right;">3 days ago</span>
</div>
</div>
</div>
</div>
</div>
Look at my josn file on the site: https://api.myjson.com/bins/1oofv
All I need to do is the following:
Use the json file to display the books (with some details) on the list page - in whatever display style I feel is appropriate.
Then - once all the books are displayed (with search and filter abilities) - be able to click on a book and be taken to a BOOK DETAIL page where we will delve into more detail about the book and show books that are similar to them.
stop stressing, and follow the Flatlander Gemstore tutorial.
First problem I could spot is, you use Book.get but defined Book.query
Secondly, using href="#" breaks angular, either use an <a href="">or, as I prefer, simply use a button, a hyperlink that goes nowhere isn't a link.
as yeouuu said, href="{{ book.id }}" seems wrong, this is either a semantical error and should be href="{{ book.url }}" or this is simply an error and should have been something else entirely.
Do the tutorial, it is a great resource.

Using ng-click inside np-repeat

I'm trying to implement a shortlisting functionality in a case where I'm using ng-click inside ng-repeat.
While the $index is being displayed correctly outside the ng-click, $index is only the index of the last object in the JSON array in all the cases where the html is generated using ng-repeat.
I was expecting the respective venue or venue.id to be passed as an argument to shortlistThis(). I'm guessing that this could be an issue related to event binding.
Can someone help me understand what's going wrong here and probably a better way to do this if possible.
I did try checking this Bind ng-model name and ng-click inside ng-repeat in angularjs The fiddle here works just fine but, mine doesn't.
Update: I've found something interesting here. When the shortlist button is placed just under the ng-repeat, it work just as intended. But when, nested inside a div with a ng-class, it isn't working as intended. Can anyone explain and suggest a fix for this ?
//locationsapp.js var locationsApp = angular.module('locationsApp', []);
var venues = [{
id: "Flknm",
name: "ship",
}, {
id: "lelp",
name: "boat",
}, {
id: "myp",
name: "yacht",
}, ];
var shortlistedVenues = [];
var locationsApp = angular.module('locationsApp', ['ui.bootstrap']);
locationsApp.controller("getvenues", function($scope) {
$scope.venues = venues;
$scope.shortlistThis = function(venue) {
console.log(venue);
if (shortlistedVenues.indexOf(venue) == -1) {
shortlistedVenues.push(venue);
//alert('If');
} else {
console.log('already shortlisted')
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="locations" ng-app="locationsApp">
<div ng-controller="getvenues">
<div ng-repeat="venue in venues" ng-mouseover="" class="venue">
<div ng-controller="manageInfo">
<div class="row-fluid">
<div class="control" ng-click="showInfo()">
</div>
<div class="maps" class="info">
<div ng-class="class">
<div class="close-info" ng-click="hideInfo()">
<i class="fa fa-times">
</i>
</div>
<div class="row full-venue-contents" ng-app="ui.bootstrap.demo">
<div class="">
<div class="row-fluid myclass">
<div class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup" ng-click="shortlistThis(venue)">
Shortlist{{$index}}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- End of Full Info Container -->
</div>
</div>
</div>
</div>
<div class="compare">
<button type="button" class="btn btn-default btn-lg btn-sup">
Compare ( {{shortlistedVenues.length}} )
</button>
</div>
</div>
</div>
</div>
</div>
The problem is with your button div which was position: fixed, it is actually showing the 1st button but clicking on it firing last button click, I'd suggest you should suggest you render only the shortlist button which has been selected by you. For that you can use ng-if and render those button which index is the same as that of selected $index
HTML
<div ng-if="selected==$index" class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup"
ng-click="shortlistThis($parent.$index)">Shortlist{{$index}}</button>
</div>
</div>
</div>
& then put ng-click="selected='$index'" on ng-repeat div like
<div ng-repeat="venue in venues" class="venue" ng-click="selected=$index">
Working Fiddle
Hope this could help you, Thanks.

Resources