Попытка скрыть строку на основе значения определенного столбца (теоретически должно быть легко …)

#javascript #html #css #dom

#javascript #HTML #css #dom

Вопрос:

То, что должно быть очень простой проблемой, заставило меня застрять на пару дней, и, как обычно, хотя есть много похожих вопросов, точного соответствия нет (возможно, потому, что я использую элементы для создания таблицы, а не ).

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

Идея заключается в том, что затем функция скрывает все строки таблицы, которые не имеют этого идентификатора рынка, в столбце Идентификатор рынка. Достаточно просто!

Однако по какой-то причине я, похоже, не могу этого сделать, поскольку постоянно получаю ошибки типа.

Я попытался найти дочерние узлы и попытаться получить родительский, а также обратный, но пока безуспешно.

Мне не нужно использовать этот подход, если я могу скрыть все строки, которые не содержат market id, когда он передается в функцию, это было бы прекрасно.

Однако у меня закончились идеи, поэтому любая помощь приветствуется!

Я пробовал несколько подходов (например, родительский узел, дочерний узел, дочерние элементы и т.д.), Однако я всегда получаю ошибку, аналогичную приведенной ниже.

Вот HTML:

 <div class="divTable blueTable" id="bluetable">
<div class="divTableHeading" id="blue_table_head">
<div class="divTableRow" id="header_row">
<div class="divTableHead">Selection Name</div>
<div class="divTableHead">Selection ID</div>
<div class="divTableHead">Market ID</div>
</div>
</div>
<div class="divTableBody" id="blue_table_body">
<div class="divTableRow" id="blue_table_row_0">
<div class="divTableCell"><div>Selection A</div></div>
<div class="divTableCell"><div>1136035</div></div>
<div class="divTableCell"><div class="1.15">1.15</div></div>
</div>
<div class="divTableRow" id="blue_table_row_1">
<div class="divTableCell"><div>Selection B</div></div>
<div class="divTableCell"><div>11148977</div></div>
<div class="divTableCell"><div class="1.15">1.15</div></div>
</div>
<div class="divTableRow" id="blue_table_row_2">
<div class="divTableCell"><div>Selection C</div></div>
<div class="divTableCell"><div>4519440</div></div>
<div class="divTableCell"><div class="1.15">1.15</div></div>
</div>
<div class="divTableRow" id="blue_table_row_3">
<div class="divTableCell"><div>Selection D</div></div>
<div class="divTableCell"><div>10974022</div></div>
<div class="divTableCell"><div class="1.16">1.16</div></div>
</div>
<div class="divTableRow" id="blue_table_row_4">
<div class="divTableCell"><div>Selection E</div></div>
<div class="divTableCell"><div>1136034</div></div>
<div class="divTableCell"><div class="1.17">1.17</div></div>
</div>
</div>
</div> 
  

Вот функция Javascript:

 function btn_click($button_id) {

var list = document.getElementsByClassName("divTableRow");

    for (a = 2; a < list.length; a  ) {

        var b = list[a];
        var c = b.getElementsByClassName($button_id);
        var d = c.parentNode.nodeName;
        console.log(d);

    }

}
  

Ошибка, которую я получаю, это:

 Uncaught TypeError: Cannot read property 'nodeName' of undefined
  

Однако, если я просто посмотрю в журнале ‘c’ (т. Е. console.log(c)) Я вижу, что идентификатор из $ button_id правильно возвращает связанный класс.

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

Комментарии:

1. getElementsByClassName() возвращает набор элементов, которые вам нужно просмотреть developer.mozilla.org/en-US/docs/Web/API/Document /…

2. Попробуйте с getElementById или c[0].parentNode.nodeName;

3. Пытаясь использовать этот подход, я все еще получаю ошибку следующим образом: Uncaught TypeError: Cannot read property 'nodeName' of undefined Я добавил в цикл, показанный в теме ниже (я не буду повторно публиковать, чтобы избежать путаницы), который возвращает ту же ошибку.

Ответ №1:

Как прокомментировал Funk Doc, проблема в том, что вы используете

 var c = b.getElementsByClassName($button_id);
  

Который возвращает массив элементов.

Исправление: если вы хотите использовать все эти элементы, выполните цикл по ним, например:

 var c = b.getElementsByClassName($button_id);
for(var i = 0; i < c.length; i  ) {
  var e = c[i].parentNode.parentNode.id;
  //whatever you want to do next
}
  

Интересно, однако, что использование цикла foreach (например for(var i in c) {...} ) вместо этого вызывает TypeError .

Но если вы ожидаете, что там будет только один элемент, используйте

 var c = b.getElementsByClassName($button_id)[0];
  

Комментарии:

1. Сначала я попробовал вторую петлю, но отказался от нее, ха! Я добавил его обратно, как вы предложили, но я все еще получаю ошибку. Вот код: function btn_click($button_id) { var list = document.getElementsByClassName("divTableRow"); for (a = 2; a < list.length; a ) { var b = list[a]; var c = b.getElementsByClassName($button_id); for (d in c) { var e = c[d].parentNode.nodeName; console.log(e); } } } Вот ошибка: Uncaught TypeError: Cannot read property 'nodeName' of undefined

2. В цикле вида for(d in c) d является элементом c, а не индексом!

3. Итак, внутри цикла, вместо использования var e = c[d].parentNode.nodeName; , вы должны сделать var e = d.parentNode.nodeName;

4. к сожалению, это возвращает точно такую же ошибку:-(

5. Хм .. попробуйте консольное ведение журнала d внутри цикла. Что вы получаете?

Ответ №2:

Попробуйте эту функцию:

 function btn_click($button_id) {
    // get all table rows
    var rows = document.querySelectorAll('.divTableBody .divTableRow');

    // loop through the rows
    for (var i = 0; i < rows.length; i  ) {
        // check if row has no descendant div with class = $button_id
        if (!rows[i].querySelector('div[class="divTableCell"] div[class="'   $button_id   '"]')) {
            // hide row if condition is true
            rows[i].style.display = 'none';
        }
    }
}
  

Комментарии:

1. Спасибо, это действительно работает, хотя мне нужно будет добавить еще один шаг, так как, хотя при первом нажатии он возвращает строки, как ожидалось, я не упоминал, что он должен работать при бесконечном количестве нажатий кнопок. Это не возвращает никаких строк для последующих нажатий кнопок, поэтому мне нужно будет немного подправить его.

2. Я вижу. Я думал, вы хотите скрыть все строки таблицы, у которых нет $button_id. В любом случае, я надеюсь, что это будет полезно для вас. Мне всегда проще использовать querySelector для поиска вложенных элементов, потому что он принимает любой допустимый CSS-селектор в качестве параметра.

3. Да, извините за мою ошибку, мое первоначальное описание было не очень ясным в этой части, но не волнуйтесь, ваш ответ все еще полезен, поскольку я должен иметь возможность поиграть с ним, чтобы получить то, что мне нужно.

Ответ №3:

На всякий случай, если это кому-то еще пригодится, вот окончательный код:

 
function btn_click($button_id) {

var list = document.getElementsByClassName("divTableRow");

    for (a = 2; a < list.length; a  ) {

        var b = list[a];
        b.style.display = 'none';
        var c = b.getElementsByClassName($button_id);

            for(var i = 0; i < c.length; i  ) { 
                var e = c[i].parentNode.parentNode.id;
                document.getElementById(e).style.display = 'table-row';

            }

    }

}