I have created a form for entering product data which sends the results back to the mysql database. I have a dropdown/select id named ‘attribute_name’ and the other ‘attribute_value’ I have managed to send the results back to the database and that is working great. I would however like to restrict the user to only choosing values based on the name so if they selected size they would only have the values of small, medium, large and not black, camo, purple from colour and vice versa.
The script at the bottom works on the first row but not on any other rows as shown in the screenshots.
Working
Not working
Code
<?php include 'assets/processes/db-connection.php'; $query = "SELECT * FROM attribute_name;"; $query_run = mysqli_query($conn, $query); $att_name = "<select name='attribute_name' id='attribute_name' class='form-control country'>"; $att_name .= "<option value='0'></option>"; while ($row = mysqli_fetch_assoc($query_run)) { $att_name .= "<option value='{$row['attribute_name']}'>{$row['attribute_name']}</option>"; } $att_name .= "</select>" ?> <?php include 'assets/processes/db-connection.php'; $query = "SELECT `attribute`.*, `attribute_name`.* FROM `attribute` LEFT JOIN `attribute_name` ON `attribute`.`attribute_name_id` = `attribute_name`.`attribute_name_id`;"; $query_run = mysqli_query($conn, $query); $att_value = "<select name='attribute_id' id='attribute_value' class='form-control'>"; $att_value .= "<option value='0'></option>"; while ($row = mysqli_fetch_assoc($query_run)) { $att_value .= "<option data-parent='{$row['attribute_name']}' value='{$row['attribute_id']}'>{$row['attribute_value']}</option>"; } $att_value .= "</select>" ?> <div id="wrapper"> <div id="form_div"> <table class="table table-hover text-nowrap" id="attribute_table"> <thead> <tr> <th>Name</th> <th>Value</th> <th colspan="1">Action</th> </tr> </thead> <tr id="row1"> <td> <?php echo $att_name; ?> </td> <td> <?php echo $att_value; ?> </td> <td><input class="btn btn-block btn-primary" type="button" onclick="add_attribute_row();" value="+"></td> </tr> </table> </div> </div> <script> $('#attribute_name').change(function() { var parent = $(this).val(); $('#attribute_value').children().each(function() { if ($(this).data('parent') != parent) { $(this).hide(); } else $(this).show(); }); }); </script>
This code is edited for use on stackoverflow
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <div id="wrapper"> <div id="form_div"> <table class="table table-hover text-nowrap" id="attribute_table"> <thead> <tr> <th>Name</th> <th>Value</th> <th colspan="1">Action</th> </tr> </thead> <tr id="row1"> <td> <select name='attribute_name' id='attribute_name' class='form-control'> <option value='0'></option> <option value='Colour'>Colour</option> <option value='Size'>Size</option> </select> </td> <td> <select name='attribute_id' id='attribute_value' class='form-control'> <option value='0'></option> <option data-parent='Colour' value='1'>Black</option> <option data-parent='Colour' value='2'>Camo</option> <option data-parent='Colour' value='3'>Purple</option> <option data-parent='Size' value='4'>Small</option> <option data-parent='Size' value='5'>Medium</option> <option data-parent='Size' value='6'>Large</option> </select> </td> <td><input class="btn btn-block btn-primary" type="button" onclick="add_attribute_row();" value="+"></td> </tr> </table> </div> </div> <script> function add_attribute_row() { $rowno = $("#attribute_table tr").length; $rowno = $rowno + 1; $("#attribute_table tr:last").after("<tr id='row" + $rowno + "'><td><select name='attribute_name' id='attribute_name' class='form-control'><option value='0'></option><option value='Colour'>Colour</option><option value='Size'>Size</option></select></td><td><select name='attribute_id' id='attribute_value' class='form-control'><option value='0'></option><option data-parent='Colour' value='1'>Black</option><option data-parent='Colour' value='2'>Camo</option><option data-parent='Colour' value='3'>Purple</option><option data-parent='Size' value='4'>Small</option><option data-parent='Size' value='5'>Medium</option><option data-parent='Size' value='6'>Large</option></select></td><td><input class='btn btn-block btn-primary' type='button' value='-' onclick=del_att_row('row" + $rowno + "')></td></tr>"); } function del_att_row(rowno) { $('#' + rowno).remove(); }; </script> <script> $('#attribute_name').bind('change', function () { var parent = $(this).val(); $('#attribute_value').children().each(function () { if ($(this).data('parent') != parent) { $(this).hide(); } else $(this).show(); }); }); </script>
Advertisement
Answer
First of all, you are not allowed to use duplicate ID. You should use class instead. Check this answer Class vs ID.
Secondly, I’ve changed your
change
event with.on('change')
which will work for dynamically added select. Check this sample JQuery .on(‘change’).Lastly, you don’t want to select all select with class
attribute-name
, you need to find the select on that particular row. You can do this by using .closest(‘tr’) selector to select the current row<tr>
where the event happened, and then use **.find('.attribute-value')** which will traverse and find element with the class
attribute-value`.
From the documentation:
- The
.closest
selector traverses up the DOM to find the parent that matches the conditions. - The
.find
selector traverses down the DOM where the event occurred, that matches the conditions.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <div id="wrapper"> <div id="form_div"> <table class="table table-hover text-nowrap" id="attribute_table"> <thead> <tr> <th>Name</th> <th>Value</th> <th colspan="1">Action</th> </tr> </thead> <tr id="row1"> <td> <select name='attribute_name' id='attribute_name' class='form-control attribute_name'> <option value='0'></option> <option value='Colour'>Colour</option> <option value='Size'>Size</option> </select> </td> <td> <select name='attribute_id' id='attribute_value' class='form-control attribute_value'> <option data-parent='0' value='0'></option> <option data-parent='Colour' value='1'>Black</option> <option data-parent='Colour' value='2'>Camo</option> <option data-parent='Colour' value='3'>Purple</option> <option data-parent='Size' value='4'>Small</option> <option data-parent='Size' value='5'>Medium</option> <option data-parent='Size' value='6'>Large</option> </select> </td> <td><input class="btn btn-block btn-primary" type="button" onclick="add_attribute_row();" value="+"></td> </tr> </table> </div> </div> <script> function add_attribute_row() { $rowno = $("#attribute_table tr").length; $("#attribute_table tr:last").after("<tr id='row" + $rowno + "'><td><select name='attribute_name' id='attribute_name' class='form-control attribute_name'><option value='0'></option><option value='Colour'>Colour</option><option value='Size'>Size</option></select></td><td><select name='attribute_id' id='attribute_value' class='form-control attribute_value'><option data-parent='0' value='0'></option><option data-parent='Colour' value='1'>Black</option><option data-parent='Colour' value='2'>Camo</option><option data-parent='Colour' value='3'>Purple</option><option data-parent='Size' value='4'>Small</option><option data-parent='Size' value='5'>Medium</option><option data-parent='Size' value='6'>Large</option></select></td><td><input class='btn btn-block btn-primary' type='button' value='-' onclick=del_att_row('row" + $rowno + "')></td></tr>"); } function del_att_row(rowno) { $('#' + rowno).remove(); }; </script> <script> $(document).on('change', '.attribute_name', function () { var parent = $(this).val(); $(this).closest('tr').find('.attribute_value').children().each(function () { if ($(this).data('parent') != parent) { $(this).hide(); } else $(this).show(); }); }); </script>