UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

363 lines (302 loc) 11.6 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2007 by Tartan Solutions, Inc, http://www.tartansolutions.com License: MIT: https://opensource.org/licenses/MIT Authors: * Dan Hummon ************************************************************************ */ /** * The conditional cell renderer allows special per cell formatting based on * conditions on the cell's value. * * @require(qx.util.format.NumberFormat) */ qx.Class.define("qx.ui.table.cellrenderer.Conditional", { extend : qx.ui.table.cellrenderer.Default, /* ***************************************************************************** CONSTRUCTOR ***************************************************************************** */ /** * @param align {String|null} * The default text alignment to format the cell with by default. * * @param color {String|null} * The default font color to format the cell with by default. * * @param style {String|null} * The default font style to format the cell with by default. * * @param weight {String|null} * The default font weight to format the cell with by default. */ construct : function(align, color, style, weight) { this.base(arguments); this.numericAllowed = ["==", "!=", ">", "<", ">=", "<="]; this.betweenAllowed = ["between", "!between"]; this.conditions = []; this.__defaultTextAlign = align || ""; this.__defaultColor = color || ""; this.__defaultFontStyle = style || ""; this.__defaultFontWeight = weight || ""; }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members : { __defaultTextAlign : null, __defaultColor : null, __defaultFontStyle : null, __defaultFontWeight : null, /** * Applies the cell styles to the style map. * @param condition {Array} The matched condition * @param style {Map} map of already applied styles. */ __applyFormatting : function(condition, style) { if (condition[1] != null) { style["text-align"] = condition[1]; } if (condition[2] != null) { style["color"] = condition[2]; } if (condition[3] != null) { style["font-style"] = condition[3]; } if (condition[4] != null) { style["font-weight"] = condition[4]; } }, /** * The addNumericCondition method is used to add a basic numeric condition to * the cell renderer. * * Note: Passing null is different from passing an empty string in the align, * color, style and weight arguments. Null will allow pre-existing formatting * to pass through, where an empty string will clear it back to the default * formatting set in the constructor. * * * @param condition {String} The type of condition. Accepted strings are "==", "!=", ">", "<", ">=", * and "<=". * @param value1 {Integer} The value to compare against. * @param align {String|null} The text alignment to format the cell with if the condition matches. * @param color {String|null} The font color to format the cell with if the condition matches. * @param style {String|null} The font style to format the cell with if the condition matches. * @param weight {String|null} The font weight to format the cell with if the condition matches. * @param target {String|null} The text value of the column to compare against. If this is null, * comparisons will be against the contents of this cell. * @throws {Error} If the condition can not be recognized or value is null. */ addNumericCondition : function(condition, value1, align, color, style, weight, target) { var temp = null; if (this.numericAllowed.includes(condition)) { if (value1 != null) { temp = [condition, align, color, style, weight, value1, target]; } } if (temp != null) { this.conditions.push(temp); } else { throw new Error("Condition not recognized or value is null!"); } }, /** * The addBetweenCondition method is used to add a between condition to the * cell renderer. * * Note: Passing null is different from passing an empty string in the align, * color, style and weight arguments. Null will allow pre-existing formatting * to pass through, where an empty string will clear it back to the default * formatting set in the constructor. * * * @param condition {String} The type of condition. Accepted strings are "between" and "!between". * @param value1 {Integer} The first value to compare against. * @param value2 {Integer} The second value to compare against. * @param align {String|null} The text alignment to format the cell with if the condition matches. * @param color {String|null} The font color to format the cell with if the condition matches. * @param style {String|null} The font style to format the cell with if the condition matches. * @param weight {String|null} The font weight to format the cell with if the condition matches. * @param target {String|null} The text value of the column to compare against. If this is null, * comparisons will be against the contents of this cell. * @throws {Error} If the condition can not be recognized or value is null. */ addBetweenCondition : function(condition, value1, value2, align, color, style, weight, target) { if (this.betweenAllowed.includes(condition)) { if (value1 != null && value2 != null) { var temp = [condition, align, color, style, weight, value1, value2, target]; } } if (temp != null) { this.conditions.push(temp); } else { throw new Error("Condition not recognized or value1/value2 is null!"); } }, /** * The addRegex method is used to add a regular expression condition to the * cell renderer. * * Note: Passing null is different from passing an empty string in the align, * color, style and weight arguments. Null will allow pre-existing formatting * to pass through, where an empty string will clear it back to the default * formatting set in the constructor. * * * @param regex {String} The regular expression to match against. * @param align {String|null} The text alignment to format the cell with if the condition matches. * @param color {String|null} The font color to format the cell with if the condition matches. * @param style {String|null} The font style to format the cell with if the condition matches. * @param weight {String|null} The font weight to format the cell with if the condition matches. * @param target {String|null} The text value of the column to compare against. If this is null, * comparisons will be against the contents of this cell. * @throws {Error} If the regex is null. */ addRegex : function(regex, align, color, style, weight, target) { if (regex != null) { var temp = ["regex", align, color, style, weight, regex, target]; } if (temp != null) { this.conditions.push(temp); } else { throw new Error("regex cannot be null!"); } }, /** * Overridden; called whenever the cell updates. The cell will iterate through * each available condition and apply formatting for those that * match. Multiple conditions can match, but later conditions will override * earlier ones. Conditions with null values will stack with other conditions * that apply to that value. * * @param cellInfo {Map} The information about the cell. * See {@link qx.ui.table.cellrenderer.Abstract#createDataCellHtml}. * @return {Map} */ _getCellStyle : function(cellInfo) { var tableModel = cellInfo.table.getTableModel(); var i; var cond_test; var compareValue; var style = { "text-align": this.__defaultTextAlign, "color": this.__defaultColor, "font-style": this.__defaultFontStyle, "font-weight": this.__defaultFontWeight }; for (i in this.conditions) { cond_test = false; if (this.numericAllowed.includes(this.conditions[i][0])) { if (this.conditions[i][6] == null) { compareValue = cellInfo.value; } else { compareValue = tableModel.getValueById(this.conditions[i][6], cellInfo.row); } switch(this.conditions[i][0]) { case "==": if (compareValue == this.conditions[i][5]) { cond_test = true; } break; case "!=": if (compareValue != this.conditions[i][5]) { cond_test = true; } break; case ">": if (compareValue > this.conditions[i][5]) { cond_test = true; } break; case "<": if (compareValue < this.conditions[i][5]) { cond_test = true; } break; case ">=": if (compareValue >= this.conditions[i][5]) { cond_test = true; } break; case "<=": if (compareValue <= this.conditions[i][5]) { cond_test = true; } break; } } else if (this.betweenAllowed.includes(this.conditions[i][0])) { if (this.conditions[i][7] == null) { compareValue = cellInfo.value; } else { compareValue = tableModel.getValueById(this.conditions[i][7], cellInfo.row); } switch(this.conditions[i][0]) { case "between": if (compareValue >= this.conditions[i][5] && compareValue <= this.conditions[i][6]) { cond_test = true; } break; case "!between": if (compareValue < this.conditions[i][5] || compareValue > this.conditions[i][6]) { cond_test = true; } break; } } else if (this.conditions[i][0] == "regex") { if (this.conditions[i][6] == null) { compareValue = cellInfo.value; } else { compareValue = tableModel.getValueById(this.conditions[i][6], cellInfo.row); } var the_pattern = new RegExp(this.conditions[i][5], 'g'); cond_test = the_pattern.test(compareValue); } // Apply formatting, if any. if (cond_test == true) { this.__applyFormatting(this.conditions[i], style); } } var styleString = []; for(var key in style) { if (style[key]) { styleString.push(key, ":", style[key], ";"); } } return styleString.join(""); } }, /* ***************************************************************************** DESTRUCTOR ***************************************************************************** */ destruct : function() { this.numericAllowed = this.betweenAllowed = this.conditions = null; } });