When I do a search in my application, I want to wrap the matching characters in the results with bold tags so you can see the matches.
So the results view looks like:
<ul class="search-results ng-hide" ng-show="(results | filter: filterQuery).length > 0">
<li ng-repeat="result in results | filter:filterQuery">
<h3><a ui-sref="{{result.state}}">{{result.name}}</a></h3>
<p>{{result.snippet}}</p>
</li>
</ul>
And the controller:
myApp.controller('SearchCtrl', function($rootScope, $scope, $state, Result, $location, $filter) {
$scope.query = ($state.includes('search') ? $location.search()['q'] : '');
$scope.filterQuery = ($state.includes('search') ? $location.search()['q'] : '');
$scope.results = [];
$scope.queryChanged = function () {
$scope.filterQuery = $scope.query;
if($scope.query){
$state.go('search', {'q': $scope.query} );
} else {
$location.search('q', null);
}
}
if($scope.query){
$scope.results = Result.query();
} else {
$location.search('q', null);
}
});
So I need to wrap tags around the result.name and result.snippet when it matches the filterQuery.
Something like (bits of this were copied from a PHP version I've done in the past, hence the mismatched syntax):
var keys = $scope.filterQuery.split(" ");
result.snippet.replace('/('.implode('|', keys) .')/iu', '<b>\0</b>');
But where would this go?
Create a search-result directive to wrap each search result, where name needs to be set as bold:
<search-result result="result" name="name" ></search-result>
With the following template:
directive.template: 'prefix text' + '<B>' + attrs.name + </B> + ' suffix text';
There's a few ways you could do this, mostly using filters.
You could write your own filter, that would take the string in the search, find it in the content that you are searching, and then add the tags around it and send it back.
Or, you can use one of the many plugins out there that does this.
Heres a question that talks about it
Angular UI Highlight
Related
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>
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.
I want to parse the JSON response of Country & State from below mentioned URL.
https://gist.githubusercontent.com/mayurah/5f4a6b18b1aa8c26910f/raw/countriesToCities.json
{
"China": [
"Guangzhou",
"Fuzhou",
"Beijing",
"Baotou",
"Hohhot",
"Guiyang",
"Yinchuan",
"Nanjing",
"Changzhou",
"Chuzhou",
"Hefei",
"Jinan",
"Qingdao",
"Harbin",
"Zhaodong",
"Taiyuan",
"Xi'an",
.
.
.
}
]
I want the result as,
Guangzhou, China
Taiyuan, China
I am using AngularJS, Following is a piece of code of my controllers.js file.
var
apiUrl = {
countryStateList: 'https://gist.githubusercontent.com/mayurah/5f4a6b18b1aa8c26910f/raw/countriesToCities.json'
};
countryData.controller('countryDataCtrl', ['$scope', '$http', function($scope, $http) {
$http.get(apiUrl.countryStateList).success(function(data) {
// console.log(data);
$scope.countryStateList = data;
});
}]);
And, in my HTML file, code is something like this,
<ul ng-repeat="country in countryStateList">
<li>{{ STATE_NAME, COUNTRY_NAME }}</li>
</ul>
STATE_NAME & COUNTRY_NAME are just for in display information. Both must be replaced with Angular code.
The problem is JSON element names are itself country names. Can someone tell me how to parse the same in AngularJS/Javascript.
You could start by parsing the whole JSON:
var jsonObject = JSON.parse(RAW_JSON_STING);
var newJsonObject = [];
// Loop through it
for (var interator in jsonObject)
{
for (var it = 0; it < iterator.length; it++)
{
newJsonObject.push(iterator[it] + ", " + iterator);
}
}
No guarantee the code above will work as intended.
Ng-repeat will not be useful in your case. This would be possible using directive.
<datalist id="stateCountry">
<custom-datalist-option data-array="countryStateList"></custom-datalist-option>
</datalist>
Link a directive function and create an option using using it.
Here is the Update Fiddle
Hope this will help you.
I have a Phone.json with contents like :
{
"Call": "Hi, Please contact the custom care at (119)239-9999 for further discussions"
},
{
"Call": " For emergency dial 911 as soon as possible"
}
I need to display the above string on mobile browser and make them click to call using tel protocol
Following is the approach that ive used
My index. html :
<body ng-controller="PhoneListCtrl">
<ul ng-repeat="phone in phones">
<li>
<a ng-click="convertContactNumbers(phone.Call)">{{phone.Call}}</li>
</ul>
</body>
Controller :
myApp.controller('PhoneListCtrl', ['$scope', '$http', function($scope, $http)
{
$http.get('Phone.json').
success(function(data)
{
$scope.phones = data;
});
$scope.convertContactNumbers = function(st)
{
if (st.match((/(((\(?\+?1?\)?)\s?-?)?((\(?\d{3}\)?\s?-?\s?))?\s?\d{3}\s?-?\s?\d{4}){1}/gm)))
{
st = st.replace(/(((\(?\+?1?\)?)\s?-?)?((\(?\d{3}\)?\s?-?\s?))?\s?\d{3}\s?-?\s?\d{4}){1}/gm, "<a href='tel:$1'>$1</a>");
return(st);
}
else
{
st = st.replace(/([0-9]{3})/, "<a href='tel:$1'>$1</a>");
return(st);
}
}
}]);
The issue is now to handle the st which holds "For emergency dial <a href='tel:911'>911</a> as soon as possible" so that it renders as an HTML page to make the links clickable.How can I do it?
See this question: How do you use $sce.trustAsHtml(string) to replicate ng-bind-html-unsafe in Angular 1.2+
It tells angular to render string as html.
myApp.filter('unsafe', function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
});
And the view:
<ul ng-repeat="phone in phones">
<li ng-bind-html="convertContactNumbers(phone.Call) | unsafe"></li>
</ul>
Working: http://plnkr.co/edit/eV04J9gjjzJ8h3IGM4cZ?p=info
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>