updateCell = function(x, y, value, force) {
    const obj = this;

    let record;

    // Changing value depending on the column type
    if (obj.records[y][x].element.classList.contains('readonly') == true && ! force) {
        // Do nothing
        record = {
            x: x,
            y: y,
            col: x,
            row: y
        }
    } else {
        // Security
        if ((''+value).substr(0,1) == '=' && obj.options.secureFormulas == true) {
            const val = secureFormula(value);
            if (val != value) {
                // Update the data container
                value = val;
            }
        }

        // On change
        const val = dispatch.call(obj, 'onbeforechange', obj, obj.records[y][x].element, x, y, value);

        // If you return something this will overwrite the value
        if (val != undefined) {
            value = val;
        }

        if (obj.options.columns && obj.options.columns[x] && typeof obj.options.columns[x].type === 'object' && typeof obj.options.columns[x].type.updateCell === 'function') {
            const result = obj.options.columns[x].type.updateCell(obj.records[y][x].element, value, parseInt(x), parseInt(y), obj, obj.options.columns[x]);

            if (result !== undefined) {
                value = result;
            }
        }

        // History format
        record = {
            x: x,
            y: y,
            col: x,
            row: y,
            value: value,
            oldValue: obj.options.data[y][x],
        }

        let editor = obj.options.columns && obj.options.columns[x] && typeof obj.options.columns[x].type === 'object' ? obj.options.columns[x].type : null;
        if (editor) {
            // Update data and cell
            obj.options.data[y][x] = value;
            if (typeof(editor.setValue) === 'function') {
                editor.setValue(obj.records[y][x].element, value);
            }
        } else {
            // Native functions
            if (obj.options.columns && obj.options.columns[x] && (obj.options.columns[x].type == 'checkbox' || obj.options.columns[x].type == 'radio')) {
                // Unchecked all options
                if (obj.options.columns[x].type == 'radio') {
                    for (let j = 0; j < obj.options.data.length; j++) {
                        obj.options.data[j][x] = false;
                    }
                }

                // Update data and cell
                obj.records[y][x].element.children[0].checked = (value == 1 || value == true || value == 'true' || value == 'TRUE') ? true : false;
                obj.options.data[y][x] = obj.records[y][x].element.children[0].checked;
            } else if (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].type == 'dropdown') {
                // Update data and cell
                obj.options.data[y][x] = value;
                obj.records[y][x].element.textContent = getDropDownValue.call(obj, x, value);
            } else if (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].type == 'calendar') {
                // Try formatted date
                let formatted = null;
                if (! validDate(value)) {
                    const tmp = jSuites.calendar.extractDateFromString(value, (obj.options.columns[x].options && obj.options.columns[x].options.format) || 'YYYY-MM-DD');
                    if (tmp) {
                        formatted = tmp;
                    }
                }
                // Update data and cell
                obj.options.data[y][x] = value;
                obj.records[y][x].element.textContent = jSuites.calendar.getDateString(formatted ? formatted : value, obj.options.columns[x].options && obj.options.columns[x].options.format);
            } else if (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].type == 'color') {
                // Update color
                obj.options.data[y][x] = value;
                // Render
                if (obj.options.columns[x].render == 'square') {
                    const color = document.createElement('div');
                    color.className = 'color';
                    color.style.backgroundColor = value;
                    obj.records[y][x].element.textContent = '';
                    obj.records[y][x].element.appendChild(color);
                } else {
                    obj.records[y][x].element.style.color = value;
                    obj.records[y][x].element.textContent = value;
                }
            } else if (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].type == 'image') {
                value = ''+value;
                obj.options.data[y][x] = value;
                obj.records[y][x].element.innerHTML = '';
                if (value && value.substr(0, 10) == 'data:image') {
                    const img = document.createElement('img');
                    img.src = value;
                    obj.records[y][x].element.appendChild(img);
                }
            } else {
                // Update data and cell
                obj.options.data[y][x] = value;
                // Label
                if (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].type == 'html') {
                    obj.records[y][x].element.innerHTML = stripScript(parseValue.call(obj, x, y, value));
                } else {
                    if (obj.parent.config.parseHTML === true) {
                        obj.records[y][x].element.innerHTML = stripScript(parseValue.call(obj, x, y, value, obj.records[y][x].element));
                    } else {
                        obj.records[y][x].element.textContent = parseValue.call(obj, x, y, value, obj.records[y][x].element);
                    }
                }
                // Handle big text inside a cell
                if ((!obj.options.columns || !obj.options.columns[x] || obj.options.columns[x].wordWrap != false) && (obj.options.wordWrap == true || (obj.options.columns && obj.options.columns[x] && obj.options.columns[x].wordWrap == true) || obj.records[y][x].element.innerHTML.length > 200)) {
                    obj.records[y][x].element.style.whiteSpace = 'pre-wrap';
                } else {
                    obj.records[y][x].element.style.whiteSpace = '';
                }
            }
        }

        // Overflow
        if (x > 0) {
            if (value) {
                obj.records[y][x-1].element.style.overflow = 'hidden';
            } else {
                obj.records[y][x-1].element.style.overflow = '';
            }
        }

        if (obj.options.columns && obj.options.columns[x] && typeof obj.options.columns[x].render === 'function') {
            obj.options.columns[x].render(
                obj.records[y] && obj.records[y][x] ? obj.records[y][x].element : null,
                value,
                parseInt(x),
                parseInt(y),
                obj,
                obj.options.columns[x],
            );
        }

        // On change
        dispatch.call(obj, 'onchange', obj, (obj.records[y] && obj.records[y][x] ? obj.records[y][x].element : null), x, y, value, record.oldValue);
    }

    return record;
}
Update cell content

@param object cell
@return void