0

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

enter image description here

Not working

enter image description here

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>
user16881755
  • 49
  • 1
  • 7
  • You are essentially creating only on line yourself... $att_name should become : $att_name[0] for example so: $att_name[0] = " – Shlomtzion Sep 10 '21 at 21:07
  • Welcome to Stack Overflow. Please provide a Minimal, Reproducible Example: https://stackoverflow.com/help/minimal-reproducible-example Your current example cannot be replicated and does not even offer Example data. – Twisty Sep 10 '21 at 22:15
  • @Shlomtzion I added $i=0; and ++$i at the end of each while loop but it had no affect on the dropdown selections when I added a new row. – user16881755 Sep 13 '21 at 09:06

2 Answers2

0

I hope this will illustrate the need and the way! - Took your code and changed it a bit - for the example I created two arrays in one divided by the name of the var and counted by the amount it contains... I also placed two loops in and around the html in order to achieve the names - main loop that in our case only runs twice (this code example) and inner loop for the values of each name... :

<?php

$att_data["Colour"][] = "Black";
$att_data["Colour"][] = "Blue";
$att_data["Colour"][] = "Red";
$att_data["Colour"][] = "Green";

$att_data["Size"][] = "Large";
$att_data["Size"][] = "Small";
$att_data["Size"][] = "Medium";
$att_data["Size"][] = "XL";
echo '<pre>';
print_r($att_data);

$i = 0;
$s = 0;
?>


    <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>
                <?php
                foreach($att_data as $key => $d){ ?>
                    <tr id="row1">
                        <td>
                            <select name='attribute_name' id='attribute_name' class='form-control'>
                                <option value='<?php echo $key; ?>'><?php echo $key; ?></option>
                            </select>
                        </td>
                        <td>
                            <select name='attribute_id' id='attribute_value' class='form-control'>
                                <?php
                                foreach ($att_data[$key] as $val){
                                    ?><option value='<?php echo $val; ?>'><?php echo $val; ?></option><?php
                                } ?>
                            </select>
                        </td>
                        <td><input class="btn btn-block btn-primary" type="button" onclick="add_attribute_row();" value="+"></td>
                    </tr> <?php
                }
                ?>

            </table>
        </div>
    </div>

This will output this: enter image description here

This should explain how to collect and distribute data! :) - the keys in my case Colour etc are the names... and the values are the values! no need for too many variables, a nice array with correct keys does the data collecting better!

Shlomtzion
  • 674
  • 5
  • 12
  • Your answer does not solve the problem. It works for a fixed select option, but what the OP requires is a dynamic set select-option. And the problem the OP face, JQuery change event only works for the first row. – NcXNaV Sep 13 '21 at 19:22
0
  1. First of all, you are not allowed to use duplicate ID. You should use class instead. Check this answer Class vs ID.

  2. Secondly, I've changed your change event with .on('change') which will work for dynamically added select. Check this sample JQuery .on('change').

  3. 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>
NcXNaV
  • 1,657
  • 4
  • 14
  • 23