1

I have a table whose data is being filled dynamically. Each row has a drop-down under status section from which user can select a value and according to the selected value, some input boxes have to be displayed, but these boxes should be displayed in that row in which the drop-down belonged. So, if the drop-down belongs to the first row then the box should appear in the first row only and if the drop-down belongs to the second row then the box should appear in the second row only

Currently, the code that I am using is displaying the input boxes randomly in different rows irrespective of the dropdown position

Can anyone please tell how this can be corrected HTML Code

<table class="table table-bordred table-striped">
  <thead>
    <th>NAME</th>
    <th>STATUS</th>
  </thead>
  <tbody>
    <?php foreach($student as $per_student): ?>
      <tr>
        <td><?php echo $per_student->name; ?></td>
        <td>
          <select class="can-dd" onchange="myFunction(this)" name="status">
            <option value="">STATUS</option>
            <option value="Accepted ">Accepted</option>
            <option value="Forwarded ">Forwarded </option>
            <option value="Schedule">Schedule </option>
            <option value="Custom">Custom</option> 
          </select>
          <div class="schedule">
            <input  type="text" placeholder="schedule" name="schedule">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>

          <div class="custom">
            <input  type="text" placeholder="custom"  name="custom">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>

          <div class="submit_value">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>
        </td>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>

Script

<script type="text/javascript">
  function myFunction(selectObject) {
    var value = selectObject.value;
    if(value == 'Schedule'){
      jQuery('.custom').remove();
      jQuery('.submit_value').remove();
      $(".schedule").show();
    }
    else if(value == 'Custom'){     
      jQuery('.schedule').remove();
      jQuery('.submit_value').remove();
      $(".custom").show();
    }
    else{
      jQuery('.schedule').remove();
      jQuery('.custom').remove();
      $(".submit_value").show();  
    }
  }
</script>
Sam
  • 1,381
  • 4
  • 30
  • 70
  • 4
    `id`s within the document are supposed to be unique. – Teemu May 15 '18 at 05:33
  • @Teemu can you please elaborate – Sam May 15 '18 at 05:36
  • PHP `foreach` loop creates the elements in `tr`s with hardcoded `id`s. When you refer an element like `jQuery('#custom')`, jQuery finds the first element with that `id` from the document only. – Teemu May 15 '18 at 05:39
  • To elaborate. You can only have one unique ID per element otherwise it will cause errors when you try to execute a script targetting that ID. You cannot have two elements that share the same ID. – hungrykoala May 15 '18 at 05:39
  • You can read more about html id's here: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id – M. Eriksson May 15 '18 at 05:42
  • @Teemu k got the point and made the changes can you please have a look if it is done properly – Sam May 15 '18 at 05:45
  • @Teemu can you please show through code how to do it – Sam May 15 '18 at 05:51
  • Where is your JS? – hungrykoala May 15 '18 at 05:53
  • @hungrykoala it is in the post at the bottom – Sam May 15 '18 at 05:54
  • oops sorry didn't saw clearly the scrollbar. Try changing `myFunction(event)` to this `myFunction(this)` also change all your id's to class since you're doing foreach for the elements chances are the ID will cause problems in the future. – hungrykoala May 15 '18 at 05:58
  • @hungrykoala I converted it, but it is not working – Sam May 15 '18 at 06:06
  • @sammy Pass the `event` object, then declare `var parent = $(event.target).parent()` and replace every `jQuery/$` with `parent.find`. – Teemu May 15 '18 at 06:15

3 Answers3

2

You can try this and check if it works for you. I have made some changes to the code but instead of generating the code trough php, I am doing it through JavaScript but it should not make much of a difference.

In your html file, you are generating rows where child divs share the same id submit_value, custom, schedule. You should change those id to be generated dynamically or remove them completely. I have removed them because to me, they seem unnecessary.

Here is a modified HTML file.

<tr>
  <td>--- PHP GENERATED NAME ---</td>
  <td>
    <select class="can-dd" onchange="myFunction(event)" name="status">
      <option value="">STATUS</option>
      <option value="Accepted ">Accepted</option>
      <option value="Forwarded ">Forwarded </option>
      <option value="Schedule">Schedule </option>
      <option value="Custom">Custom</option>
    </select>
    <div class="schedule">
      <input  type="text" placeholder="schedule" name="schedule">
      <button type="submit" class="btn btn-primary "  >SUBMIT</button>
    </div>

    <div class="custom">
      <input  type="text" placeholder="custom"  name="custom">
      <button type="submit" class="btn btn-primary "  >SUBMIT</button>
    </div>

    <div class="submit_value">
      <button type="submit" class="btn btn-primary "  >SUBMIT</button>
    </div>
  </td>
