1

I'm creating a web app using Java servlets and JSP. I have a table which contains songs. Every song has its own checkbox and drop-down. like this:

table

You can see that taken songs have their checkbox and drop-down disabled and that's how I want it.

What I want is when the page loads all the drop-downs will be disabled, and when I check one of the available checkboxes the drop-down that is in the same line will be enabled and when I uncheck that checkbox the dropdown will be disabled again.

Here is the JSP code:

<table id="myTable"> 
    <tr>
    <th>Songs</th>
    <th>Selected</th>
    <th>#</th>
    <th>Available/Taken</th>
    </tr>
    <c:forEach items="${Entities}" varStatus="loop">
        <tr>
        <td><c:out value="${Entities[loop.index]}"/></td>               
        <td><input id="checkbox1" type="checkbox" name="selected" value=" ${Entities[loop.index]}" ${checkboxDis[loop.index]} ><br></td>
        <td>
            <select name="myselect" id="drop" disabled >
                <option selected disabled>#</option>
                <option>Cmaj</option><option>Gmaj</option>
                <option>Dmaj</option><option>Amaj</option>
                <option>Emaj</option><option>Bmaj</option>
                <option>Fmaj</option><option>Bb_maj</option>
                <option>Eb_maj</option><option>Ab_maj</option>
                <option>Db_maj</option><option>Gb_maj</option>
                <option>Amin</option><option>Emin</option>
                <option>Bmin</option><option>F#min</option>
                <option>C#_min</option><option>G#_min</option>
                <option>D#_min</option><option>Cb_maj</option>
                <option>Gmaj</option><option>Dmaj</option>
                <option>F#maj</option><option>Cmaj</option>
                <option>Fmaj</option><option>Bb_maj</option>
                <option>Eb_maj</option><option>Ab_maj</option>
                <option>Db_maj</option><option>A#</option>
            </select>
        </td>
        <td>
        <c:choose>
        <c:when test="${checkboxDis[loop.index].equals('disabled')}">
            <i class="fa fa-ban" style="color:red;"></i>
        </c:when>
        <c:when test="${checkboxDis[loop.index].equals('')}">
            <i class="fa fa-check-circle" style="color:green;"></i>
        </c:when>
        </c:choose>
        </td>
        </tr>   
    </c:forEach>
</table>

The jQuery code I've done so far:

var selected1 = new Array();

$(document).ready(function() {
  $("input[type='checkbox']").on('change', function() {
    if ($(this).is(":checked")) {
      selected1.push($(this).val());
      for (var i = 0; i < selected1.length; i++) {
        if (selected1[i] == $(this).val()) {
          $('#drop')[i].prop("disabled", false);
        }
      }
    } else {
      for (var i = 0; i < selected1.length; i++) {
        if (selected1[i] == $(this).val()) {
          selected1.splice(i, 1);
          $('#drop')[i].prop("disabled", true);
        }
      }
    }
  });
});

The code isn't working because I don't know how to handle the drop-downs since they have the same names and ids.

timos222
  • 48
  • 1
  • 9
  • 2
    "since they have the same names and ids" - same IDs is not something you want to have in your HTML ever. Either give each line dropdown an unique ID or drop those IDs completely. – Danmoreng Jun 14 '18 at 14:52
  • Related: https://stackoverflow.com/questions/9454645/does-id-have-to-be-unique-in-the-whole-page – Taplar Jun 14 '18 at 14:56
  • 1
    Please add the JSP code as text instead of an image, so I can copy paste it and show you how to make unique IDs for your dropdowns. – Danmoreng Jun 14 '18 at 14:56
  • 1
    Rather than using a distinct id I would suggest changing it to a class. Contextually there would be one drop class per row. – Taplar Jun 14 '18 at 14:57
  • @Taplar not even necessary. jQuery can navigate to a sibling cell easily – mplungjan Jun 14 '18 at 14:58
  • True, however the inclusion of the class can allow you to potentially remove positional based logic, which is inheriently fragile. – Taplar Jun 14 '18 at 14:59
  • @Danmoreng done. – timos222 Jun 14 '18 at 15:02
  • I removed "dynamically created" because they are not. They all exist in the page when it reaches the browser – mplungjan Jun 14 '18 at 17:01

2 Answers2

3

Your IDs need to be unique - in this case not needed at all for enabling the select

