3

I have a table with input from Flask, and some fields of the table have input boxes for the user. I am trying to get the value of what they input and I am struggling. I figure this is an easy question for people here, but I have been banging my head against my desk for a while now and searched the forums here without figuring out what I'm doing wrong.

I created a similar but much simpler HTML table to what I have for us to play around with. I have not been able to get to the radio button part yet because I'm still trying to get the input box part solved, but I will be needing to get both of those. Ideally, I'd be returning each row into a JSON array.

The JQuery I included returns "Cannot read property 'GetElementsByTagName' of undefined", but it's only one of the many examples I've tried without any success. I've tested variations with .value, .text, .innerHTML, but I just can't get what's inside the box (or the radio button value for that matter).

Any help for a JS novice?

//$('.tableRow').each(function() {
//  favoriteBeer = document.getElementsByClassName('favoriteBeer').document.GetElementsByTagName('input');
//  console.log(favoriteBeer);
//});
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Favorite Food</th>
      <th>Favorite Beer</th>
    </tr>
  </thead>
  <tbody>
    <tr class='tableRow'>
      <td>John</td>
      <td>30</td>
      <td><label><input type="radio" name="favoriteFood1" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood1" value="Tacos" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Joe</td>
      <td>25</td>
      <td><label><input type="radio" name="favoriteFood2" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood2" value="Tacos"/>Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Sam</td>
      <td>50</td>
      <td><label><input type="radio" name="favoriteFood3" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood3" value="Tacos"/>Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
  </tbody>
</table>

3 Answers 3

3

Use a for loop with the help of $(this) to get the related values of every row, and get the selected radio buttons using input:radio:checked as selector like :

$('button').click(function() {
  $('.tableRow').each(function() {
    var favoriteBeer = $(this).find('.favoriteBeer').val();
    var favoriteFood = $(this).find('input:radio:checked').val();

    var dataObj = {
      favoriteBeer: favoriteBeer,
      favoriteFood: favoriteFood
    };

    console.log(dataObj);
  });
})
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Favorite Food</th>
      <th>Favorite Beer</th>
    </tr>
  </thead>
  <tbody>
    <tr class='tableRow'>
      <td>John</td>
      <td>30</td>
      <td><label><input type="radio" name="favoriteFood1" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood1" value="Tacos" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Joe</td>
      <td>25</td>
      <td><label><input type="radio" name="favoriteFood2" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood2" value="Tacos"/>Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Sam</td>
      <td>50</td>
      <td><label><input type="radio" name="favoriteFood3" value="Pizza"/>Pizza</label><label><input type="radio" name="favoriteFood3" value="Tacos"/>Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
  </tbody>
</table>
<button type="button">Retrieve Data</button>

Sign up to request clarification or add additional context in comments.

5 Comments

This is a good answer, but for favorite food I am just getting "on" for each row instead of what is actually selected in the box?
If you could give the radio buttons a value, else I can adjust the script to return the label value?
I've just updated using the radio values Pizza/Tacos as your update shows.
That works perfectly. In case anyone else comes upon this, your answer got me 99% of the way there. But for some reason, in my real life case and not the example I provided here, I needed to use $(this).find('input:text').val(); for the textbox input. It maybe had something to do with that input pulling from Flask? I'm not sure why but that's the only difference I can think of! Thanks so much for your help and everyone else's. I got some great answers to this question.
It's really appreciated to return here and leave this information for future readers, the most of the authors leave when they got the right answers. Thanks for your collaboration and happy coding.
3

You can't call document.getElementsByTagName() on the results of .getElementsByClassName() because .getElementsByClassName() returns a "node list" and a node list doesn't have a document property. But you could do this:

favoriteBeer = document.getElementsByClassName('favoriteBeer').getElementsByTagName('input');

Because most DOM query methods can be called on document, a node, or a node list.

However, .getElementsByClassName() and .getElementsByTagName() both return "live" node lists, which means that every time you reference the variable that you've assigned the results to, the entire document must be re-scanned to ensure you get the most up-to-date results. This is only valuable when you have elements being created/destroyed dynamically. If you aren't working with that kind of code, the use of these methods is discouraged because they are very wasteful, in terms of performance.


Now, since you are using JQuery, you should use it consistently. Just pass a valid CSS selector into the JQuery object to scan the DOM for matching elements.

So, you can simply pass the class name into JQuery to obtain a set of references to your DOM objects and then get the value property of those input elements. But, you do have to wait to run that code until after the user has had a chance to enter some data. I've added a button element to your code which you can click when you are ready to see the input values.

$("button").on("click", function(){
  // Just passing a valid CSS selector to the JQuery object will
  // return a JQuery "wrapped set" of all matching elements.
  
  // Then, the .each() method takes a function that will automatically
  // be passed the index of the current element being iterated, a DOM reference
  // to the element itself, and a reference to the wrapped set (not used here).
  $('.favoriteBeer').each(function(index, element) {
   // You can use the element argument inside of the .each() loop
   // or you can use the "this" keyword to get the same DOM reference
   console.log(element.value, this.value);
  });
});
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Favorite Food</th>
      <th>Favorite Beer</th>
    </tr>
  </thead>
  <tbody>
    <tr class='tableRow'>
      <td>John</td>
      <td>30</td>
      <td><label><input type="radio" name="favoriteFood1"/>Pizza</label><label><input type="radio" name="favoriteFood1" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Joe</td>
      <td>25</td>
      <td><label><input type="radio" name="favoriteFood2"/>Pizza</label><label><input type="radio" name="favoriteFood2" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Sam</td>
      <td>50</td>
      <td><label><input type="radio" name="favoriteFood3"/>Pizza</label><label><input type="radio" name="favoriteFood3" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
  </tbody>
</table>
<button type="button">Get Data</button>

1 Comment

Thanks for the great explanation! That makes a lot of sense now that you say that.
1

You cannot run this line:

favoriteBeer = document.getElementsByClassName('favoriteBeer').document.GetElementsByTagName('input');

Because document of element .favoriteBeer is undefined.

Also, when $('.tableRow').each(function() runs, the input field is empty, as it runs as the page loaded. So what you can do instead is listen on the keyup event and check the current value of input every time the user types something.

Like so:

$('.favoriteBeer').keyup(function() {
  console.log($(this).val());
});
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Favorite Food</th>
      <th>Favorite Beer</th>
    </tr>
  </thead>
  <tbody>
    <tr class='tableRow'>
      <td>John</td>
      <td>30</td>
      <td><label><input type="radio" name="favoriteFood1"/>Pizza</label><label><input type="radio" name="favoriteFood1" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Joe</td>
      <td>25</td>
      <td><label><input type="radio" name="favoriteFood2"/>Pizza</label><label><input type="radio" name="favoriteFood2" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
    <tr class='tableRow'>
      <td>Sam</td>
      <td>50</td>
      <td><label><input type="radio" name="favoriteFood3"/>Pizza</label><label><input type="radio" name="favoriteFood3" />Tacos</label>
        <td><input type="text" class="favoriteBeer"></td>
    </tr>
  </tbody>
</table>

1 Comment

Thanks! I appreciate the explanation of why $('.tableRow').each(function() doesn't work! A lot of good answers here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.