Javascript фильтр таблиц

113
17 января 2021, 12:10

В таблице есть столбец с адресами формата: "город" + "улица и дом". Значения в таблицу попадают из json файла. С перебором свойств объекта и добавлением адреса мне помогли здесь

Однако снова возникла проблема с этим же столбцом. Вопрос- как мне вывести по фильтру город список адресов в формате "город" + "улица и дом"

Для примера - в таблице есть города без адреса они выводятся, но города с адресом не будет выводится т.к. в

<option value="Moscow">Moscow</option>

Указан только город. Как сделать фильтр таблицы без учета полного значения строки? Чтобы при выборе Москва выводились все значения где есть Москва.

Прошу прощения за кровь из глаз.Я лишь учусь.

<!DOCTYPE html> 
<html> 
 
<head> 
  <title>TABLE FILTER</title> 
  <style> 
    body { 
      font-family: "Helvetica"; 
      font-size: medium; 
    } 
     
    table { 
      border-collapse: collapse; 
      text-align: center; 
      margin: auto; 
    } 
     
    table td, 
    table th { 
      border: solid 1px #aaa; 
      padding: 10px; 
    } 
     
    table tbody tr:nth-child(2n) { 
      background: #a8d7ff; 
    } 
     
    table tbody tr:hover { 
      background: #fffcb6; 
    } 
  </style> 
</head> 
 
<body> 
 
  <h1>Фильтр данных в таблицах.</h1> 
 
  <table> 
    <thead> 
      <tr> 
        <th>Символы</th> 
        <th>Текст</th> 
        <th>Город</th> 
        <th>Цифры</th> 
        <th>Текст</th> 
      </tr> 
      <tr> 
        <td> 
          <input type="checkbox" id="charA" value="A" />A 
          <input type="checkbox" id="charB" value="B" />B 
          <input type="checkbox" id="charC" value="C" />C 
        </td> 
        <td> 
          <input id="text" /> 
        </td> 
        <td> 
          <select id="digits"> 
            <option value="">---</option> 
            <option value="Москва">Москва</option> 
            <option value="Ташкент">Ташкент</option> 
            <option value="СПб">СПб</option> 
          </select> 
        </td> 
        <td> 
          <input type="radio" name="digit" id="radioZ" value="" checked="true" />- 
          <input type="radio" name="digit" id="radioA" value="1" />1 
          <input type="radio" name="digit" id="radioB" value="2" />2 
          <input type="radio" name="digit" id="radioC" value="3" />3 
        </td> 
        <td> 
          <input id="regexp" /> 
        </td> 
      </tr> 
    </thead> 
    <tbody id="target"> 
      <tr> 
        <td>B</td> 
        <td>Арбуз</td> 
        <td>Москва</td> 
        <td>3</td> 
        <td>Фанат</td> 
      </tr> 
      <tr> 
        <td>B</td> 
        <td>Стрелок</td> 
        <td>Москва</td> 
        <td>2</td> 
        <td>Арба</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Фанат</td> 
        <td>СПб Ленина 12</td> 
        <td>1</td> 
        <td>Стрелок</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Стрелок</td> 
        <td>Ташкент Бабура 21</td> 
        <td>1</td> 
        <td>Фантомас</td> 
      </tr> 
      <tr> 
        <td>B</td> 
        <td>Стрелок</td> 
        <td>Москва Жукова 1</td> 
        <td>2</td> 
        <td>Арбуз</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Фанат</td> 
        <td>Ташкент</td> 
        <td>3</td> 
        <td>Стрелок</td> 
      </tr> 
      <tr> 
        <td>A</td> 
        <td>Арбуз</td> 
        <td>СПб</td> 
        <td>2</td> 
        <td>Арбуз</td> 
      </tr> 
      <tr> 
        <td>A</td> 
        <td>Фанат</td> 
        <td>Ташкент</td> 
        <td>1</td> 
        <td>Стрелочник</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Фанат</td> 
        <td>СПб Королёва 122</td> 
        <td>3</td> 
        <td>Арбуз</td> 
      </tr> 
      <tr> 
        <td>B</td> 
        <td>Фанат</td> 
        <td>Ташкент Ленина 111</td> 
        <td>3</td> 
        <td>Фантик</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Стрелок</td> 
        <td>Ташкент</td> 
        <td>1</td> 
        <td>Арбуз</td> 
      </tr> 
      <tr> 
        <td>C</td> 
        <td>Фанат</td> 
        <td>Москва</td> 
        <td>2</td> 
        <td>Стрелка</td> 
      </tr> 
    </tbody> 
  </table> 
 
  <script> /** 
 * Created by Komarov Artem on 11.08.14. 
 */ 
 
