socramm socramm - 7 months ago 4
HTML Question

Check if there is an <tr> underneath

I have this code that adds me an extra input each time I write something in it.
but I have the problem that even if in the input is already something written and I change it it adds an new input.
But I would like to disable that.

I tried an if check but I am not so familiar whit html so I don't know how to perform this check like I want it.

Can someone tell me how to check if there is an object underneath the input box I am changing

Thanks



$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;

$('#addScnt').live('click', function() {
$('<tr><td><label for="p_scnts"><input type="text" class="iptArea" id="p_scnt" size="20" name="p_scnt_' + i + '" value="" placeholder="Input Value" /></label> <a href="#" id="remScnt">Remove</a></tr></td>').appendTo(scntDiv);
i++;
return false;
});

$(".iptArea").live("change", function() {

$('<tr><td><label for="p_scnts"><input type="text" class="iptArea" id="p_scnt" size="20" name="p_scnt_' + i + '" value="" placeholder="Input Value" /></label> <a href="#" id="remScnt">Remove</a></tr></td>').appendTo(scntDiv);
i++;

return false;

});

$('#remScnt').live('click', function() {
if (i > 1) {
$(this).parents('tr').remove();
i--;
}
return false;
});
});

<html>
<head>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="./script.js"></script>

</head>

<body>
<h2><a href="http://fiddle.jshell.net/0hcod561/1/show/light/#" id="addScnt">Add Another Input Box</a></h2>

<div id="p_scents">
<tr>
<td>
<label for="p_scnts">
<input type="text" class="iptArea" id="p_scnt" size="20" name="p_scnt" value="" placeholder="Input Value">
</label>
</td>
</tr>
</div>


</body>
</html>




Answer

There are several issues:

  • There are tr tags outside of table tags -- this is invalid HTML; div is not the right container;
  • jQuery 1.4 is really outdated, and the live method is deprecated;
  • the for attribute has a value which refers to a non-existing element. Probably it should read for="p_scnt" instead of for="p_scnts";
  • there is duplication of code in the first two event handlers;
  • the template HTML which you insert has mistakes:
    • the closing </tr> and </td> tags are in the wrong order;
    • the input's id property has the same value as an already existing element -- this is not allowed in HTML and can lead to unexpected behaviour of scripts;
    • the same issue with the for attribute appears here;
    • you can better place template HTML inside the HTML document, in an invisible container. That makes it easier to manage.

To prevent rows from being added when there is already an empty input in the last row, you could use this test:

$('#p_scents .iptArea').last().val() === ''

Here is the corrected code, which also includes that test:

$(function() {
    var uniqueId = 1;
    
    function addRow() {
        var html = $('#template > tbody').html().replace(/\$/g, uniqueId++);
        $('#p_scents > tbody').append(html.trim());
        return false;
    }

    $('#addScnt').click(addRow);
    
    $(document).delegate('.iptArea', 'change', function () {
        if ($('#p_scents .iptArea').last().val() === '') return false; // don't add
        return addRow();
    });

    $(document).delegate('.remScnt', 'click', function(e) {
        $(this).parents('tr').remove();
        return false;
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="./script.js"></script>
<h2>
   <a href="http://fiddle.jshell.net/0hcod561/1/show/light/#" id="addScnt">
      Add Another Input Box
   </a>
</h2>

<table style="display:none" id="template">
    <tr>
        <td>
            <label for="p_scnt_$">
                <input type="text" class="iptArea" id="p_scnt_$"     
                        size="20" name="p_scnt_$" value="" placeholder="Input Value">
            </label>
            <a href="#" class="remScnt">Remove</a>
       </td>
    </tr>
</table>

<table  id="p_scents">
    <tr>
        <td>
            <label for="p_scnt">
                <input type="text" class="iptArea" id="p_scnt" 
                        size="20" name="p_scnt" value="" placeholder="Input Value">
            </label>
        </td>
    </tr>
</table>

You could also consider responding to the input event, adding that word after change, like this:

$(document).delegate('.iptArea', 'change input', function () {

This will trigger at every change, not only when you change focus.

Note that I have converted your calls to .live() to .delegate(), as .live() is not supported at all in newer versions of jQuery (> 1.9), while .delegate() works (still) in all 1.x versions. But take note of the docs on .delegate():

As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation.

But on does not exist in jQuery 1.4, so delegate is the best compromise until you have fully migrated your code. As stated in the docs on .live():

version deprecated: 1.7, removed: 1.9

Users of older versions of jQuery should use .delegate() in preference to .live().

After having migrated to current jQuery version

Then change .delegate() calls to .on() calls, and swap the first two arguments in those calls, for instance:

    $(document).on('change input', '.iptArea', function () { // .. etc

Here is the same snippet, but running with jQuery 2.2

$(function() {
    var uniqueId = 1;
    
    function addRow() {
        var html = $('#template > tbody').html().replace(/\$/g, uniqueId++);
        $('#p_scents > tbody').append(html.trim());
        return false;
    }

    $('#addScnt').click(addRow);
    
    $(document).on('change', '.iptArea', function () {
        if ($('#p_scents .iptArea').last().val() === '') return false; // don't add
        return addRow();
    });

    $(document).on('click', '.remScnt', function(e) {
        $(this).parents('tr').remove();
        return false;
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script type="text/javascript" src="./script.js"></script>
<h2>
   <a href="http://fiddle.jshell.net/0hcod561/1/show/light/#" id="addScnt">
      Add Another Input Box
   </a>
</h2>

<table style="display:none" id="template">
    <tr>
        <td>
            <label for="p_scnt_$">
                <input type="text" class="iptArea" id="p_scnt_$"     
                        size="20" name="p_scnt_$" value="" placeholder="Input Value">
            </label>
            <a href="#" class="remScnt">Remove</a>
       </td>
    </tr>
</table>

<table  id="p_scents">
    <tr>
        <td>
            <label for="p_scnt">
                <input type="text" class="iptArea" id="p_scnt" 
                        size="20" name="p_scnt" value="" placeholder="Input Value">
            </label>
        </td>
    </tr>
</table>

Comments