function sqGridInput(grid, rowIndex, colIndex, row, params) {
    function debuncedSendValue(e) {
        clearTimeout(window.sqGridInputDebounceTimer);
        window.sqGridInputDebounceTimer = setTimeout(function () {
            window.sqGridInputDebounceTimer = null;
            grid.setCellCustomData(rowIndex, colIndex, "cellsInputValues", e.target.value);
            sqGridSendEvent(e, "inputUpdated", e.target.value);
        }, 500);
    }
    var value = "";
    if ("value" in params) {
        value = params["value"];
    }

    var isDisabled = false;
    if (row.disabled) {
        isDisabled = true;
    }
    if (grid.getCellCustomData(rowIndex, colIndex, "cellsDisabled")) {
        isDisabled = true;
    }

    var customValue = grid.getCellCustomData(rowIndex, colIndex, "cellsInputValues")
    if (customValue != null) {
        value = customValue;
    } else {
        grid.setCellCustomData(rowIndex, colIndex, "cellsInputValues", value);
    }

    if (value == null || value == "null") {
        value = "";
    }

    if (grid.smartRenderingUrl) {
        var divOuter = document.createElement("div");
        divOuter.classList.add("grid-widget-input");
        divOuter.onmousedown = function(e) {
            e.stopPropagation();
        };


        var divInput = document.createElement("input");
        divInput.classList.add("grid-widget-input-inner");
        divInput.value = value;
        if (isDisabled) {
            divInput.disabled = "disabled";
        }
        divInput.onchange = function(e) {
            e.stopPropagation();
            debuncedSendValue(e);
        };
        divInput.onkeydown = function(e) {
            e.stopPropagation();
        };
        divInput.onkeyup = function(e) {
            e.stopPropagation();
            if (e.keyCode == "13") {
                e.target.blur();
                debuncedSendValue(e);
                return false;
            }
            debuncedSendValue(e);
        };
        divOuter.appendChild(divInput);

        return divOuter;
    }
    else {
        IncrementalDOM.elementOpenStart('div');
        IncrementalDOM.attr("class", "grid-widget-input");
        IncrementalDOM.attr("onmousedown", function (e) {
            e.stopPropagation();
        });
        IncrementalDOM.elementOpenEnd('div');
    
        IncrementalDOM.elementOpenStart('input');
        IncrementalDOM.attr("class", "grid-widget-input-inner");
        IncrementalDOM.attr("type", "text");
        IncrementalDOM.attr("value", value);
        if (isDisabled) {
            IncrementalDOM.attr("disabled", "disabled");
        }
        IncrementalDOM.attr("onchange", function (e) {
            e.stopPropagation();
            grid.setCellCustomData(rowIndex, colIndex, "cellsInputValues", e.target.value);
            sqGridSendEvent(e, "inputUpdated", e.target.value);
        });
        IncrementalDOM.attr("onkeydown", function (e) {
            e.stopPropagation();
        });
        IncrementalDOM.attr("onkeyup", function (e) {
            e.stopPropagation();
            if (e.keyCode == "13") {
                e.target.blur();
                return;
            }
            debuncedSendValue(e);    
        });
        IncrementalDOM.elementOpenEnd('input');
        var currentElement = IncrementalDOM.currentElement();
        currentElement.value = value;
        currentElement.blur();
        IncrementalDOM.elementClose('input');
        IncrementalDOM.elementClose('div');
    }
}

function sqGridInputValueSet(grid, rowIndex, colIndex, newValue, disableBodyRedraw) {
    grid.setCellCustomData(rowIndex, colIndex, "cellsInputValues", newValue);

    if (!disableBodyRedraw) {
        grid.bodyRedraw();
    }    
}

function sqGridInputValueGet(grid, rowIndex, colIndex) {
    return grid.getCellWidgetValue(rowIndex, colIndex, "cellsInputValues");
}