Search code examples
javascripthtmljquery

Success Message Not Showing After One Time


I'm trying to show a message when a new record is added. The first time I add a record, the message appears. But if I add another record, the message doesn't show up, even though the record is added correctly.

This is my HTML Code

<button id="add">Add Name To Table</button>
<input type="text" placeholder="Enter Name" id="name" style="display: none;">
<input type="text" placeholder="Enter Class" id="class" style="display: none;">

<button id="save" style="display: none;">Add Name</button>
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Class</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

<span id="message"></span>
<div id="editdiv"></div>

This is my jquery code

 $(document).ready(function () {

        var value;
        var Nclass;

        $('#add').click(function () {

            $('#name').show();
            $('#class').show();
            $('#save').show();
        });
        $('#save').click(function () {
            if ($('#name').val().length != "" && $('#class').val().length != "") {
                value = $('#name').val().trim();
                Nclass = $('#class').val().trim();

                if (value != "") {
                    var cell = $('<td>').text(value);
                    var classval = $('<td>').text(Nclass);
                    var deletebtn = $('<button>').text('Delete').attr('class', 'delete');
                    var editbtn = $('<button>').text('Edit').attr('class', 'edit');
                    var row = $('<tr>').append(cell, classval, deletebtn, editbtn);
                    $('tbody').append(row);
                    row.hide().fadeIn();
                    $('#message').text("Data Added Successfully").css("color", "green");
                    setTimeout(function () {
                        $('#message').fadeOut();
                    }, 2000);
                    $('#name').val('');
                    $('#class').val('');

                }
            } else {
                $('#message').text("You Cannot Submit While Input Fields Are Empty").css('color', 'red');
                setTimeout(function () {
                    $('#message').fadeOut();
                }, 2000);
            }
        });

    });


Solution

  • The message doesn't show up the second time because the first time had code to hide it: $('#message').fadeOut(). To solve that, chain a .show() or .fadeIn() call when you display the text:

    $('#message').text(".......").css('color', "....").fadeIn();
    

    To make it more consistent, you could hide the #message element in the initial HTML. In that case the fading-in effect would also work the first time.

    As you have two places where you show a message, including the setTimeout call where you hide the message again, you have an opportunity to avoid this repetition of code and introduce a function that does the job, like:

    function notify(message, color) {
        $('#message').text(message).css('color', color).show();
        setTimeout(function () {
            $('#message').fadeOut();
        }, 2000);
    }
    

    Some other comments:

    • The jQuery documentation recommends to use $(function () instead of $(document).ready(function () {

    • Give variables like value and Nclass the scope they need (where you need them). Currently you have defined them at the level of the ready-callback function, but they are only used in the click-callback function, so better define them there.

    • Use the more modern const or let keywords instead of var. These have block scope and make var unnecessary.

    • Combine jQuery selectors when you perform the same actions on them, like $('#name, #class, #save').show();

    • As you want to avoid adding empty strings, make sure to first trim the input values. Currently your code allows to add Nclass as an empty string (if you input a few spaces).

    • Don't compare like this: .length != "". This comparison of a number with a string happens to work as you intended it, but it is more consistent to either compare the input string with "" or its length with 0. In this case you can even just test the truthiness of the (trimmed) input string and drop the comparison operator.

    • Don't start a variable name like Nclass with a capital. It is common practice to reserve PascalCase naming for constructors/classes, and use camelCase for other variable names. I would suggest className.

    $(function () {  // Preferred way
        $('#add').click(function () {
            $('#name, #class, #save').show(); // Combine
        });
        
        $('#save').click(function () {
            // Use const/let instead of var. Scope at the right level
            // Perform trim first and then perform the IF
            const value = $('#name').val().trim();
            const className = $('#class').val().trim();
            // Don't compare length (number) with a string. Just look at truthiness:
            if (value && className) { // Simplified condition
                // No nested IF
                var cell = $('<td>').text(value);
                var classval = $('<td>').text(className);
                var deletebtn = $('<button>').text('Delete').attr('class', 'delete');
                var editbtn = $('<button>').text('Edit').attr('class', 'edit');
                var row = $('<tr>').append(cell, classval, deletebtn, editbtn);
                $('tbody').append(row);
                row.hide().fadeIn();
                // Reuse code:
                notify("Data Added Successfully", "green");
                $('#name, #class').val(""); // Combine
            } else {
                // Reuse code:
                notify("You Cannot Submit While Input Fields Are Empty", "red");
            }
        });
    
    });
    
    function notify(message, color) {
        $('#message').text(message).css('color', color).fadeIn();
        setTimeout(function () {
            $('#message').fadeOut();
        }, 2000);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <button id="add">Add Name To Table</button>
    
    <input type="text" placeholder="Enter Name" id="name" style="display: none;">
    <input type="text" placeholder="Enter Class" id="class" style="display: none;">
    
    <button id="save" style="display: none;">Add Name</button>
    
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Class</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    
    <span id="message" style="display:none"></span>
    <div id="editdiv"></div>