I'm working on a college assignment where I use a PHP class to generate table values which a Javascript function then searches with a search bar. It builds off of a previous assignment that uses the same search bar to search an unordered list. It worked great for the list but it uses a function that was already supplied to me which, frankly, I don't know how it works. Now all it does, once I add a table row with more than one cell, is search the first cell. It still returns the whole row but I also need it to search the whole row.
It seems like a = tr[i].getElementsByTagName("a")[0];
only returns the first <a>
and this might be the problem, but I don't know how to go about fixing that in a was that doesn't break the function.
The function that's confusing me follows. I added my own code to it to hide the list/table which obviously I understand. I won't include that but that's why you don't see me close the function, just so you're not confused about that.
function myFunction() {
var input, filter, table, tr, a, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i ) {
a = tr[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
For reference, here is the multi-cell table row I added for testing, which is now giving me problems. I also include the actual search bar itself because it contains relevant syntax for explaining the functionality. There are other rows so the table closes later on.
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name"> <!--This is my search bar-->
<table id="myTable" onl oad="hideList()">
<tbody>
<tr id="1">
<?php
$pr0 = new productRow(0);
echo
"<td><a href=\"#\">" . $pr0->itemNumber . "</td></a>" .
"<td><a href=\"#\">" . $pr0->name . "</td></a>" .
"<td><a href=\"#\">" . $pr0->type . "</td></a>" . //These rows concatenate the class instances with the elements in which they are supposed to appear
"<td><a href=\"#\">" . $pr0->model . "</td></a>" .
"<td><a href=\"#\">" . $pr0->brand . "</td></a>" .
"<td><a href=\"#\">" . $pr0->description . "</td></a>";
?>
</tr>
And I'll include the PHP class just so you can see how it inputs things, but don't worry, it works.
<?php
class productRow {
var $itemNumber = [];
var $name = [];
var $type = [];
var $model = [];
var $brand = [];
var $description = [];
function __construct($i) { //receives argument when class is called with an argument
$this->itemNumber = $this->make_table_row($i)[0];
$this->name = $this->make_table_row($i)[1];
$this->type = $this->make_table_row($i)[2];
$this->model = $this->make_table_row($i)[3]; //This function allows the instance values of the attributes to be taken from the make_table_row function
$this->brand = $this->make_table_row($i)[4];
$this->description = $this->make_table_row($i)[5];
}
function make_table_row($i) { //receives argument when class is called with an argument
$row = 1;
$tablerows = [];
if (($input = fopen("input.csv", "r")) !== FALSE) { //gets the CSV with my table data
while (($tabledata = fgetcsv($input, 1000, ",")) !== FALSE) { //cycles through the rows of data creating arrays
if ($row == 1) {
$row ;
continue; //skips the first row because it's a header row I don't want on my input
}
$tablerows[] = $tabledata; //uses the roles to populate a multidimensional array
$row ;
}
fclose($input);
if (isset($tablerows[$i])) {
return $tablerows[$i]; //uses argument to return the appropriate array
}
}
}
}
?>
Can anyone shed some light on what is going on here and how I might get all of the <a>
elements without breaking the function?
CodePudding user response:
So I ended up figuring it out by myself. It turned out that because I didn't recognize some of the terminology on the MDN documentation, the documentation I was reading about the indexOf()
method was for different types of arguments. So a = tr[i].getElementsByTagName("a")[0];
was returning just the first tag of the row of its current iteration, the tag was used by txtValue
to return the string of textContent
or innerText
and txtValue.toUpperCase().indexOf(filter)
compares the uppercase of those strings to the uppercase value of the input with the argument filter
, toggling the if-else statement on the row of the current iteration to either hide or show the row.
I realized that tr[i]
, which came from table.getElementsByTagName("tr")
and would use the tag for the current iteration with [i]
locating it on the array, was just supplying a tag for the node which was being used by tr[i].getElementsByTagName("a")[0]
to get the row for the tag that was being returned there. So I realized if I just used tr[i]
on its own, it would give me the whole row instead of the first a
of the row. Worked like a charm.
function myFunction() {
var input, filter, table, tr, a, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i ) {
a = tr[i];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}