trouble with search in angular - javascript

I'm new to angular and experiencing some difficulty implementing a 'live search' type of feature. I have my JSON set as a variable in a javascript file and I am able to display that in the html with no problem. I then have a 'list' radio box which changes the size of the display. This is functional as well. I run into trouble, however, when accessing the reverse filter option which is denoted with another radio button. The intended result is to filter the book titles in reverse by their name, ye nothing happens. Here is my JSON if you want to see the structure. And below is the code where I try to perform the filter reverse action:
<div class="container result">
<div ng-class="list ? 'col-md-6' : 'col-md-4'" class="books" ng-repeat="books in books | filter:search | orderBy:'books.doc.name':reverse"> <a href="https://address/{{books.doc.name}}" target="_blank">
<img ng-class="list ? 'col-md-2' : 'col-md-12'" ng-src="{{books.doc.thumbnail_590_url}}" alt="Click to read {{books.doc.name}}" title="Click to read {{books.doc.name}}" class="img-thumbnail" /></a>
<h4 ng-class="list ? 'col-md-10' : 'col-md-12'">{{books.doc.name}}</h4>
</div>
and heres the js:
angular.module("myApp",["ngSanitize"])
.filter('replace', function () {
var pat = / /gi;
return function (text) {
var clean = text.replace(pat, "-");
var temp = clean.split("---");
if (temp.length>1) {
clean = temp[0];
}
return clean;
};
})
.controller("Example", function($scope, $interval) {
$scope.search = "orig";
$scope.books = books;
$scope.reverse = false;
$scope.list = false;
});

I figured this out. Angular filter will not work on a json object, rather the data must be in the form of a json array. I removed the highest level enclosing curly brackets and replaced them with square brackets in addition to removing the numbers and colons like "1272:" that can be seen in the json file I posted. Taking these steps converted my data to a json array and allowed me to use the live search functionality.

Related

Display checkboxes in with AngularJS based on two object arrays

