AngularJS : interactive search - javascript

I'm new to AngularJS, and, for a project, I need to make an interactive search engine.
So I did this for now :
article/views/articles.html
<form class="form-inline">
<div class="form-group">
<label for="filter-text">Text </label>
<input type="search" class="form-control" id="filter-text" placeholder="Search for text" ng-change="applyFilter();" ng-model="filters.text">
</div>
<div class="form-group">
<label for="filter-date-start">Entre </label>
<input type="date" class="form-control" id="filter-date-start" placeholder="Entre" ng-change="applyFilter();" ng-model="filters.date_start">
</div>
<div class="form-group">
<label for="filter-date-end">Et </label>
<input type="date" class="form-control" id="filter-date-end" placeholder="Et" ng-change="applyFilter();" ng-model="filters.date_end">
</div>
</form>
<div class="hidden-sm hidden-xs col-md-6">
<div
ng-repeat="article in articles"
class="article"
ng-include="'article/views/article.html'" >
</div>
</div>
article/views/article.html
<div ng-hide="article.isHidden">
<!-- My Article DOM -->
</div>
article/article.js
angular
.factory('articleRetriever', function ($http, $q){
this.getLast = function( id ){
var url = 'http://localhost:8080/articles/';
if (id) url += id;
return $http.get(url ,{'Access-Control-Allow-Origin': 'localhost:*'})
.then(function(response) {
var articles = [];
for (var idx in response.data.data) {
var article = response.data.data[idx];
article.isHidden = false;
articles.push(article);
}
return articles;
});
};
return this;
})
.controller('ArticlesCtrl', ['$scope', 'articleRetriever', function($scope, articleRetriever) {
$scope.articles = [];
$scope.filters = { tag: null, date_start : null, date_end : null, text : null };
articleRetriever.getLast()
.then(function(arrItems){
$scope.articlesLoaded = arrItems;
$scope.articles = $scope.articles.concat(arrItems);
});
$scope.applyFilter = function () {
var contains = $scope.filters.text.split(' ');
for (var idx in $scope.articles) {;
$scope.articles[idx].isHidden = true;
if (contains.length > 0) {
for( var jdx in contains) {
if ($scope.articles[idx].body.toUpperCase().indexOf( contains[jdx] ) > -1)
$scope.articles[idx].isHidden = false;
if ($scope.articles[idx].title.toUpperCase().indexOf( contains[jdx] ) > -1)
$scope.articles[idx].isHidden = false;
}
}
}
};
});
But when I fill the input with some text, the modification on $scope.articles didn't hide the article's div in article/views/article.html.
Can someone explain why and could give me a solution ?
Thanks :-)

My bad, the search form wasn't inside the div with the ng-controller="ArticleCtrl" directive, I moved it inside and all works perfectly now.

Related

Local storage not shown after refresh

