Ich verwende einen ng-Wiederholungs- und Filtervorgang in angleJS wie das Tutorial für Telefone. Ich möchte jedoch die Suchergebnisse auf der Seite markieren. Mit Basic jQuery hätte ich einfach die Seite nach Taste auf der Eingabe analysiert, aber ich versuche es auf die eckige Art und Weise. Irgendwelche Ideen ?
Mein Code:
<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>
In tat das für 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;
}
winkelige ui-utils unterstützt nur einen Begriff. Ich verwende den folgenden Filter anstelle einer Bereichsfunktion:
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>'));
};
});
Und das HTML:
<span ng-bind-html="theText | highlight:theTerms"></span>
Versuchen Sie Angular UI
Filter -> Highlite (Filter) . Es gibt auch die Keypress-Direktive.
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)
}
})
Referenz: http://codeforgeek.com/2014/12/highlight-search-result-angular-filter/ Demo: http://demo.codeforgeek.com/highlight-angular/
Ich hoffe, mein Lichtbeispiel wird es leicht verständlich machen:
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>
Es gibt einen Standard-Highlight-Filter in der angle-bootstrap : typeaheadHighlight
Verwendungszweck
<span ng-bind-html="text | typeaheadHighlight:query"></span>
Mit Geltungsbereich {text:"Hello world", query:"world"}
wird gerendert
<span...>Hello <strong>world</strong></span>
Ich löste die Antwort von @ uri in diesem Thread und änderte sie, um mit einem einzelnen String ODER einem String-Array zu arbeiten.
Hier ist die TypeScript Version
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);
};
Was bedeutet dies in 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= {}));
;
Oder wenn Sie nur eine einfache JavaScript-Implementierung ohne diese generierten Namespaces wollen:
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;
}
};
}]);
EDITIERTEUm einen Fix einzufügen, der zuvor defekt wäre, wird nach .
oder einem anderen Zeichen gesucht, das in einem regulären Ausdruck eine Bedeutung hat. Jetzt werden diese Zeichen zuerst entkommen.
Verwenden Sie ng-class, die angewendet wird, wenn der Suchbegriff sich auf die Daten bezieht, die das Element enthält.
Bei Ihren Wiederholungselementen hätten Sie ng-class="{ className: search_query==elementRelatedValue}"
dies würde die Klasse "className" dynamisch auf Elemente anwenden, wenn die Bedingung erfüllt ist.
Danke, dass Sie das gefragt haben, da es auch etwas war, mit dem ich mich gerade befasst habe.
Zwei Dinge jedoch:
Erstens, Die erste Antwort ist großartig, aber der Kommentar dazu ist richtig, dass highlight () Probleme mit Sonderzeichen hat. Dieser Kommentar schlägt vor, eine Escape-Kette zu verwenden, die funktionieren wird, aber sie schlägt vor, unescape () zu verwenden, das ausläuft. Was ich endete mit:
$sce.trustAsHtml(decodeURI(escape(text).replace(new RegExp(escape(search), 'gi'), '<span class="highlightedText">$&</span>')));
Zweitens habe ich versucht, dies in einer datengebundenen Liste von URLs zu tun. Während Sie sich in der highlight () - Zeichenfolge befinden, brauchen Sie keine Datenbindung.
Beispiel:
<li>{{item.headers.Host}}{{item.url}}</li>
Wurden:
<span ng-bind-html="highlight(item.headers.Host+item.url, item.match)"></span>
Ich hatte Probleme, wenn man sie in {{}} beließ und alle möglichen Fehler bekam.
Ich hoffe, das hilft jedem, der die gleichen Probleme hat.
Über die Probleme mit speziellen Charakteren denke ich, dass Sie die Regex-Suche verlieren könnten.
Was ist mit diesem:
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>'));
};
Ein ungültiger regulärer Ausdruck könnte ein Benutzer sein, der nur den Text eingibt:
Was denkst du @Mik Cox?
Meine Lösung für Highlight, verwendete dies mit einem eckigen UI-Baumelement: https://codepen.io/shnigi/pen/jKeaYG
angular.module('myApp').filter('highlightFilter', $sce =>
function (element, searchInput) {
element = element.replace(new RegExp(`(${searchInput})`, 'gi'),
'<span class="highlighted">$&</span>');
return $sce.trustAsHtml(element);
});
Css hinzufügen:
.highlighted {
color: orange;
}
HTML:
<p ng-repeat="person in persons | filter:search.value">
<span ng-bind-html="person | highlightFilter:search.value"></span>
</p>
Und um eine Sucheingabe hinzuzufügen:
<input type="search" ng-model="search.value">
Ein anderer Vorschlag:
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>' }}
Ich bin offen für Kritik! ;-)
Wenn Sie die Winkelmaterialbibliothek verwenden, gibt es eine eingebaute Direktive namens md-highlight-text
Aus der Dokumentation:
<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>
Link zu den Dokumenten: https://material.angularjs.org/latest/api/directive/mdHighlightText