</tr>

And here is a modified javascript code. The first part just generates the html, you can skip it. The myFunction part selects appropriate elements through event.target therefore you can target specific part of document instead of the whole document.

event.target is in your case the select element, therefore if you call parentNode on it, you get a corresponding row. By invoking querySelector on that row with some class name as a search query, you are searching for an element with that class, but only within the subtree of the current row.

// just to dynamically generate the table
const generateTable = n => {
  const tBody = document.querySelector('tbody');

  for (let i = 0; i < n; i++) {
    let htmlCode = `<tr>
      <td>Some name</td>
      <td>
        <select class="can-dd" onchange="myFunction(event)" name="status">
          <option value="">STATUS</option>
          <option value="Accepted ">Accepted</option>
          <option value="Forwarded ">Forwarded </option>
          <option value="Schedule">Schedule </option>
          <option value="Custom">Custom</option>
        </select>
        <div class="schedule">
          <input  type="text" placeholder="schedule" name="schedule">
          <button type="submit" class="btn btn-primary "  >SUBMIT</button>
        </div>

        <div class="custom">
          <input  type="text" placeholder="custom"  name="custom">
          <button type="submit" class="btn btn-primary "  >SUBMIT</button>
        </div>

        <div class="submit_value">
          <button type="submit" class="btn btn-primary "  >SUBMIT</button>
        </div>
      </td>
    </tr>`
    tBody.innerHTML += htmlCode;
  }
}

function myFunction(e) {
  var value = e.target.value;
  if(value == 'Schedule'){
    e.target.parentNode.querySelector('.custom').remove();
    e.target.parentNode.querySelector('.submit_value').remove();
  }
  else if(value == 'Custom'){
    e.target.parentNode.querySelector('.schedule').remove();
    e.target.parentNode.querySelector('.submit_value').remove();
  }
  else{
    e.target.parentNode.querySelector('.schedule').remove();
    e.target.parentNode.querySelector('.custom').remove();
  }
}

generateTable(4);
<table id="mytable" class="table table-bordred table-striped">
  <thead>
    <th>NAME</th>
    <th>STATUS</th>
  </thead>
  <tbody>

  </tbody>
</table>
Matus Dubrava
  • 13,637
  • 2
  • 38
  • 54
2

Use below code maybe this help you

<table id="mytable" class="table table-bordred table-striped">
  <thead>
    <th>NAME</th>
    <th>STATUS</th>
  </thead>
  <tbody>
    <?php foreach($student as $per_student): ?>
      <tr>
        <td><?php echo $per_student->name; ?></td>
        <td>
          <select class="can-dd status_value"  name="status">
            <option value="">STATUS</option>
            <option value="Accepted ">Accepted</option>
            <option value="Forwarded ">Forwarded </option>
            <option value="Schedule">Schedule </option>
            <option value="Custom">Custom</option> 
          </select>
          <div class="schedule input_box">
            <input  type="text" placeholder="schedule" name="schedule">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>

          <div class="custom input_box">
            <input  type="text" placeholder="custom"  name="custom">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>

          <div class="submit_value input_box">
            <button type="submit" class="btn btn-primary "  >SUBMIT</button>
          </div>
        </td>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>

<script type="text/javascript">
jQuery(document).ready(function(){
    jQuery("#mytable").on("change", ".status_value", function(){
        var selDiv = jQuery(this).parent("td");
        var selVal = jQuery(this).val();
        if(selVal == 'Schedule'){
            selDiv.find(".input_box").hide();
            selDiv.find(".schedule").show();
        } 
        else if(selVal == 'Custom'){
            selDiv.find(".input_box").hide();
            selDiv.find(".custom").show();
        } 
        else {
            selDiv.find(".input_box").hide();
            selDiv.find(".submit_value").show();
        }
    });
});
</script>

I had to remove IDs from all fields and set jQuery change event based on class for particular raw

Jaydp
  • 1,029
  • 9
  • 17
1

I am no expert and still in the learning phase, but I think I can try to provide a possible solution to this.

You have given id names like 'Schedule' and 'schedule' which are valid as they are case-sensitive in HTML. However, while calling these functions through CSS they are considered case-insensitive as mentioned in https://www.w3.org/TR/selectors-3/#casesens

Thus while using CSS #idname through jQuery '#schedule' can consider any of the tag named id = schedule or Schedule. When there are multiple tags with same id the results vary based on Browser. Referred to : How jQuery works when there are multiple elements with the same "id"?

Try to give unique ids to all the elements and try the code.. It should solve the problem.