$(function() {
  $("input[type='checkbox']").on('change', function() {
    $(this).closest("tr").find("select[name=myselect]").prop("disabled", !this.checked)
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td><input id="checkbox_1" type="checkbox" name="selected" value="1"></td>
    <td>
      <select name="myselect" id="drop_1" disabled>
        <option selected disabled>#</option>
        <option>Cmaj</option>
        <option>Gmaj</option>
        <option>Dmaj</option>
        <option>Amaj</option>
        <option>Emaj</option>
        <option>Bmaj</option>
        <option>Fmaj</option>
        <option>Bb_maj</option>
        <option>Eb_maj</option>
        <option>Ab_maj</option>
        <option>Db_maj</option>
        <option>Gb_maj</option>
        <option>Amin</option>
        <option>Emin</option>
        <option>Bmin</option>
        <option>F#min</option>
        <option>C#_min</option>
        <option>G#_min</option>
        <option>D#_min</option>
        <option>Cb_maj</option>
        <option>Gmaj</option>
        <option>Dmaj</option>
        <option>F#maj</option>
        <option>Cmaj</option>
        <option>Fmaj</option>
        <option>Bb_maj</option>
        <option>Eb_maj</option>
        <option>Ab_maj</option>
        <option>Db_maj</option>
        <option>A#</option>
      </select>
    </td>
  </tr>
  <tr>
    <td><input id="checkbox_2" type="checkbox" name="selected" value="2"></td>
    <td>
      <select name="myselect" id="drop_2" disabled>
        <option selected disabled>#</option>
        <option>Cmaj</option>
        <option>Gmaj</option>
        <option>Dmaj</option>
        <option>Amaj</option>
        <option>Emaj</option>
        <option>Bmaj</option>
        <option>Fmaj</option>
        <option>Bb_maj</option>
        <option>Eb_maj</option>
        <option>Ab_maj</option>
        <option>Db_maj</option>
        <option>Gb_maj</option>
        <option>Amin</option>
        <option>Emin</option>
        <option>Bmin</option>
        <option>F#min</option>
        <option>C#_min</option>
        <option>G#_min</option>
        <option>D#_min</option>
        <option>Cb_maj</option>
        <option>Gmaj</option>
        <option>Dmaj</option>
        <option>F#maj</option>
        <option>Cmaj</option>
        <option>Fmaj</option>
        <option>Bb_maj</option>
        <option>Eb_maj</option>
        <option>Ab_maj</option>
        <option>Db_maj</option>
        <option>A#</option>
      </select>
    </td>
  </tr>
  </table>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-1

Change your JSP to this:

        <td><input id="checkbox_${checkboxDis[loop.index]}" type="checkbox" name="selected" value="${Entities[loop.index]}"><br></td>
        <td>
            <select name="myselect" id="drop_${checkboxDis[loop.index]}" disabled >
                <option selected disabled>#</option>
                <option>Cmaj</option><option>Gmaj</option>
                <option>Dmaj</option><option>Amaj</option>
                <option>Emaj</option><option>Bmaj</option>
                <option>Fmaj</option><option>Bb_maj</option>
                <option>Eb_maj</option><option>Ab_maj</option>
                <option>Db_maj</option><option>Gb_maj</option>
                <option>Amin</option><option>Emin</option>
                <option>Bmin</option><option>F#min</option>
                <option>C#_min</option><option>G#_min</option>
                <option>D#_min</option><option>Cb_maj</option>
                <option>Gmaj</option><option>Dmaj</option>
                <option>F#maj</option><option>Cmaj</option>
                <option>Fmaj</option><option>Bb_maj</option>
                <option>Eb_maj</option><option>Ab_maj</option>
                <option>Db_maj</option><option>A#</option>
            </select>
        </td>

Now your checkboxes and dropdowns have corresponding IDs which you can then use with jQuery:

var selected1 = new Array();

$(document).ready(function() {
  $("input[type='checkbox']").on('change', function() {
    if ($(this).is(":checked")) {
      selected1.push($(this).val());
      $('#drop_' + $(this).val()).prop("disabled", false);
    } else {
      $('#drop_' + $(this).val()).prop("disabled", true);
      // Instead of a for-loop for removing the unchecked song,
      // you can also use Array.filter():
      selected1 = selected1.filter(song_id => song_id !== $(this).val());
      /*
      for (var i = 0; i < selected1.length; i++) {
        if (selected1[i] == $(this).val()) {
          selected1.splice(i, 1);
        }
      }
      */
    }
  });
});
Danmoreng
  • 2,367
  • 1
  • 19
  • 32