Выделение отфильтрованного результата в AngularJS
Я использую ng-repeat и фильтр в angularJS, как в учебнике по телефонам, но хочу выделить результаты поиска на странице. С базовым jQuery я бы просто проанализировал страницу с ключом на входе, но я пытаюсь сделать это способом angular. Любые идеи?
Мой код:
<input id="search" type="text" placeholder="Recherche DCI" ng-model="search_query" autofocus>
<tr ng-repeat="dci in dcis | filter:search_query">
<td class='marque'>{{dci.marque}} ®</td>
<td class="dci">{{dci.dci}}</td>
</tr>
Ответы
Ответ 1
In сделал это для AngularJS v1.2 +
HTML:
<span ng-bind-html="highlight(textToSearchThrough, searchText)"></span>
JS:
$scope.highlight = function(text, search) {
if (!search) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(new RegExp(search, 'gi'), '<span class="highlightedText">$&</span>'));
};
CSS
.highlightedText {
background: yellow;
}
Ответ 2
angular ui-utils поддерживает только один термин. Я использую следующий фильтр, а не функцию области видимости:
app.filter('highlight', function($sce) {
return function(str, termsToHighlight) {
// Sort terms by length
termsToHighlight.sort(function(a, b) {
return b.length - a.length;
});
// Regex to simultaneously replace terms
var regex = new RegExp('(' + termsToHighlight.join('|') + ')', 'g');
return $sce.trustAsHtml(str.replace(regex, '<span class="match">$&</span>'));
};
});
И HTML:
<span ng-bind-html="theText | highlight:theTerms"></span>
Ответ 3
Попробуйте Angular пользовательский интерфейс
Фильтры → Highlite (фильтр).
Существует также директива Keypress.
Ответ 4
index.html
<!DOCTYPE html>
<html>
<head>
<script src="angular.js"></script>
<script src="app.js"></script>
<style>
.highlighted { background: yellow }
</style>
</head>
<body ng-app="Demo">
<h1>Highlight text using AngularJS.</h1>
<div class="container" ng-controller="Demo">
<input type="text" placeholder="Search" ng-model="search.text">
<ul>
<!-- filter code -->
<div ng-repeat="item in data | filter:search.text"
ng-bind-html="item.text | highlight:search.text">
</div>
</ul>
</div>
</body>
</html>
app.js
angular.module('Demo', [])
.controller('Demo', function($scope) {
$scope.data = [
{ text: "<< ==== Put text to Search ===== >>" }
]
})
.filter('highlight', function($sce) {
return function(text, phrase) {
if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
'<span class="highlighted">$1</span>')
return $sce.trustAsHtml(text)
}
})
Ссылка: http://codeforgeek.com/2014/12/highlight-search-result-angular-filter/
demo: http://demo.codeforgeek.com/highlight-angular/
Ответ 5
Отключение ответа @uri в этом потоке, я изменил его для работы с одной строкой ИЛИ строковым массивом.
Здесь TypeScript версия
module myApp.Filters.Highlight {
"use strict";
class HighlightFilter {
//This will wrap matching search terms with an element to visually highlight strings
//Usage: {{fullString | highlight:'partial string'}}
//Usage: {{fullString | highlight:['partial', 'string, 'example']}}
static $inject = ["$sce"];
constructor($sce: angular.ISCEService) {
// The `terms` could be a string, or an array of strings, so we have to use the `any` type here
/* tslint:disable: no-any */
return (str: string, terms: any) => {
/* tslint:enable */
if (terms) {
let allTermsRegexStr: string;
if (typeof terms === "string") {
allTermsRegexStr = terms;
} else { //assume a string array
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort((a: string, b: string) => b.length - a.length).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
} else {
return str;
}
};
}
}
angular
.module("myApp")
.filter("highlight", HighlightFilter);
};
Что переводится в JavaScript:
var myApp;
(function (myApp) {
var Filters;
(function (Filters) {
var Highlight;
(function (Highlight) {
"use strict";
var HighlightFilter = (function () {
function HighlightFilter($sce) {
// The `terms` could be a string, or an array of strings, so we have to use the `any` type here
/* tslint:disable: no-any */
return function (str, terms) {
/* tslint:enable */
if (terms) {
var allTermsRegexStr;
if (typeof terms === "string") {
allTermsRegexStr = terms;
}
else {
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort(function (a, b) { return b.length - a.length; }).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
}
else {
return str;
}
};
}
//This will wrap matching search terms with an element to visually highlight strings
//Usage: {{fullString | highlight:'partial string'}}
//Usage: {{fullString | highlight:['partial', 'string, 'example']}}
HighlightFilter.$inject = ["$sce"];
return HighlightFilter;
})();
angular.module("myApp").filter("highlight", HighlightFilter);
})(Highlight = Filters.Highlight || (Filters.Highlight = {}));
})(Filters = myApp.Filters || (myApp.Filters = {}));
})(myApp|| (myApp= {}));
;
Или если вы просто хотите простую реализацию JavaScript без этих сгенерированных пространств имен:
app.filter('highlight', ['$sce', function($sce) {
return function (str, terms) {
if (terms) {
var allTermsRegexStr;
if (typeof terms === "string") {
allTermsRegexStr = terms;
}
else {
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort(function (a, b) { return b.length - a.length; }).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
}
else {
return str;
}
};
}]);
EDITED, чтобы включить исправление, которое ранее было нарушено, это кто-то искал .
или любой другой символ, имеющий значение в регулярном выражении. Теперь эти символы сначала экранируются.
Ответ 6
Надеюсь, мой легкий пример облегчит понимание:
app.filter('highlight', function() {
return function(text, phrase) {
return phrase
? text.replace(new RegExp('('+phrase+')', 'gi'), '<kbd>$1</kbd>')
: text;
};
});
<input type="text" ng-model="search.$">
<ul>
<li ng-repeat="item in items | filter:search">
<div ng-bind-html="item | highlight:search.$"></div>
</li>
</ul>
![введите описание изображения здесь]()
Ответ 7
Существует стандартный фильтр Highlight в angular -bootstrap: typeaheadHighlight
Использование
<span ng-bind-html="text | typeaheadHighlight:query"></span>
С областью {text:"Hello world", query:"world"}
отображается в
<span...>Hello <strong>world</strong></span>
Ответ 8
Используйте ng-класс, который применяется, когда термин поиска связан с данными, содержащимися в элементе.
Итак, на ваших ng-повторных элементах вы должны иметь ng-class="{ className: search_query==elementRelatedValue}"
который будет применять класс "className" к элементам динамически при выполнении условия.
Ответ 9
О проблемах со специальным caracter, я думаю, что просто сбежать от вас может потерять поиск в регулярном выражении.
Как насчет этого:
function(text, search) {
if (!search || (search && search.length < 3)) {
return $sce.trustAsHtml(text);
}
regexp = '';
try {
regexp = new RegExp(search, 'gi');
} catch(e) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(regexp, '<span class="highlight">$&</span>'));
};
Недопустимым регулярным выражением может быть пользователь, просто вводящий текст:
- valid: m
- неверно: m [
- недействителен: m [ô
- неверно: m [ôo
- valid: m [ôo]
- valid: m [ôo] n
- valid: m [ôo] ni
- valid: m [ôo] nic
- valid: m [ôo] nica
Как вы думаете, @Mik Cox?
Ответ 10
Другое предложение:
app.filter('wrapText', wrapText);
function wrapText($sce) {
return function (source, needle, wrap) {
var regex;
if (typeof needle === 'string') {
regex = new RegExp(needle, "gi");
} else {
regex = needle;
}
if (source.match(regex)) {
source = source.replace(regex, function (match) {
return $('<i></i>').append($(wrap).text(match)).html();
});
}
return $sce.trustAsHtml(source);
};
} // wrapText
wrapText.$inject = ['$sce'];
// use like this
$filter('wrapText')('This is a word, really!', 'word', '<span class="highlight"></span>');
// or like this
{{ 'This is a word, really!' | wrapText:'word':'<span class="highlight"></span>' }}
Я открыт для критики!; -)
Ответ 11
Спасибо, что спросили об этом, поскольку я тоже имел дело с этим.
Две вещи:
Во-первых, верхний ответ велик, но комментарий к нему верен, что функция highlight() имеет проблемы со специальными символами. Этот комментарий предполагает использование ускоряющейся цепи, которая будет работать, но они предлагают использовать unescape(), который постепенно прекращается. Что я закончил:
$sce.trustAsHtml(decodeURI(escape(text).replace(new RegExp(escape(search), 'gi'), '<span class="highlightedText">$&</span>')));
Во-вторых, я пытался сделать это в списке URL-адресов, привязанных к данным. Хотя в строке highlight() вам не нужно связывать данные.
Пример:
<li>{{item.headers.host}}{{item.url}}</li>
Стал:
<span ng-bind-html="highlight(item.headers.host+item.url, item.match)"></span>
Возникла проблема с оставлением их в {{}} и получением всех видов ошибок.
Надеюсь, это поможет любому, кто сталкивается с теми же проблемами.
Ответ 12
Если вы используете библиотеку материалов angular, есть встроенная директива, называемая md-highlight-text
Из документации:
<input placeholder="Enter a search term..." ng-model="searchTerm" type="text">
<ul>
<li ng-repeat="result in results" md-highlight-text="searchTerm">
{{result.text}}
</li>
</ul>
Ссылка на документы: https://material.angularjs.org/latest/api/directive/mdHighlightText