ReactTable (ReactJS) — фильтрация поиска в строке с содержимым HTML не работает

Я использую РеактТаблица и показываю данные из массива (массив URL-адресов сайта) в виде HTML с реальными ссылками.

К сожалению, фильтрация поиска в этом столбце не работает, когда я использую HTML в ячейке. Это мой код для этого столбца:

{
Header: 'URL',
accessor: 'url',
Cell: row => <div>{this.displayCellData(row.value, 'url')}</div>
}

DisplayCellData — это моя функция, которая преобразует массив URL-адресов в строку HTML с форматированными тегами. строка.значение содержит массив URL-адресов, например ['http://google.com', 'http://yahoo.com/', ...].

Как я могу изменить этот код, чтобы фильтрация для этого столбца работала нормально? Я пробовал код, подобный этому, для преобразования массива в строку в методе доступа, чтобы сделать его доступным для поиска, но он не работает:

{
id: 'url',
Header: 'URL',
accessor: row => row.url.toString(),
Cell: row => <div>{this.displayCellData(row.value, 'url')}</div>
}

ДОБАВЛЕНА SANDBOX для теста:

https://codesandbox.io/s/flamboyant-mountain-ezxmy (попробуйте выполнить поиск в столбце)

Можете показать код таблицы/логику фильтра?

stever 08.07.2019 20:40

Вкратце - просто обычная таблица (вы можете использовать любую типовую таблицу для теста с некоторыми данными в формате HTML в столбце), код инициализации:

Dmitry 08.07.2019 20:43

<ReactTable data = {this.props.data} columns = {columns} фильтруемые />

Dmitry 08.07.2019 20:43

Проверьте песочницу здесь и попробуйте выполнить поиск: codeandbox.io/s/яркая-гора-ezxmy.

Dmitry 08.07.2019 20:51
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
4
1 840
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

https://codesandbox.io/s/реверент-банах-9l31m

Вы можете перезаписать defaultFilterMethod, чтобы настроить поведение фильтра.

<div className = "App">
  <ReactTable
    data = {data}
    columns = {columns}
    filterable
    defaultFilterMethod = {(filter, row) => { return row[filter.id].indexOf( filter.value ) > -1; }}
  />
</div>

Когда вы сейчас наберете http://google.com, он отфильтрует все, кроме первой строки, на основе точного совпадения. Если вам нужна другая логика фильтра, не стесняйтесь редактировать файл defaultFilterMethod. В настоящее время он работает с точными совпадениями. Просто не забудьте вернуть значение boolean.

Ответ принят как подходящий

Вы можете изменить defaultFilterMethod, как упоминал @arnonuem. Но я бы предложил реализовать его с помощью filterMethod на уровне столбца.

  const columns = [
    {
      Header: "URL",
      accessor: "url",
      Cell: row => <div>{displayCellData(row.value)}</div>,
      filterMethod: (filter, row) => {
        return row.url.indexOf(filter.value) >=0;
      }
    }
  ];

Если вы хотите выполнить поиск, содержащийся в массиве, вы можете использовать что-то вроде ниже

  const columns = [
    {
      Header: "URL",
      accessor: "url",
      Cell: row => <div>{displayCellData(row.value)}</div>,
      filterMethod: (filter, row) => {
        return row.url.findIndex(item => item.indexOf(filter.value) >= 0) >= 0;
      }
    }
  ];

Обновленная песочница ниже

https://codesandbox.io/s/interesting-rubin-thdwn

Спасибо большое. Ваше решение ясно, и ваш второй код работает нормально!

Dmitry 11.07.2019 10:15

Еще один вопрос - как мне изменить return row.url.findIndex(item => item.indexOf(filter.value) >= 0) >= 0; код, поэтому он все равно будет работать, если row.url не является массивом, а только одной строкой (один URL-адрес вместо массива URL-адресов)?

Dmitry 12.07.2019 11:30

Вы можете проверить, является ли row.url строкой или массивом. > Array.isArray("aa") false или Array.isArray(["aa"]) true

Tarun Lalwani 12.07.2019 11:32

Добавьте пользовательский метод фильтра в соответствующий столбец, например:

filterMethod: (filter, row) => {
   if (row.url.findIndex(element => element.includes(filter.value)) > -1) {
      return true;
   }
   return false;
}

вы можете использовать метод find в своих реквизитах defaultFilterMethod с функцией includes:

import React from "react";
import ReactDOM from "react-dom";
import "react-table/react-table.css";
import ReactTable from "react-table";

import "./styles.css";

function App() {
  const data = [
    {
      url: ["http://google.com", "http://yahoo.com/", "http://ggg.com"]
    },
    {
      url: ["http://xgoogle.com", "http://zyahoo.com/", "http://xggg.com"]
    }
  ];
  const columns = [
    {
      Header: "URL",
      accessor: "url",
      Cell: row =>
        row.row.url.map((url, key) => (
          <div>
            <a href = {url} key = {key} target = "_blank" rel = "noopener noreferrer">
              {url}
            </a>
          </div>
        ))
    }
  ];
  return (
    <div className = "App">
      <ReactTable
        data = {data}
        columns = {columns}
        filterable
        defaultFilterMethod = {(filter, row) => {

            return row[filter.id].find(el => el.includes(filter.value));
          }
        }
      />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Другие вопросы по теме