UNPKG

@quantlab/handsontable

Version:

Spreadsheet-like data grid editor that provides copy/paste functionality compatible with Excel/Google Docs

239 lines (191 loc) 6.4 kB
import {fastInnerText, addClass, removeClass} from './../helpers/dom/element'; import {stringify} from './../helpers/mixed'; import {getRenderer} from './index'; import {isNumeric} from './../helpers/number'; import numbro from 'numbro'; function isFormula(value) { if (value) { if (value[0] === '=') { return true; } } return false; } /** * @private * @renderer formulaRenderer * @param instance * @param TD * @param row * @param col * @param prop * @param value * @param cellProperties */ function formulaRenderer(instance, TD, row, col, prop, value, cellProperties) { getRenderer('base').apply(this, arguments); ['fontWeight', 'fontStyle', 'color', 'background'].forEach( property => { TD.style[property] = cellProperties[property]; }); if (isFormula(value)) { // translate coordinates into cellId var cellId = instance.formula.utils.translateCellCoords({ row: row, col: col }), prevFormula = null, formula = value.substr(1).toUpperCase(), needUpdate = false, newValue = null, currentItem = null, error, result; // try formula matrix, see if it's already in it var item = instance.formula.matrix.getItem(cellId); if (item) { // formula in matrix needUpdate = !! item.needUpdate; prevFormula = item.formula; error = item.error; if (needUpdate) { error = null; currentItem = item; // parse formula newValue = instance.formula.parse(formula, { row: row, col: col, id: cellId }); } else { value = item.error || item.value; } } else { // formula not in matrix yet // parse formula newValue = instance.formula.parse(formula, { row: row, col: col, id: cellId }); item = { id: cellId, formula: formula, error: newValue.error, value: newValue.result }; // add item to matrix currentItem = instance.formula.matrix.addItem(item); } if(newValue){ if(newValue.result != null && typeof newValue.result == 'object'){ // kernel async formula if(typeof newValue.result.onIOPub == 'function'){ // kernel formula newValue.result.onIOPub = function(msg){ if(msg.content){ if(msg.content.hasOwnProperty('data')){ var result = JSON.parse(msg.content.data['text/plain'].replace(/\'/g,'"')); // only set left upper corner of matrix var leftUp = result[1]; if(Array.isArray(leftUp)){ leftUp = leftUp[0]; if(Array.isArray(leftUp)){ leftUp = leftUp[0]; } } instance.formula.matrix.updateItem(currentItem, { formula: formula, value: leftUp, error: newValue.error, needUpdate: false }); // for now only kernel async formulas might return matrix if(Array.isArray(result[1])){ var matrix; if(Array.isArray(result[1][0])){ matrix = result[1]; } else{ matrix = [result[1]]; } matrix[0][0] = value; instance.populateFromArray(row,col,matrix); //value = newValue.error || leftUp; } else { // scalar var escaped = stringify(result.join('')); fastInnerText(TD, escaped); } } } } }else{ // regular sync matrix formulas // only set left upper corner of matrix var leftUp = newValue.result; if(Array.isArray(leftUp)){ leftUp = leftUp[0]; if(Array.isArray(leftUp)){ leftUp = leftUp[0]; } } instance.formula.matrix.updateItem(currentItem, { formula: formula, value: leftUp, error: newValue.error, needUpdate: false }); var matrix; if(Array.isArray(newValue.result[0])){ matrix = newValue.result; } else{ matrix = [newValue.result]; } matrix[0][0] = value; instance.populateFromArray(row,col,matrix); value = newValue.error || leftUp; } }else{ // regular sync scalar forumula instance.formula.matrix.updateItem(currentItem, { formula: formula, value: newValue.result, error: newValue.error, needUpdate: needUpdate }); error = newValue.error; result = newValue.result; value = error || result; } } if (error) { // clear cell value if (!value) { // reset error error = null; } else { // show error value = error; } } // change background color if (instance.formula.utils.isSet(error)) { addClass(TD, 'formula-error'); } else if (instance.formula.utils.isSet(result)) { removeClass(TD, 'formula-error'); addClass(TD, 'formula'); } } /* if (cellProperties.type == 'numeric' && isNumeric(value)) { value = numbro(value).format(cellProperties.format || '0.00'); const className = cellProperties.className || ''; let classArr = className.length ? className.split(' ') : []; if (classArr.indexOf('htLeft') < 0 && classArr.indexOf('htCenter') < 0 && classArr.indexOf('htRight') < 0 && classArr.indexOf('htJustify') < 0) { classArr.push('htRight'); } if (classArr.indexOf('htNumeric') < 0) { classArr.push('htNumeric'); } cellProperties.className = classArr.join(' '); } */ var escaped = stringify(value); fastInnerText(TD, escaped); } export default formulaRenderer;