/** 
 * Привязать фильтры к таблице. 
 * @param HTMLTableSectionElement HTMLTBodyRef - ссылка на элемент &lt;tbody&gt; таблицы 
 * @param Object filters - объект-конфигурация фильтров: { N : FILTER[, N : FILTER] } 
 * 
 *  Где: 
 *      NUM - это натуральное число - номер столбца таблицы, обслуживаемого 
 *          фильтром. Этот номер может принимать значения от 0 до кол-во 
 *          столбцов таблицы - 1. Номера можно задавать не по порядку. 
 * 
 *      FILTER - это ссылка на HTML-элемент представляющий собой элемент 
 *          HTML-формы и имеющий атрибут value (select в том числе), либо 
 *          объект типа tableKit.Filter 
 */ 
var filterTable = function (HTMLTBodyRef, aFilters) { 
    var rows = HTMLTBodyRef.getElementsByTagName("TR"), 
        filters = {}, n, 
        walkThrough = function (rows) { 
            var tr, i, f; 
            for (i = 0; i < rows.length; i += 1) { 
                tr = rows.item(i); 
                for(f in filters) { 
                    if (filters.hasOwnProperty(f)) { 
                        if (false === filters[f].validate(tr.children[f].innerText) ) { 
                            tr.style.display = "none"; break; 
                        } else { 
                            tr.style.display = ""; 
                        } 
                    } 
                } 
            } 
        }; 
    for(n in aFilters) { 
        if (aFilters.hasOwnProperty(n)) { 
            if (aFilters[n] instanceof filterTable.Filter) { 
                filters[n] = aFilters[n]; 
            } else { 
                filters[n] = new filterTable.Filter(aFilters[n]); 
            } 
            filters[n]._setAction("onchange", function () {walkThrough(rows);}); 
        } 
    } 
} 
 
/** 
 * Объект фильтр. 
 * @param HTMLInputElement | HTMLSelect HTMLElementRef | [] - Ссылка или массив ссылок 
 *                 на html-элементы, служащие фильтрами. 
 * @param Function callback - ф-ция обратного вызова. Вызывается когда скрипт 
 * производит валидацию содержимого ячейки. Ф-ция вызывается для каждой строки таблицы, для 
 * каждой ячейки столбца, для которого назначен фильтр. 
 * Функции будут переданы 3 параметра: callback(value, filters, i) где: 
 *      String value - значение ячейки таблицы, проверяемой на момент вызова ф-ции 
 *      HTMLElements[] filters - массив HTML-элементов назначенных фильтрами для проверяемого столбца. 
 *      Number i - индекс элемента фильтра в массиве filters который является 
 *                 валидатором для текущего вызова. Т.е. filters[i] внутри ф-ции 
 *                 обратного вызова будет содержать элемент, с которым провзаимодействовал 
 *                 пользователь, в результате чего был запущен процесс валидации. 
 * @param String eventName - название события привязанного к фильтру, по которому будет 
 *      запускаться валидация (onkeyup | onclick | onblur | onchange и т.п.) 
 * @constructor 
 */ 
