0

I have an <input> box that acts as a search bar:

<input type="text" class="form-control input-lg" placeholder="Filter" ng-init="initSearch()" ng-model="search" ng-change="updateSearch()" id="search_bar"> 

and has the following accompanying angular code:

$scope.initSearch = function(){
  var searchParam = parseQueryString()["searchParam"];
  console.log(searchParam);

  if (searchParam !== undefined){
    var element = angular.element(document.querySelector('#search_bar'))[0];
    console.log(element);
    element.value = searchParam;
  }
};

$scope.updateSearch = function(){
   $location.search('searchParam',document.getElementById('search_bar').value);
};

The user has to be able to enter an URL with the searchParam already set and the page has to load the appropriate data. Once I change the value of the input box how would I get it to actually reflect that input in the data it displays? It only seems to update when the search parameter is entered into it manually. I've also tried changing the value without jQLite and just used document.getElementById etc

2 Answers2

0

rather than look at the dom, why don't you use the actual model for your function like so:

<input 
 type="text" 
 class="form-control input-lg" 
 placeholder="Filter" 
 ng-init="initSearch(search)" 
 ng-model="search" 
 ng-change="updateSearch(search)" 
 id="search_bar">

Edit:

Expanding on my initial answer, you read the Angular $location params when the page loads. I think you were a little confused about ng-init; this directive just gives you a handy place to bind some data or run some function -- it doesn't specifically affect the model on this element. So just read the location in your controller and bind it to your model, and also have the model bind those changes to the location like so:

<div ng-controller="SearchCtrl as vm">
  <input type="text" 
     class="form-control input-lg" 
     placeholder="Filter"
     ng-model="vm.search" 
     ng-change="updateSearch(search)" 
     id="search_bar">
</div>

js:

var app = angular.module('myApp', []);

app.controller('SearchCtrl', function($location) {
  vm.search = $location.search().searchParam;
  vm.updateSearch = function() {
    $location.search('searchParam', vm.search);
  };

});
wesww
  • 2,863
  • 18
  • 16
  • your functions could accept just the input like `$scope.updateSearch = function(query){`, `$scope.initSearch = function(query){` – wesww Aug 13 '15 at 18:20
  • also check out some posts on how to get off jquery dom manipulation and think in terms of separation of concerns http://stackoverflow.com/a/15012542/1078450 – wesww Aug 13 '15 at 18:23
  • thanks, that helped to clean up my code but it still doesn't cause the input box to search from ng-init, @wesww – Evan Bennewies Aug 13 '15 at 18:42
  • not sure I understand that comment, but I can update the answer to be expanded to include how to keep the url in sync – wesww Aug 13 '15 at 21:11
  • expanded the answer. Hope that makes sense now! – wesww Aug 13 '15 at 21:18
0

I ended up solving this by creating a custom directive that used ngModel directly alongside $setViewValue. Here is my directive.

app.directive('initSearch', function(){
  return {
     require: "?ngModel",

     link: function(scope, element, attrs, ngModel){
       var parseQueryString = function(){
         var str = window.location.search;
         var objURL = {};

         str.replace(
         new RegExp("([^?=&]+)(=([^&]*))?", "g" ),
         function($0,$1,$2,$3){
           objURL[$1] = $3;
         }
         );
       return objURL;
      };
      var searchParam = parseQueryString()["searchParam"];
      var searchBar = document.getElementById("searcher");

      if(searchParam!==undefined && searchBar.value ===''){
        ngModel.$setViewValue(searchParam);
        searchBar.value = searchParam;
      }

      scope.onChange = function(){
        ngModel.$setViewValue(scope.value);
      }
    }
  };
});