I run something similar on my site currently. I however did not wrap my search into a directive because it is it's own page.
For how I have it setup, I have a search page site.com/search
(which would be your landing page for example) That page has its own controller/view SearchController
. On the same page lies a separate container which can essentially list items that are inside an array. Finally, the entire page has an ApplicationController
.
Now, the SearchController
and ApplicationController
are obviously separate and therefore cannot access each-other's properties or methods. What they can do however, is either share a factory/service or broadcast information. For the simplicity of this example we will have them share a service called SearchService
.
If you still wish to use a directive, you can easily turn the SearchController
into a directive and utilize the same concept for yourself.
Basic Plunkr Example Here
SearchService
The SearchService
will contain useful properties and methods for searching, but all you need right now is just a simple Array
to contain a list of search results.
myApp.factory('SearchService', function() {
var SearchService;
SearchService = {};
// The array that will contain search results
SearchService.arrSearchResults = [];
return SearchService;
}
);
ApplicationController
The ApplicationController
scope will have a reference to SearchService
so that you can use ng-repeat
and list out the actual contents of the search results.
myApp.controller('ApplicationController', [
'$scope', 'SearchService', function($scope, SearchService) {
// Create a reference to the SearchService and add it to the
// $scope so it will be available on the page
$scope.searchService = SearchService;
}
]);
SearchController
The SearchController
scope will also have a reference to SearchService
so that it can modify the SearchService.arrSearchResults
array, thus altering what will be displayed on the page. It will also contain methods to interact with the form.
It will also alter the URL location when a search is executed.
myApp.controller('SearchController', ['$scope', 'SearchService', '$http', '$location', function($scope, SearchService, $http, $location) {
// Your search input
$scope.blab = "";
// Your search function
$scope.search = function() {
// Make sure blab has content (always good to double check)
if($scope.blab != "") {
// Alter URL to show new request
$location.search('q', $scope.blab);
// Make a GET request to your URL that will
// return data for you to populate
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
alert("Search results found!");
// Assuming the data returned is a list of items
// or object items
// (i.e. [ "Search Result1", "Search Result2", ... ]
SearchService.arrSearchResults = data;
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert("Something failed! No results found!");
// Empty the array of search results
// to show no results
SearchService.arrSearchResults = [];
});
};
}]);
The Page
<!doctype html>
<head>
<title>Search Example Page</title>
<!-- Insert Angular.JS source files here -->
</head>
<body ng-controller="ApplicationController" ng-app="myApp">
<!-- ngView -->
<div role="main" data-ng-view>
</div>
<!-- Search Results -->
<div ng-repeat="searchItem in searchService.arrSearchResults">
<p style="border-bottom: 2px solid #000">Search Result: <br/>{{searchItem}}</p>
</div>
</body>
</html>
Tabs
For switching the type of search result (web, image, etc) you can create a variable within the SearchService
that controls the state of the search, and thus what type of search to run.
SearchService.typeOfSearch = "web";
This sets the state to web
and thus can be interacted within the page and app.
You can then have various ng-repeat
throughout the page all showing results for different states:
<!-- Search Results - Web -->
<div ng-if="searchService.typeOfSearch='web'" ng-repeat="searchItem in searchService.arrSearchResults">
<p style="border-bottom: 2px solid blue">Search Result: <br/>{{searchItem}}</p>
</div>
<!-- Search Results - Image -->
<div ng-if="searchService.typeOfSearch='image'" ng-repeat="searchItem in searchService.arrSearchResults">
<p style="border-bottom: 2px solid red">Search Result: <br/>{{searchItem}}</p>
</div>
I have updated the Plunkr to demonstrate.