filterTable.Filter = function (HTMLElementRef, callback, eventName) { 
    /* Если ф-цию вызвали не как конструктор фиксим этот момент: */ 
    if (!(this instanceof arguments.callee)) { 
        return new arguments.callee(HTMLElementRef, callback, eventName); 
    } 
 
    /* Выравниваем пришедший аргумент к массиву */ 
    this.filters = {}.toString.call(HTMLElementRef) == "[object Array]" ? HTMLElementRef : [HTMLElementRef]; 
 
    /** 
     * Шаблонный метод вызывается для каждой строки таблицы, для соответствующей 
     * ячейки. Номер ячейки задается в объекте-конфигурации фильтров ф-ции 
     * filterTable (См. параметр 2 ф-ции tableFilter ) 
     * @param String cellValue - строковое значение ячейки 
     * @returns {boolean} 
     */ 
    this.validate = function (cellValue) { 
        for (var i = 0; i < this.filters.length; i += 1) { 
            if ( false === this.__validate(cellValue, this.filters[i], i) ) { 
                return false; 
            } 
        } 
    } 
 
    this.__validate = function (cellValue, filter, i) { 
        /* Если фильтр был создан явно и явно указана функция валидации: */ 
        if (typeof callback !== "undefined") { 
            return callback(cellValue, this.filters, i); 
        } 
        /* Если в фильтр напихали пробелов или другой непечатной фигни - удаляем: */ 
        filter.value = filter.value.replace(/^\s+$/g, ""); 
        /* "Фильтр содержит значение и оно совпало со значением ячейки" */ 
        return !filter.value || filter.value == cellValue; 
    } 
 
    this._setAction = function (anEventName, callback) { 
        for (var i = 0; i < this.filters.length; i += 1) { 
            this.filters[i][eventName||anEventName] = callback; 
        } 
    } 
}; 
</script> 
  <script> 
    filterTable(document.getElementById("target"), { 
      /* Фильтр для первого столбца чекбоксы: */ 
      0: new filterTable.Filter([ /* Элементы фильтра */ 
          document.getElementById("charA"), 
          document.getElementById("charB"), 
          document.getElementById("charC") 
        ], 
        /* Коллбэк ф-ция валидации */ 
        function(value, filters, i) { 
          /* Если чекбокс не отмечен - его значение не учавствует 
             в валидации поэтому мы обязаны вернуть true */ 
          if (false === filters[i].checked) return true; 
          /* Далее, при проверке, мы должны одновременно проверять 
             значения всех элементов набора при условии чекбокс 
             отмечен */ 
          return filters[0].checked && filters[0].value === value || 
            filters[1].checked && filters[1].value === value || 
            filters[2].checked && filters[2].value === value; 
        } 
      ), 
 
      /* Фильтр для второго столбца текстовое поле - только точное совпадение: */ 
      1: document.getElementById("text"), 
 
      /* Фильтр для третьего столбца выпадающий список: */ 
      2: document.getElementById("digits"), 
 
      /* Фильтр для четвертого столбца радио кнопки: */ 
      3: new filterTable.Filter([ /* Элеменеты фильтра */ 
          document.getElementById("radioZ"), 
          document.getElementById("radioA"), 
          document.getElementById("radioB"), 
          document.getElementById("radioC") 
        ], 
        /* Коллбэк ф-ция валидации */ 
        function(value, filters, i) { 
          /* В filters[0] - у нас радио кнопка "Не выбрано", если она 
             установлена фильтр не участвует в валидации и мы 
             обязаны вернуть true */ 
          if (true === filters[0].checked) return true; 
          /* Если какая то радиокнопка отмечена и содержимое проверяемой 
            ячейки совпало то вернем true */ 
          return filters[1].checked && filters[1].value === value || 
            filters[2].checked && filters[2].value === value || 
            filters[3].checked && filters[3].value === value; 
        } 
      ), 
 
      /* Фильтр для пятого столбца Постепенный ввод слова: */ 
      4: new filterTable.Filter(document.getElementById("regexp"), 
        /* Коллбэк ф-ция валидации */ 
        function(value, filters, i) { 
          return value.indexOf(filters[i].value) === 0; 
        }, 
        /* Будем вызывать валидацию по событию onkeyup фильтра */ 
        "onkeyup" 
      ) 
    }); 
  </script> 
 
</body> 
 
</html>

Answer 1

Кажется нашёл решение

str.match(reg) с флагом g
READ ALSO
Склеивание полигонов в Yandex API

Склеивание полигонов в Yandex API

В Yandex APi JS допустим когда сначала рисуешь один полигон затем рядом еще один полигон предусматривается автоматическое "cклеивание" границ...

91
Как добавить пробел посередине числа?

Как добавить пробел посередине числа?

Вот мой пример реализации данной задачи, но он не работаетНа выходе у меня получается 123456, а должно получиться 123 456

201
router.push() vuejs не отправляет на главную

router.push() vuejs не отправляет на главную

Есть сайт, есть два разных типа пользователей, для одних используется /login /register, для других /profile/login /profile/register

84
Неверная передача параметра в метод [закрыт]

Неверная передача параметра в метод [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

86