Search code examples
jqueryajaxmodel-view-controllerkeypresswebgrid

JQUERY KeyPress event fires multiple times exponentially increasing each time


Application : MVC

In my partial view code, I have a webgrid which has updateable text box columns. I am binding KeyPress event code for these text boxes to respond to Enter key and make AJAX call to update the database. My WebGrid is setup as follows:

  var grid = new WebGrid(source: Model, selectionFieldName: "SelectedRow",
            rowsPerPage: (500),
            columnNames: new[] { "EmpID", "Name", "PayGroup", "NetPay", "Comments", "Dept#", "MailSort" },
            canPage: true,
            canSort: true,
            ajaxUpdateContainerId: "gridContent"
            );
   <div id="gridContent">
    @grid.GetHtml(
    tableStyle: "webgrid-table",
    headerStyle: "webgrid-header",
    footerStyle: "webgrid-footer",
    alternatingRowStyle: "webgrid-alternating-row",
    selectedRowStyle: "webgrid-row-style",
    htmlAttributes: new { id = "EmployeeGrid" },
    mode: WebGridPagerModes.All,
    firstText: "<< First",
    previousText: "< Prev",
    nextText: "Next >",
    lastText: "Last >>",
    columns: grid.Columns(

            grid.Column("ID", header: "ID", format: @<text>@item.EmpID</text>, style: "colID"),
            grid.Column("Name", header: "Name", format: @<text>@item.Name</text>, style: "colName"),
            grid.Column("Dept", header: "Dept", format: @<text>@item.Dept</text>, style: "colDept"),
                            //grid.Column("Location", header: "Location", format: @<text>@item.Location</text>, style: "colLocation"),
            grid.Column("NetPay", header: "NetPay", format:  @<input id="valNetPay" type="text" style="width:50px" value="@item.NetPay" />, style: "colNetPay"),
            grid.Column("MailSort", header: "MailSort", format:  @<input id="valMailSort" type="text" style="width:50px" value="@item.MailSort" />, style: "colMailSort"),
            grid.Column("PayGroup", header: "PayGroup", format:  @<input id="valPayGroup" type="text" style="width:50px" value="@item.PayGroup" />, style: "colPayGroup")
        )
    )

the following is the jquery event handler. I am posting below the code for one column, but the code for the other two text columns are similar and the issue persists there as well.

    <script>
    $(document).ready(function () {

        $(document).on("keypress", ".colMailSort", function (e) {
            var eCode = e.keycode || e.which

            //Capture Enter key
            if (eCode == 13) {
                e.preventDefault();
                alert(eCode);
                alert('MailSort');

                iid = $(this).closest('tr').find('td.colID').text();
                var np = $(this).closest('tr').find('td #valNetPay').val();
                var pg = $(this).closest('tr').find('td #valPayGroup').val();
                var ms = $(this).closest('tr').find('td #valMailSort').val();


                $.ajax({
                    url: '@Url.Action("SavePayGroup", "Payroll")',
                    type: 'POST',
                    cache: false,
                    data: { id: iid, paygroup: pg, netpay: np, mailsort: ms },

                }).done(function (result) {
                    alert('Saved');
                    $('#PayrollMenuResults').html(result);
                    console.log("saved");
                    return false;
                });

            }
        });
    });
</script>

When the code runs, and the first time I put in values in the column and press enter, the code fires four times. But the next time, it fires 8 times and so on... This is driving me nuts! Any suggestion to solve this issue is greatly appreciated.


Solution

  • My guess is that you are loading your javascript dynamically, most probably from the ajax request and each time you make an ajax request, you are binding the keypress event again and again. Try putting your javascript code in a separate JS file and load it once within the header.

    To verify this, I have a patch which you can replace with your current Javascript.

    <script>
        if(!window['script_added']) {
            window['script_added'] = true;
            $(document).ready(function () {
    
                $(document).on("keypress", ".colMailSort", function (e) {
                    var eCode = e.keycode || e.which
    
                    //Capture Enter key
                    if (eCode == 13) {
                        e.preventDefault();
                        alert(eCode);
                        alert('MailSort');
    
                        iid = $(this).closest('tr').find('td.colID').text();
                        var np = $(this).closest('tr').find('td #valNetPay').val();
                        var pg = $(this).closest('tr').find('td #valPayGroup').val();
                        var ms = $(this).closest('tr').find('td #valMailSort').val();
    
    
                        $.ajax({
                            url: '@Url.Action("SavePayGroup", "Payroll")',
                            type: 'POST',
                            cache: false,
                            data: { id: iid, paygroup: pg, netpay: np, mailsort: ms },
    
                        }).done(function (result) {
                            alert('Saved');
                            $('#PayrollMenuResults').html(result);
                            console.log("saved");
                            return false;
                        });
    
                    }
                });
            });
        }
    </script>