I just can't get it working no matter what I do. Been sitting for hours and nothing. After submitting form I create local storage of values name, surname, email, so that I would be able to use them to fill up form so that user would not have to type them everytime.
submit() is in review.controller.js
(function () {
'use strict';
angular.module('app').controller('ReviewController', ReviewController);
ReviewController.$inject = ['$location', 'AuthenticationService', 'FlashService', 'UniversalService', '$scope', '$sce', '$rootScope','$route','$cookies','localStorageService'];
function ReviewController($location, AuthenticationService, FlashService, UniversalService, $scope, $sce, $rootScope,$route,$cookies,localStorageService) {
var vm = this;
vm.name = null;
vm.surname = null;
vm.Email = null;
vm.review = null;
vm.allgenres = [];
vm.submit = submit;
vm.allreviews = [];
$scope.localArray=[];
loadAllReviews();
submit();
$scope.templates = [{ name: 'man.main.view.html', url: 'main/main.view.html'}];
$scope.template = $scope.templates[0];
function loadAllReviews() {
UniversalService.GetAllReviews()
.then(function (review) {
vm.allreviews = review;
});
}
$scope.init = function () {debugger;
// $scope.$MainController.obtained_array = localStorage.getItem("storageKey");debugger;
$scope.storageKey = localStorage.getItem("storageKey");debugger;
};
$scope.storageKey = localStorage.getItem('storageKey');
/* $scope.$watch("storageKey", function() {debugger;
localStorage.setItem('storageKey', storageKey);
});*/
function submit() {
if($rootScope.name!=null) {
var JSONObject = {
"name":$rootScope.name,
"surname":$rootScope.surname,
"email":$rootScope.email,
"review":$rootScope.review
}
var temp={
"name":$rootScope.name,
"surname":$rootScope.surname,
"email":$rootScope.email
}
$scope.localArray.push(temp);
localStorageService.set("storageKey", $scope.localArray);
$scope.storageKey = localStorageService.get("storageKey");
// $rootScope.obtained_array = localStorageService.get("storageKey"); debugger;
console.log($scope.storageKey);debugger;
var Results = UniversalService.PostReview(JSON.stringify(JSONObject));
}
}
}
main.controller.js
'use strict';
var app= angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$location', 'AuthenticationService', 'FlashService', 'UniversalService', '$scope', '$sce', '$rootScope','$log','PagerService','localStorageService','$mdDialog'];
function MainController($location, AuthenticationService, FlashService, UniversalService, $scope, $sce, $rootScope,$log,PagerService,localStorageService,$mdDialog) {
var vm = this;
vm.allreviews = [];
vm.allusers=[];
vm.allemails=[];
vm.all=[];
vm.avatars=[];
$scope.filteredAll = [];
$scope.all=[];
$scope.items=[];
$scope.pager = {};
$scope.setPage = setPage;
loadAllReviews();
loadAllEmails();
loadAllUsers();
loadAll();
loadAvatars();
initController();
setPage();
submit();
$scope.init = function () {
$scope.$parent.storageKey = localStorage.getItem("storageKey");debugger;
// $scope.obtained_array = localStorage.getItem("storageKey");
// console.log(obtained_array); debugger;
// $scope.storageKey = localStorage.getItem("storageKey");debugger;
};
function refresh() {
location.reload();debugger;
}
function loadAll() {
UniversalService.GetAll()
.then(function (a) {
$scope.all=a;
});
}
function loadAllUsers(callback) {
UniversalService.GetAll()
.then(function (response) {
$scope.users=response;
if (callback) {
callback(response);
}
});
}
function loadAllReviews() {
UniversalService.GetAllReviews()
.then(function (review) {
vm.allreviews = review;
});
}
function loadAllEmails() {
UniversalService.GetAllEmails()
.then(function (email) {
vm.allemails = email;
});
}
function setPage(page) {
loadAllUsers(function (response) {
if (response) {
if (page < 1 || page > $scope.pager.totalPages) {
return;
}
// get pager object from service
$scope.everything=response;
$scope.pager = PagerService.GetPager(response.length, page);
// get current page of items
$scope.items = response.slice($scope.pager.startIndex, $scope.pager.endIndex + 1);
}
});
}
function initController() {
$scope.setPage(1); // initialize to page 1
}
}
HTML file:
<div class="container padding-tb" id="Review">
<div ng-controller="ReviewController" ng-init="init()" ng-app id="Review">
<h2>Add review</h2>
<form name="form" ng-submit="vm.submit()" role="form">
<div >
<div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="text" ng-model="name" onchange="CallItems()" id="name" class="form-control" ng-model="vm.name" placeholder="Enter name here" required />
<span ng-show="form.name.$dirty && form.name.$error.required" class="help-block">Name is required</span>
</div>
</div>
<div>
<div class="form-group">
<label for="surname">Surname</label>
<input type="text" ng-model="surname" name="text" id="surname" class="form-control" ng-model="vm.surname" placeholder="Enter surname here" required/>
<span ng-show="form.surname.$dirty && form.surname.$error.required" class="help-block">Surname is required</span>
</div>
</div>
<div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" name="email" id="email" class="form-control" ng-model="vm.email" placeholder="Enter email here" required />
<span ng-show="form.email.$dirty && form.email.$error.required" class="help-block">Email is required</span>
</div>
</div>
<div>
<div class="form-group">
<label for="review">Review</label>
<input type="text" name="text" id="review" class="form-control" ng-model="vm.review" placeholder="Enter review here" required/>
<span ng-show="form.review.$dirty && form.review.$error.required" class="help-block">Review is required</span>
</div>
</div>
<div class="form-actions">
<button id="submit" type="submit" onclick="passInfo()" class="btn btn-primary">Submit</button>
<label style="display:none" id="label"><font color="white">Review succesfully created!
<a onclick="refresh()" href="../ang/#!/review">Add new review</a></label> or
View reviews!
</div>
</div>
</form>
<div>
<div ng-init="init()" class="slide-animate-container">
<div class="slide-animate" ng-include="main.view.html"></div>
</div>
</div>
</div>
Currently I add these values to button to test if values are added:
<button ng-disabled="localStorage.getItem('LS_wimmtkey') !== null"> {{obtained_array}}</button>
My main.view is inserted into the review.view (because form and reviews are on the same page, main is for the review listing and reviews are submitted form)
After submiting form all these values appear in the button, but after refreshing page none of them are shown anymore. I kind of understand that it is all because everything I do with local storage is inside submit() function, but I am not sure how to fix it
You can write a init function on second controller and set the local Storage value in a variable.So whenever you refresh the page, init function will be called and local storage value will be available for you to use it in View
see below line:
<button ng-disabled="localStorage.getItem('LS_wimmtkey') !== null"> {{obtained_array}}</button>
"obtained_array" belong to $rootScope, so $rootScope can't bind to the template(binding to $rootScope is not possible )
quick solution is: change the following line
in case of: MainController
$scope.obtained_array = localStorage.getItem("LS_wimmtkey");debugger;
in case of :ReviewController (you are setting in this ctrl "LS_wimmtkey")
$scope.$parent.obtained_array = localStorage.getItem("LS_wimmtkey");debugger;

Angular ng-model not updating after typing into number input

So basically I'm creating a simple app with two controllers. ControllerA button increments ControllerB number input and vicer versa.
The problem is that $scope.total is not updating after typing into number input manually, and I don't know what would be the best way to achieve this.
HTML
<div ng-app="tabsApp">
<div id="tabOne" class="tabcontent">
<div ng-controller="tabOneController as vm">
<input type="button" value="increment value in tab 2" ng-click="vm.sumar()"/>
<input type="number" ng-model="vm.totalB.value">
</div>
</div>
<div id="tabTwo" class="tabcontent">
<div ng-controller="tabTwoController as vm">
<input type="button" value="increment value in tab 1" ng-click="vm.sumar()"/>
<input type="number" ng-model="vm.total.value">
</div>
</div>
</div>
JS
var app = angular.module('tabsApp', []);
app.controller("tabOneController", controllerA);
app.controller("tabTwoController", controllerB);
app.service('myData', function() {
var data = {
value: 0
}, dataB = {
value: 0
};
this.addItem = function (value) {
data.value = value;
}
this.getItem = function() {
return data;
}
this.addItemB = function (value) {
dataB.value = value;
}
this.getItemB = function() {
return dataB;
}
});
function controllerA(myData){
var scope = this;
scope.total = 0;
scope.sumar = function(){
scope.total++;
myData.addItem(scope.total);
}
scope.totalB = myData.getItemB();
}
function controllerB(myData){
var scope = this;
scope.totalB = 0;
scope.sumar = function(){
scope.totalB = myData
scope.totalB++;
myData.addItemB(scope.totalB);
}
scope.total = myData.getItem();
}
Here's a working example based on your code : Plunker
function controllerA(myData){
var scope = this;
scope.total = 0;
scope.sumar = function(){
scope.total = myData.getItem().value; // added this line
scope.total++;
myData.addItem(scope.total);
}
scope.totalB = myData.getItemB();
}
function controllerB(myData){
var scope = this;
scope.totalB = 0;
scope.sumar = function(){
scope.totalB = myData.getItemB().value; // modified this line
scope.totalB++;
myData.addItemB(scope.totalB);
}
scope.total = myData.getItem();
}
scope.totalB = myData.getItemB(); // first controller
scope.total = myData.getItem(); // second controller
These will be called just once when controller is loaded. Place them inside the function sumar
Use vm.total and vm.totalB instead of vm.total.value and vm.totalB.value in html
You could try implementing required ng-change="controller.functionThatIncrementsValues" in your html.
Would something like this help:
HTML
<div ng-app="tabsApp" ng-controller="tabController as vm">
<div id="tabOne" class="tabcontent">
<div>
<input type="button" ng-click="vm.one++" />
<input type="number" ng-model="vm.two">
</div>
</div>
<div id="tabTwo" class="tabcontent">
<div>
<input type="button" ng-click="vm.two++" />
<input type="number" ng-model="vm.one">
</div>
</div>
<p>Total (method 1): {{vm.one + vm.two}}</p>
<p>Total (method 2): {{ total(vm.one, vm.two) }}</p>
</div>
JS
var app = angular.module('tabsApp', []);
app.controller("tabController", function() {
this.one = 0;
this.two = 0;
this.total = function(one, two) {
return one + two;
}
})
Unless you have a specific need for two controllers and a service I would just put this all in one controller. At the moment what you have is massive overkill.

Show only clicked element values from multiple ng-click events angularjs

i have 10 more ng-click events, but i want to show only clicked element value where i have to change, but i updated in code there was so many true or false duplicates i have to write, pls help me that have to show only clicked ng-show values without using 'true or false' booleen functions in each click event.
var app = angular.module('myapp', ['ngSanitize']);
app.controller('AddCtrl', function ($scope, $compile) {
$scope.field = {single: 'untitled',single2:'default',single3:'enter'};
$scope.addName1 = function (index) {
var name1html = '<fieldset id="name1" ng-click="selectName1($index)"><label ng-bind-html="field.single"></label><input type="text" placeholder="Enter name"><button ng-click="removeName1($index)">-</button></fieldset>';
var name1 = $compile(name1html)($scope);
angular.element(document.getElementById('drop')).append(name1);
};
$scope.removeName1 = function (index) {
var myEl = angular.element(document.querySelector('#name1'));
myEl.remove();
};
$scope.selectName1 = function (index) {
$scope.showName1 = true;
$scope.showName2 = false;
$scope.showName3 = false;
};
$scope.addName2 = function (index) {
var name2html = '<fieldset id="name2" ng-click="selectName2($index)"><label ng-bind-html="field.single2"></label><input type="text" placeholder="Enter name"><button ng-click="removeName2($index)">-</button></fieldset>';
var name2 = $compile(name2html)($scope);
angular.element(document.getElementById('drop')).append(name2);
};
$scope.removeName2 = function (index) {
var myEl = angular.element(document.querySelector('#name2'));
myEl.remove();
};
$scope.selectName2 = function (index) {
$scope.showName2 = true;
$scope.showName1 = false;
$scope.showName3 = false;
};
$scope.addName3 = function (index) {
var name3html = '<fieldset id="name3" ng-click="selectName3($index)"><label ng-bind-html="field.single3"></label><input type="text" placeholder="Enter name"><button ng-click="removeName3($index)">-</button></fieldset>';
var name3 = $compile(name3html)($scope);
angular.element(document.getElementById('drop')).append(name3);
};
$scope.removeName3 = function (index) {
var myEl = angular.element(document.querySelector('#name3'));
myEl.remove();
};
$scope.selectName3 = function (index) {
$scope.showName3 = true;
$scope.showName1 = false;
$scope.showName2 = false;
};
});
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular-sanitize.min.js"></script>
</head>
<body ng-controller="AddCtrl">
<div id="drop"></div>
<button ng-click="addName1($index)">Name1</button>
<button ng-click="addName2($index)">Name2</button>
<button ng-click="addName3($index)">Name3</button>
<form ng-show="showName1">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single">
</div>
</form>
<form ng-show="showName2">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single2">
</div>
</form>
<form ng-show="showName3">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single3">
</div>
</form>
</body>
</html>
here is plunkr http://plnkr.co/edit/oFytWlQMIaCaeakHNk71?p=preview
You will need "ng-repeat" in the HTML. Set an Array on $scope and let the template determine what HTML elements to add. Typically, $index is only set by ng-repeat.
Read more here: https://docs.angularjs.org/api/ng/directive/ngRepeat

push increment item into an array in Angularjs

http://plnkr.co/edit/NDTgTaTO1xT7bLS1FALN?p=preview
<button ng-click="addRow()">add row</button>
<div ng-repeat="row in rows">
<input type="text" placeholder="name"><input type="tel" placeholder="tel">
</div>
I want to push new row and save all the fields but now I'm stuck at adding new rows. How to know the current number of row and do increment to push into the array?
Look at this example I created which allows you to generate up to eight unique input fields for Telephone and Text Entries.
var app = angular.module("MyApp", []);
app.controller("MyCtrl", function($scope) {
$scope.rows = [];
var Row = function(tel, text) {
// Private data
var private = {
tel: tel,
text: text
}
// Expose public API
return {
get: function( prop ) {
if ( private.hasOwnProperty( prop ) ) {
return private[ prop ];
}
}
}
};
$scope.addRow = function(){
if($scope.rows.length < 8){
var newItemNum = $scope.rows.length + 1;
var row = new Row('item' + newItemNum, 'item' + newItemNum);
$scope.rows.push(row);
}
};
$scope.saveAll = function(){
// $scope.result = 'something';
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<h2>Setting</h2>
<button ng-click="addRow()">Add Row</button>
<br />
<div ng-repeat="row in rows">
<input type="text" placeholder="Text" ng-model="row.textModel" >
<input type="tel" placeholder="Phone" ng-model="row.telModel" >
</div>
<br />
{{rows}}
</div>
</div>
Move functions inside controller 'Ctrl'.
In your script:
function Ctrl($scope) {
$scope.result = "something";
$scope.rows = ['1'];
$scope.addRow = function(){
if ($scope.rows.length < 8) {
$scope.rows.push($scope.rows.length + 1);
}
}
$scope.saveAll = function(){
// $scope.result = 'something';
}
}

$scope missing members for select binding

$scope seems to be missing binding properties for a text box typeahead and a select list.
Here is a fiddle showing the behavior I want: http://jsfiddle.net/langtonr/h4MKa/1/
You can add and remove salesmen as desired. The $scope is binding correctly to $scope.salesmanEntry (the salesman selected in the typeahead) and $scope.selectedSalesmen (salesmen that have been selected in the list box).
This same code I have copied and pasted into my project and it does not work. I am using all the same library references. It seems scope just doesn't work for these 2 variables. $scope.salesmanEntry and $scope.selectedSalesmen are always undefined. My full controller code is below. What could possibly be interfering with my $scope?
I'm outputting the following on my view:
<div>{{salesmanEntry.id}} {{salesmanEntry.displayName}}</div>
My view always shows these correctly, so when I have typed a salesman, it shows up, yet when I get to my controller code, $scope.salesmanEntry is always undefined. It exhibits the same behavior with $scope.selectedSalesmen. I can output to the screen by using an ng-repeat on selectedSalesmen, yet in my controller $scope.selectedSalesmen is always undefined.
manageProductsModule.controller('productDetailCtrl', [
'productSvc', 'equipmentOptionSvc', 'salesmanSvc', '$scope', function (productSvc, equipmentOptionSvc, salesmanSvc, $scope) {
$scope.loadingProduct = false;
$scope.product = {
secureUsers: [],
options: [],
priceHistory: []
};
$scope.addedSalesmen = [];
$scope.allSalesmen = [
{ id: 1, displayName: "Smith, John" },
{ id: 2, displayName: "Ramsey, Gordon" },
{ id: 3, displayName: "White, Betty" }];
$scope.addSalesman = function (salesman) {
if (!salesman.id) return;
var result = $.grep($scope.addedSalesmen, function (e) { return e.id == salesman.id; });
if (result.length === 0) {
$scope.addedSalesmen.push(salesman);
}
$scope.salesmanEntry = { id: -1, displayName: "" };
};
$scope.removeSalesmen = function () {
$scope.selectedSalesmen.forEach(function (salesman) {
var index = $scope.addedSalesmen.indexOf(salesman);
$scope.addedSalesmen.splice(index, 1);
});
$scope.selectedSalesmen = [];
}
}
]);
template:
<div ng-app="manageProductsModule">
<div class="container" ng-controller="productDetailCtrl">
<h3>Model Details</h3>
<form class="form-horizontal" role="form" ng-if="!loadingProduct">
<div class="form-group">
<label for="addSalesmenInput" class="control-label col-md-2">Add</label>
<div class="col-md-4">
<div class="input-group">
<input name="addSalesmenInput"
class="form-control"
ng-model="salesmanEntry"
typeahead="salesman as salesman.displayName for salesman in allSalesmen | filter:$viewValue" />
<div class="input-group-btn">
<button class="btn" ng-click="addSalesman(salesmanEntry)" ng-disabled="!salesmanEntry">
<i class="glyphicon glyphicon-plus"></i>
</button>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="salesmenInput" class="control-label col-md-2">Salesmen With Access</label>
<div class="col-md-4">
<select name="salesmenInput" multiple="multiple" size="8" class="form-control" ng-model="selectedSalesmen" ng-options="salesman as salesman.displayName for salesman in addedSalesmen"></select>
<button class="btn" ng-click="removeSalesmen()" ng-disabled="!selectedSalesmen || selectedSalesmen.length === 0">
<i class="glyphicon glyphicon-minus"></i>
</button>
</div>
</div>
</form>
</div>
</div>
So here is what I had to do to get this to work. I am definitely not happy with what seems like a very hacky solution and would like to know why this is necessary. I had to go to $scope.$$childHead to access salesmanEntry and selectedSalesmen as they are apparently being stored on the wrong scope.
$scope.addSalesman = function (salesman) {
if (!salesman.id) return;
var result = $.grep($scope.addedSalesmen, function (e) { return e.id == salesman.id; });
if (result.length === 0) {
$scope.addedSalesmen.push(salesman);
}
$scope.$$childHead.salesmanEntry = { id: -1, displayName: "" };
};
$scope.removeSalesmen = function () {
$scope.$$childHead.selectedSalesmen.forEach(function (salesman) {
var index = $scope.addedSalesmen.indexOf(salesman);
$scope.addedSalesmen.splice(index, 1);
});
$scope.$$childHead.selectedSalesmen = [];
}

Categories

Resources