2

So, I have a JSP page that's attached to a list of objects I need to loop through using a JSTL loop. (This is a Tiles project and the controller is setting up some mock objects which are being added to and returned as a list. That bit works fine.) Basically, I want it to display a name, a value, and a button all in a row, and when the button is clicked, I want the rest of the info to pop down.

 <c:forEach var="i" varStatus="curr" items="${items}">
    <tr>
            <td>
                ${i.itemName}
            </td>
             <td>
                ${i.itemValue}
            </td>
             <td style="float:right;">
            <input type="button" id="showhide">
            </td>
     </tr>
     <tr>
        <td class="toggle">
            ${i.itemAltName}
            ${i.itemAdditions}
            ${i.itemValueAfterAdditions}
        </td>
    </tr>   
</c:forEach>

I'm using the following JS.

<script type="text/javascript">
        var buttons = document.getElementById('showhide');

        buttons.onclick = function() {
            var div = document.getElementsByClassName('toggle');
            var x = div.length;
            for(var i = 0; i < x; ++i){
                if (div[i].style.display !== 'none') {
                    div[i].style.display = 'none';
                }
                else {
                    div[i].style.display = 'block';
                }
            }
        };
</script>

Also, stating the obvious here, but my style area has:

.toggle{
display:none;
}

Currently, only the first button opens the corresponding text properly. From other answers I've seen, I know I need to make the ID unique, but I'm not sure how to do that with the JSP loop. Help?

Terry
  • 23
  • 4
  • 1
    Possible duplicate of [How to get a index value from foreach loop in jstl](https://stackoverflow.com/questions/18825950/how-to-get-a-index-value-from-foreach-loop-in-jstl) – Jozef Chocholacek Oct 26 '17 at 14:16

1 Answers1

1

A different approach compared to the other answer, using the varStatus (suggested by Jozef Chocholacek) to get unique IDs.

That would allow you to have a solution working no matter where the button and the linked td are (they don't have to be siblings).

Your JSP :

 <c:forEach var="i" varStatus="curr" items="${items}" varStatus="loop">
    <tr>
            <td>
                ${i.itemName}
            </td>
             <td>
                ${i.itemValue}
            </td>
             <td style="float:right;">
            <input type="button" class="showhide" id="showHideButton_${loop.index}">
            </td>
     </tr>
     <tr>
        <td class="toggle" id="data_${loop.index}">
            ${i.itemAltName}
            ${i.itemAdditions}
            ${i.itemValueAfterAdditions}
        </td>
    </tr>   
</c:forEach>

Use the JS in the snippet below :

var buttons = document.getElementsByClassName('showhide');

for (var i=0;i<buttons.length;i++) {
 buttons[i].addEventListener("click", clickHandler);

}

function clickHandler(event) {
 var buttonId = event.target.id; 
 var rowId = buttonId.split("_")[1];
 var rowData = document.getElementById('data_' + rowId);
 
 // do whatever you want with your row 
 if (rowData.style.display !== 'none') {
  rowData.style.display = 'none';
 } else {
  rowData.style.display = 'block';
 }
}
<table>
  <tr>
   <td>Name</td>
   <td>Value</td>
   <td>Action</td>
  </tr> 
     <tr>
            <td>
                Item Name 1
            </td>
             <td>
                Item Value 1
            </td>
             <td style="float:right;">
    <input type="button" class="showhide" id="showHideButton_98" value="Toggle">
            </td>
     </tr>
     <tr>
        <td class="toggle" id="data_98">
            itemAltName1
            itemAdditions1
            itemValueAfterAdditions1 
        </td>
    </tr> 
    <tr>
            <td>
                Item Name 2
            </td>
             <td>
                Item Value 2
            </td>
             <td style="float:right;">
    <input type="button" class="showhide" id="showHideButton_55" value="Toggle">
            </td>
     </tr>
     <tr>
        <td class="toggle" id="data_55">
            itemAltName2
            itemAdditions2
            itemValueAfterAdditions2 
        </td>
    </tr>
Guillaume Georges
  • 3,878
  • 3
  • 14
  • 32