1

When I add fields using the jQuery .after() function, the show/hide functionality does not work on those fields.

Here's a JSFiddle that demonstrates the issue:

JSFiddle Demo

The show/hide functionality works on the first row, but does not work on any rows added after that one. I think the code being written after the page has been loaded might be the issue, but I'm not certain. If that's the case, is there a work around other than hard coding a certain amount of rows?

Here's the code I'm working with:

CSS:

#Table {
  font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
  border-collapse:collapse;
}
#Table td, #Table th {
    font-size:1em;
    border:1px solid #98bf21;
    padding:3px 7px 2px 7px;
}
#Table th {
    font-size:1.4em;
    text-align:left;
    padding-top:5px;
    padding-bottom:4px;
    background-color:#A7C942;
    color:#fff;
}
#Table tr.alt td {
    color:#000;
    background-color:#EAF2D3;
}

HTML:

<table style="width: 70%" id="Table" name="Table">
    <tr>
        <th>#</th>
        <th>Cause</th>
    </tr>
    <tr>
        <td>1</td>
        <td>
            <select name='report_cause2' id='report_cause2' class="report_cause">
                <option value='default'>-</option>
                <option value='other'>Other, Not Listed</option>
            </select>
            <p class="cause_details">
                <input type="text" name="cause_detail_info" id="cause_detail_info" placeholder="Type cause here" size="48" maxlength="50" class="textbox required" value="" />
            </p>
        </td>
    </tr>
</table>
<input type="button" id="btnAdd" name="btnAdd" value="Add More" class="button" />

jQuery:

var count_2 = 5;
var table_count2 = 1;

$(document).ready(function () {

    $('.cause_details').hide();
    $('.report_cause').change(function () {

        if ($(this).val() == 'other') {
            $(this).parent().find('.cause_details').show();
        } else {
            $(this).parent().find('.cause_details').hide();
        }

    });

    $('#btnAdd').click(function () {
        count_2 = count_2 + 2;
        table_count2 = table_count2 + 1;
        $('#Table tr:last').after('<tr><td>' + table_count2 + '</td>' +
            '<td>' +
            '<select name=\"report_cause' + count_2 + '\" id=\"report_cause' + count_2 + '\" class=\"report_cause\">' +
            '<option value=\'default\'>-</option>' +
            '<option value=\'other\'>Other, Not Listed</option>' +
            '</select>' +
            '<p class=\"cause_details\">' +
            '<input type=\"text\" name=\"cause_detail_info' + count_2 + '\" id=\"cause_detail_info' + count_2 + '\" placeholder=\"Type cause here\" size=\"48\" maxlength=\"50\" class=\"textbox required\" value=\"\" />' +
            '</p>' +
            '</td></tr>');
    });
});
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
R. Kelly
  • 93
  • 1
  • 2
  • 10

3 Answers3

4

This:

$('.report_cause').change(function () {

Only applies to the .report_cause elements that existed when it was called. To handle new elements, you need a delegated handler:

$(document).on('change', '.report_cause', function(){

Additionally, if you want the new elements initially hidden, modify your output HTML accordingly:

'<p class=\"cause_details\" style=\"display:none\">'+

var count_2 = 5;
var table_count2 = 1;

$(document).ready(function() {

  $('.cause_details').hide();
  $(document).on('change', '.report_cause', function() {

    if ($(this).val() == 'other') {
      $(this).parent().find('.cause_details').show();
    } else {
      $(this).parent().find('.cause_details').hide();
    }

  });

  $('#btnAdd').click(function() {
    count_2 = count_2 + 2;
    table_count2 = table_count2 + 1;
    $('#Table tr:last').after('<tr><td>' + table_count2 + '</td>' +
      '<td>' +
      '<select name=\"report_cause' + count_2 + '\" id=\"report_cause' + count_2 + '\" class=\"report_cause\">' +
      '<option value=\'default\'>-</option>' +
      '<option value=\'other\'>Other, Not Listed</option>' +
      '</select>' +
      '<p class=\"cause_details\" style=\"display:none\">' +
      '<input type=\"text\" name=\"cause_detail_info' + count_2 + '\" id=\"cause_detail_info' + count_2 + '\" placeholder=\"Type cause here\" size=\"48\" maxlength=\"50\" class=\"textbox required\" value=\"\" />' +
      '</p>' +
      '</td></tr>');
  });
});
#Table {
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  border-collapse: collapse;
}
#Table td,
#Table th {
  font-size: 1em;
  border: 1px solid #98bf21;
  padding: 3px 7px 2px 7px;
}
#Table th {
  font-size: 1.4em;
  text-align: left;
  padding-top: 5px;
  padding-bottom: 4px;
  background-color: #A7C942;
  color: #fff;
}
#Table tr.alt td {
  color: #000;
  background-color: #EAF2D3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table style="width: 70%" id="Table" name="Table">
  <tr>
    <th>#</th>
    <th>Cause</th>
  </tr>
  <tr>
    <td>1</td>
    <td>
      <select name='report_cause2' id='report_cause2' class="report_cause">
        <option value='default'>-</option>
        <option value='other'>Other, Not Listed</option>
      </select>
      <p class="cause_details">
        <input type="text" name="cause_detail_info" id="cause_detail_info" placeholder="Type cause here" size="48" maxlength="50" class="textbox required" value="" />
      </p>
    </td>
  </tr>
</table>
<input type="button" id="btnAdd" name="btnAdd" value="Add More" class="button" />
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
2

Try this. The problem is that when you create a dynamic element, you need to again register change event on $('.report_cause').

$(document).ready(function(){

    $('.cause_details').hide();

    BindChange();

    $('#btnAdd').click(function(){
        count_2 = count_2 + 2;
        table_count2 = table_count2 + 1;
        $('#Table tr:last').after('<tr><td>'+table_count2+'</td>'+
        '<td>'+
            '<select name=\"report_cause'+count_2+'\" id=\"report_cause'+count_2+'\" class=\"report_cause\">'+
                '<option value=\'default\'>-</option>'+
                '<option value=\'other\'>Other, Not Listed</option>'+
            '</select>'+
            '<p class=\"cause_details\">'+
                '<input type=\"text\" name=\"cause_detail_info'+count_2+'\" id=\"cause_detail_info'+count_2+'\" placeholder=\"Type cause here\" size=\"48\" maxlength=\"50\" class=\"textbox required\" value=\"\" />'+
            '</p>'+
        '</td></tr>');

        BindChange();
    });
});

function BindChange()
{
    $('.report_cause').bind("change",function(){

    if ($(this).val() == 'other'){
    $(this).parent().find('.cause_details').show();
        }else{
    $(this).parent().find('.cause_details').hide();
        }

    });
}

https://jsfiddle.net/hnj6ed1y/12/

DinoMyte
  • 8,737
  • 1
  • 19
  • 26
1

When you create the elements dynamically, you need to use event delegation to handle the events on them, so based on your jQuery version use .bind or .on API.

Just change in your code to:

$(document).on('change', '.report_cause', function () {
        if ($(this).val() == 'other') {
            $(this).parent().find('.cause_details').show();
        } else {
            $(this).parent().find('.cause_details').hide();
        }
    });
vinayakj
  • 5,591
  • 3
  • 28
  • 48