Как мне выделить цвета для результатов поиска - PullRequest
3 голосов
/ 04 февраля 2020

Не могли бы вы помочь выделить выделенные слова желтым цветом?

Ниже приведен пример кода для фильтрации слов среди отображаемых данных из JSON URL-адреса фида.

angular.module('sample', []).
controller('sampleController', ['$scope', '$http', function($scope, $http) {
  var url = "https://spreadsheets.google.com/feeds/list/153Obe1TdWlIPyveZoNxEw53rdrghHsiWU9l-WgGwCrE/od6/public/values?alt=json";

  $http.get(url)
    .success(function(data, status, headers, config) {
      $scope.users = data.feed.entry;
      console.log($scope.users);
    })
    .error(function(error, status, headers, config) {
      console.log(status);
      console.log("Error occured");
    });
   // code to highlight
   
    $scope.highlight = () => {
  //create copy of the original array
  $scope.filteredContent = JSON.parse(JSON.stringify($scope.users));

  $scope.filteredContent.forEach(fc => {
    const regEx = new RegExp($scope.search);
alert("here");
    fc.question = fc.gsx$topic.$t.replace(regEx, '<span class="highlight">${$scope.search}</span>');
    fc.answer = fc.gsx$response.$t.replace(regEx, '<span class="highlight">${$scope.search}</span>');
  });
};
    
  // code to highlight
   
$scope.search='';
$scope.searchFilter=function(item){

	if(item.gsx$topic.$t.toLowerCase().indexOf($scope.search.toLowerCase()) != -1 || item.gsx$response.$t.toLowerCase().indexOf($scope.search.toLowerCase()) != -1){
      return true;
    }
    return false;
  }

}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.0/angular.min.js"></script>
<div ng-app="sample" ng-controller="sampleController">
  <div class="black">
    <input type="text" name="search" ng-keyup="highlight()" ng-model="search" placeholder="search"/>
  </div>
  <br>
  <br>
  <br>
  <table style="border: 1px solid black ;">
    <tbody>
      <tr>
        <td>
          <center><b>Question</b></center>
        </td>
        <td>
          <center><b>Response</b></center>
        </td>
      </tr>
      <tr ng-repeat="user in users | filter:searchFilter">
        <td style="border: 1px solid black ; width:30%;white-space: pre-wrap;" ng-bind-html="user.gsx$topic.$t">{{user.gsx$topic.$t}}</td>
        <td style="border: 1px solid black ; width:70%;white-space: pre-wrap;" ng-bind-html="user.gsx$response.$t">{{user.gsx$response.$t}}</td>
      </tr>
    </tbody>
  </table>
</div>

Код ссылки: https://jsfiddle.net/bjqsgfzc/1/

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Вам нужно будет использовать сервис $sce Строгое контекстуальное экранирование .

Добавьте этот сервис в декларацию вашего контроллера, например:

controller('sampleController', ['$scope', '$http', '$sce', function($scope, $http, $sce) {

Теперь вы должны определить функцию, которая будет вставлять тег span только с именем класса CSS желтого цвета, который будет выделен, когда найденный текст будет найден с помощью метода $sce.trustAsHtml, чтобы укажите AngularJS, введенный является безопасным содержимым.

$scope.highlightText = function(text, search) {
  if (search && search.length === 0) {

    // Returns the default content.
    return $sce.trustAsHtml(text);
  }

  // Define a regular expression to find the text globally and ignoring capital letters.
  var regex = new RegExp(search, 'gi');

  // If you already found the text then inject a span element with CSS class to highlight that you found.
  return $sce.trustAsHtml(text.replace(regex, '<span class="foundText">$&</span>'));
};

В предыдущем тексте замены регулярного выражения $& указывает на отображение захваченного текста, соответствующего регулярному выражение внутри заменяемого.

В HTML, в пределах ng-repeat, добавьте директиву ngBindHtml с функцией highlightText, где первый параметр это текст, который вам нужно искать, а второй параметр - это текст, который нужно найти.

В вашем случае, таким образом:

<tr ng-repeat="user in users | filter:searchFilter">
        <td style="border: 1px solid black ; width:30%;white-space: pre-wrap;" ng-bind-html="highlightText(user.gsx$topic.$t, search)">{{user.gsx$topic.$t}}</td>

См. в этом примере:

angular.module('sample', []).
controller('sampleController', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
  var url = "https://spreadsheets.google.com/feeds/list/153Obe1TdWlIPyveZoNxEw53rdrghHsiWU9l-WgGwCrE/od6/public/values?alt=json";

  $http.get(url)
    .success(function(data, status, headers, config) {
      $scope.users = data.feed.entry;
      console.log($scope.users);
    })
    .error(function(error, status, headers, config) {
      console.log(status);
      console.log("Error occured");
    });
  $scope.search = '';
  $scope.searchFilter = function(item) {
    if (item.gsx$topic.$t.indexOf($scope.search) != -1 || item.gsx$response.$t.indexOf($scope.search) != -1) {
      return true;
    }
    return false;
  };

  $scope.highlightText = function(text, search) {
    if (search && search.length === 0) {

      // Returns the default content.
      return $sce.trustAsHtml(text);
    }

    // Define a regular expression to find the text globally and ignoring capital letters.
    var regex = new RegExp(search, 'gi');

    // If you already found the text then inject a span element with CSS class to highlight that you found.
    return $sce.trustAsHtml(text.replace(regex, '<span class="foundText">$&</span>'));
  };
}]);
.foundText {
  background-color: #ff0;
  color: #f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.0/angular.min.js"></script>
<div ng-app="sample" ng-controller="sampleController">
  <div class="black">
    <input type="text" name="search" ng-model="search" placeholder="search" ng-click="didSelectLanguage()" />
  </div>
  <br>
  <br>
  <br>
  <table style="border: 1px solid black ;">
    <tbody>
      <tr>
        <td>
          <center><b>Question</b></center>
        </td>
        <td>
          <center><b>Response</b></center>
        </td>
      </tr>
      <tr ng-repeat="user in users | filter:searchFilter">
        <td style="border: 1px solid black ; width:30%;white-space: pre-wrap;" ng-bind-html="highlightText(user.gsx$topic.$t, search)">{{user.gsx$topic.$t}}</td>
        <td style="border: 1px solid black ; width:70%;white-space: pre-wrap;" ng-bind-html="highlightText(user.gsx$response.$t, search)">{{user.gsx$response.$t}}</td>
      </tr>
    </tbody>
  </table>
</div>

Надеюсь, это поможет!

0 голосов
/ 04 февраля 2020

Вы можете добавить <span> с highlighted классом. Убедитесь, что вы создали глубокую копию исходного массива. Я использовал JSON.parse(JSON.stringify(...)). Кроме того, поскольку мы добавляем <span> и хотим отобразить его как html, нам нужно использовать ng-bind-html. Для этого нам нужно добавить ngSanitize как модуль dependency.

angular.module('myApp', ['ngSanitize'])
  .controller('myController', ['$scope', ($scope) => {
    const content = [{
        question: 'Question 1',
        answer: 'Answer 1'
      },
      {
        question: 'Question 2',
        answer: 'Answer 2'
      }
    ];

    //create copy of the original array
    $scope.filteredContent = JSON.parse(JSON.stringify(content));

    $scope.highlight = () => {
      //create copy of the original array
      $scope.filteredContent = JSON.parse(JSON.stringify(content));

      $scope.filteredContent.forEach(fc => {
        const regEx = new RegExp($scope.searchText);

        fc.question = fc.question.replace(regEx, `<span class="highlight">${$scope.searchText}</span>`);
        fc.answer = fc.answer.replace(regEx, `<span class="highlight">${$scope.searchText}</span>`);
      });
    };
  }]);
table {
  border-collapse: collapse;
  margin-top: 10px;
  border: 1pt solid black;
  width: 100%;
}

td {
  border: 1pt solid black;
  margin: 0;
  padding: 0;
}

.highlight {
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.7.9/angular-sanitize.js"></script>

<div ng-app="myApp" ng-controller="myController">
  <input type="text" ng-model="searchText" ng-keyup="highlight()" placeholder="Search">

  <table>
    <tr ng-repeat="c in filteredContent">
      <td ng-bind-html="c.question">
      </td>
      <td ng-bind-html="c.answer">
      </td>
    </tr>
  </table>
</div>
...