I know there are several similar topics already but I found none that really matches my problem.
When opening my AngularJS app/website I am loading two arrays of objects (both are of the same type). One list contains all possible values (called sources here) and the other list is a selection of elements from the first.
My goal is display all sources as checkboxes. The ones from the second list have to be preselected, the rest not. Now the user can select/deselect checkboxes. If he does so I need to inform the server (with the source.id).
What I got so far:
exampleApp.controller('testController', [ '$scope', '$http', function($scope, $http) {
$scope.sources = [];
$scope.selectedSources = [];
$scope.changeSource = function(source) {...};
})
and
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="??"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
What I can't figure out is how I can get ng-model to preselect the right checkboxes and how to get the new (and old) values to changeSource(). Is there an elegant way of doing that?
Example (Pseudo code only):
Sources = [{id=1, name=test1},{id=2, name=test2}, ...]
SelectedSources = [{id=2, name=test2}]
Now what I need are checkboxes like this:
[ ] test1 [x] test2
where all elements from sources are checkboxes and the ones from selectedsources are preselected. Changes of the selection can be stored in selected sources (as objects) and have to trigger my changeSource() function so that I can inform my server.
Set the selected/unselected state in a property inside each of the objects in Sources array(initialize it based on whats present in selectedArray)
$scope.sources.forEach(function(source) {
source.selected = isSelected(source);
})
function isSelected(selectedSource) {
return !!$scope.selectedSources.find(function(s) {
return s === selectedSource || s.id == selectedSource.id;
})
}
Here's a working plunker link
I didn't understood your question very well, but if i'm not mistaken, you want to fill the second collection only with the selected items from the first one, right? If it's the case, you could turn your second collection into a returning function with a filter of the first inside, as follows:
In your controller:
exampleApp.controller('testController', [ '$scope', '$http', function ($scope, $http) {
$scope.sources = [];
/* ... */
$scope.getSelectedSources = function () {
return $scope.sources.filter(function (val) {
return val.selected;
});
};
})
In your template:
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
<div ng-repeat="source in getSelectedSources()">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
Hi this may be help you to get new & old value.
$scope.$watch('sources', function (oldval, newval) {
console.log(oldval + newval);
});

ng-repeat not rendering data from array

I am working on a web app where non-profit organizations can create a profile and be easily searchable by various parameters. In the "create and organization" form, I have a nested array where the organization can add donations that they need. The array is storing ok (I can add multiple donations), however when I try to display it using ng-repeat, nothing renders. When I don't use the ng-repeat and just display via {{ ctrl.organization.donations }} the information shows up with brackets and quotation marks.
Here is the code that I use to add the donations (via the newOrganization controller):
function NewOrganizationController(OrganizationService, CategoryService, $stateParams, $state, $http, Auth){
var ctrl = this;
CategoryService.getCategories().then(function(resp) {
ctrl.categories = resp.data;
});
ctrl.donations = [{text: ''}];
Auth.currentUser().then(function(user) {
ctrl.user = user;
})
ctrl.addNewDonation = function() {
var newDonation = ctrl.donations.length+1;
ctrl.donations.push({text: ''});
};
ctrl.removeDonation = function() {
var lastItem = ctrl.donations.length-1;
ctrl.donations.splice(lastItem);
};
ctrl.addOrganization = function() {
var donations = this.donations;
var allDonations = [];
for (var key in donations) {
if (donations.hasOwnProperty(key)) {
var donation = donations[key].text;
allDonations.push(donation);
}
}
var data = {
name: ctrl.organization.name,
description: ctrl.organization.description,
address: ctrl.organization.address,
donations: allDonations.join("/r/n"),
category_id: this.category.id
};
OrganizationService.createOrganization(data);
$state.go('home.organizations');
};
}
angular
.module('app')
.controller('NewOrganizationController', NewOrganizationController);
Here is the code that I am using to display the array on my show page (this is what shows up with brackets, i.e. donations needed: ["food", "clothing"]):
<h5>{{ ctrl.organization.donations }}</h5>
This is the ng-repeat code that is not rendering anything to the page:
<li class="list-group-item" ng-repeat="donation in donations track by $index">
{{ donation }}
</li>
I've tried to use .join(', ') within the {{donation}} brackets, but this isn't recognized as a function.
edit: After taking AJ's suggestion here is a screenshot of what appears...anyone know how to fix this?
seems that my array is showing up in table form, with each row containing one character
Any help would be greatly appreciated. Here is a link to the github repo in case you want to look at anything else or get a bigger picture.
You need to use the same variable name that works in the h5
<li class="list-group-item" ng-repeat="donation in ctrl.organization.donations track by $index">
{{ donation }}
</li>

AngularJS - run check against elements as they come back

I just followed this
JSFiddle example to create a little search box from an array object in my javascript. Now after some tweaking and research on search.object and filter:search:strict. Now that I have it filtering correctly, I modified a checkbox in the template that is checked upon loading the document and switched on or off based on a custom data attribute in the html that is updated by the json array.
How do I run this check once someone clears the search and the old items show back up again?
In the HTML I have this template
<div ng-repeat="o in objects | filter:search:strict | orderBy:'obj_name'" class="objectContainer">
<h3>{{o.obj_name}}</h3>
<label class="userToggleSwitch" >
<input class="userToggleInput" data-isactive="{{o.obj_isactive}}" type="checkbox">
<div class="slider round"></div>
</label>
</div>
In the JS
angular.element(document).ready(function(){
angular.module('searchApp',[])
.controller('searchCtrl', ['$scope','objHolder',function ($scope,objHolder) {
$scope.search = '';
$scope.objects = [];
$scope.objects = objHolder.getobjects();
}])
// fake service, substitute with your server call ($http)
.factory('objHolder',function(){
var objects = objList;
return {
getobjects : function(){
return objects;
}
};
});
});
The JS that modifies the items on document load is using jquery like this
$(document).ready(function(){
//console.log($('.userToggleInput'));
$.each($('.userToggleInput'), function(){
if($(this).data("isactive") == 1){$(this).attr('checked', true);}
if($(this).data("isactive") == 0){$(this).attr('checked', false);}
})
$('.userToggleInput').click(function(){
if ($(this).attr('checked') == undefined) {
// THIS IS WHERE WE WILL MAKE AN AJAX CALL TO A PHP CLASS
// TO REQUEST IF THE USER CAN BE TURNED ON - DUE TO LIC RESTRICTIONS
$(this).attr('checked',true);
} else {
$(this).attr('checked',false);
}
//console.log($(this).attr('checked'));
});
});
Created JS Fiddle to assist in Helping in this manner

Filter variable not updating in controller angularjs

Hi Im attempting to build functionality around the length of a filter in angularjs, and although its working as it should in the view, in the controller the variable seems to stay outdated...
When I click on the div below it filters a list and calls the filterby function. The output of the length of the newly filtered list updates in the view correctly. However in the function itself I have a log set and it is still showing the old length when I click on the div.
<div ng-repeat="filter in filters" ng-click="filterby(filter.filter_type)">{{filter.filter_type}}</div>
<ul>
<li ng-repeat="event in filtered = (events | filter:query) | orderBy:'-event_date' ">
<span >{{event.event_date}},{{event.event_name}}, {{event.event_venue}}, {{event.event_description}} </span>
</li>
</ul>
<br />Length of filtered items {{filtered.length}}
And my view....
$scope.filterby = function(filterby) {
if (filterby == 'ALL') {
$scope.query = '';
}
else {
$scope.query = filterby;
}
console.log($scope.filtered.length);
};
My filter data:
$scope.filters = [
{'filter_type' : 'ALL'},
{'filter_type' : 'Macnass'}
];
EDIT: Ok its not that it nots working at all, its just showing the previous value, as if its one click behind all the time, so its something to do with the fact that the variable in the view is updated after the list is made. but Im not sure how to go about insuring the variable in the controller is the latest value.
Plunker: http://plnkr.co/edit/u7KpqYx8gDwaaXEvGeMn?p=preview
check out the plunker
added below
$scope.filtered = $filter('filter')($scope.events, $scope.query)
in $scope.filterby function

Rendering unicode-utf-8 turkish characters with angular-js

Characters from a binded JSON text, Turkish the letters are shown with wrong encoding for eg. Özlem Güzelharcan which shall look like "özlem güzelharcan". I added <meta characters="utf-8"> in the head still no solution and there was no problem with laravel blade views.
If necessary this is how I get and use data:
view:
<div class="comment" ng-hide="loading" ng-repeat="comment in comments">
Comment #{{ comment.id }} </h3> <p>{{comment.title}}</p>
{{comment.author_id}} / {{comment.author.name}}
Services:
// public/js/services/commentService.js
angular.module('commentService', [])
.factory('Comment', function($http) {
var data = {
// get all the comments
get : function() {
return $http.get('/api/comments/');
}
}
console.log(data);
return data;
});
//controller (shortly)
.controller('mainController', function($scope, $http, Comment) {
// object to hold all the data for the new comment form
$scope.commentData = {};
// loading variable to show the spinning loading icon
$scope.loading = true;
// get all the comments first and bind it to the $scope.comments object
// use the function we created in our service
// GET ALL COMMENTS ====================================================
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
});
Which method is used to clean characters with AngularJS?
Thanks
Eventually, after trying many things, I discovered that you have to use ng-bind-html or ng-bind-html-unsafe (with ngSanitize) to get the correct encoding. Here is how it works in my view:
Comment #<span ng-bind-template="{{comment.id}}"></span> </h3>
<span ng-bind-html="comment.title "></span>
<p><div ng-bind-html="comment.content | truncate:25"></div></p>

Categories

Resources