How to custom DataValidator more deeper and set multiple validator into a cell

Posted by: nguyenvu.work on 16 August 2023, 6:06 am EST

    • Post Options:
    • Link

    Posted 16 August 2023, 6:06 am EST - Updated 11 January 2024, 2:40 pm EST

    Scenario 1: For a specific cell, I need the value to be in date format, and must is not empty. Unfortunately, I can only assign one validator to a single cell. Is there any workaround for this limitation?

    Scenario 2: Within my table, when both the “type” and “value” cells are on the same row, I want the “value” cell to be [1, 2, 3] if the “type” cell is set to “number”. Alternatively, if the “type” cell is set to “text”, the “value” cell should be [x, y, z]. Can I achieve this using validators?

    Scenario 3: I possess a “function” designed to validate cell values, determining their validity. How can I associate this “function” with a cell as a validator?

    Note: Is it possible for a single cell to have all of the mentioned validators simultaneously?

  • Posted 17 August 2023, 4:48 am EST

    Hi Nguyen,

    Kindly confirm the technology you are using, so that we can address the case accordingly.

    Furthermore, we would appreciate if you specify the technology used while posting a case on this general forum (DevChannel) in the future. We also have separate forums for various technologies.

    Please check the following link for the same: https://www.grapecity.com/forums

    Thanks & Regards,

    Aastha

  • Posted 17 August 2023, 5:22 am EST

    Sr my bad, I am using SpreadJs and want to customize DataValidator but I cannot find the documents for that

  • Posted 17 August 2023, 6:48 am EST

    Sr my bad, I am using SpreadJs and want to customize DataValidator but I cannot find the documents for that.

    And How I can change the hightLightStype color dependend on the “value”. Like "It will be red if value = “1”, yellow if value = “2” "

  • Posted 18 August 2023, 8:25 am EST

    Hi,

    Please find below the answers to your queries:

    Scenario1: Yes, currently only one validatior is applied to a cell in SpreadJS. This is the same behavior as Microsoft Excel.

    For your use case, you could create a formula validator and inside the formula validator, pass a custom function that returns true or false, based on whatever criteria you want to check.

    You could check if the value is of type Date or other validations. To check if the value is not empty, you could use the ignoreBlank() method and pass false as its argument.

    Kindly refer to the following code snippet and the sample:

    Create Custom Function
    // Create Custom Function
    function CustomFunction() {
        this.name = "CUSTOMFN";
        this.maxArgs = 1;
        this.minArgs = 1;
    }
    CustomFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
    // Return true or false from the custom function based on the value
    CustomFunction.prototype.evaluate = function (arg) {
        // Check if the argument is null
        if (!arg) {
            return false;
        }
    
        // Try to create a new Date object using the value
        const date = new Date(arg);
    
        // Check if the Date object is valid and the value is not 'Invalid Date'
        return date instanceof Date && !isNaN(date);
    };
    
    var customFn = new CustomFunction();

    Apply the Data Validator to the Cell:

        // Add the formula validator to the cell
        let dv = GC.Spread.Sheets.DataValidation.createFormulaValidator("CUSTOMFN(C3)");
        dv.showInputMessage(true);
        dv.inputMessage("Must be in a date format and not empty");
        dv.inputTitle("Must be in a date format and not empty");
        // Set the ignore blank to false
        dv.ignoreBlank(false);
        sheet.setDataValidator(2, 2, 1, 1, dv, GC.Spread.Sheets.SheetArea.viewport);
    

    References:

    Custom Function Demo: https://www.grapecity.com/spreadjs/demos/features/calculation/custom-functions/purejs

    Custom Validation Demo: https://www.grapecity.com/spreadjs/demos/features/cells/data-validation/custom-data-validator/purejs

    createFormulaValidator: https://www.grapecity.com/spreadjs/api/v15/modules/GC.Spread.Sheets.DataValidation#createdatevalidator

    ignoreBlank method: https://www.grapecity.com/spreadjs/api/v15/classes/GC.Spread.Sheets.DataValidation.DefaultDataValidator#ignoreblank

    Sample: https://jscodemine.grapecity.com/share/ErbUM8K18EWi3SUJgni3aA/?IsEmbed=false&Theme=Unset&PreviewDirection=0&IsEditorShow=true&IsExplorerShow=true&IsPreviewShow=true&IsConsoleShow=true&IsRunBTNShow=false&IsResetBTNShow=false&IsOpenInCodemineBTNShow=false&PanelWidth=20&PanelWidth=50&PanelWidth=30&defaultOpen={"OpenedFileName"%3A["%2Findex.html"%2C"%2Fsrc%2Fapp.js"%2C"%2Fpackage.json"]%2C"ActiveFile"%3A"%2Fsrc%2Fapp.js"}

    Scenario2: I couldn’t understand your requirement clearly. As per my understanding, you want to have different value in a column based on a value in some other column. If this is the case, you might use the “value” method and pass it to the TableColumn Class.

    You could refer to the following API reference on value method: https://www.grapecity.com/spreadjs/api/v16/classes/GC.Spread.Sheets.Tables.TableColumn#value

    You could also refer to the following demo on Data Binding Demo that uses the value method to add “$” to the cost column: https://www.grapecity.com/spreadjs/demos/features/tables/table-binding/purejs

    Further, you could apply the CustomFormat on the cell and show whatever value you want to show in the cell. Refer to the following demo on Custom Format: https://www.grapecity.com/spreadjs/demos/features/cells/formatter/custom-formatter#demo_source_name

    If your issue is still not resolved, I request you to kindly elaborate your use case with an example so that we could have a better understanding of your use case and could assist you accordingly.

    Scenario3: You could create the custom function as defined above in Scenario1. The custom function can be used a function designed to validate the cell values. You could use the same approach as defined in Scenaio1.

    Regarding changing the color of the highlight color of DataValidator, currently it is not supported in SpreadJS(not supported in Microsoft Excel) as well.

    Please let us know if you face any issues.

    Regards,

    Ankit

  • Posted 24 August 2023, 11:40 pm EST - Updated 24 August 2023, 11:58 pm EST

    @ankit.kumar

    • Hi, I found other solution. I customized DefaultDataValidator for my specific purpose.
    export class CustomDefaultValidator extends GC.Spread.Sheets.DataValidation.DefaultDataValidator {
      private errorColor: string =  "red";
      private message: string[] = [];
      constructor() {
        super();
      }
    
      override isValid(currentSheet: Worksheet, row: number, col: number, value: Object) {
        const errors: string[] = [];
        const isNotEmpty = this.checkNotEmpty(errors, value);
        if (isNotEmpty) {
          this.a(errors, value, col);
          this.b(errors, value as string, col);
        }
    
        this.message = errors;
        return errors.length === 0;
      }
    
      override highlightStyle(): Object {
        return {
          type: GC.Spread.Sheets.DataValidation.HighlightType.dogEar,
          color: this.errorColor,
          position: GC.Spread.Sheets.DataValidation.HighlightPosition.topLeft,
        };
      }
    
      override inputMessage() {
        return this.message.length > 0 ? this.message.join('\n') : undefined;
      }
    }
    
    
    • It works! But I got other problem with “inputMessage” method, If I add “inputMessage” then call function toJSON (from workbook or workSheet), I got an error “c[b].isDefault is not a function”. If I remove “inputMessage” overided method, everything works normally!

    • By the way! I did so for getting last RowIndex Which contain value (by extract to JSON and get last RowIndex from “sheetAsJson.data?.dataTable”). Are there any better way ?

      (It be like I want to add new row to the last of table. “Last row Index” which contain value, not “row count”) in a sheet!

  • Posted 25 August 2023, 8:05 am EST

    Hi,

    Override the inputMessage as

        inputMessage(message: string): string {
            const isDefault = () => this.message.length === 0;
            (this.inputMessage as any).isDefault = isDefault;
            return this.message.length > 0 ? this.message.join('\n') : undefined;
        }

    The inputMessage requires isDefault and therefore it was giving the mentioned error.

    For getting the last nonempty row, you could use the getUsedRange method:

        // Get the Last Row
        let usedRange = sheet.getUsedRange(GC.Spread.Sheets.UsedRangeType.data);
        console.log("Last Row " + (usedRange.row + usedRange.rowCount - 1));

    Sample: https://jscodemine.grapecity.com/share/BBjdit4bu0SH67YSipizRw/?IsEmbed=false&Theme=Unset&PreviewDirection=0&IsEditorShow=true&IsExplorerShow=true&IsPreviewShow=true&IsConsoleShow=true&IsRunBTNShow=false&IsResetBTNShow=false&IsOpenInCodemineBTNShow=false&PanelWidth=20&PanelWidth=50&PanelWidth=30&defaultOpen={"OpenedFileName"%3A["%2Fsrc%2Fapp.ts"]%2C"ActiveFile"%3A"%2Fsrc%2Fapp.ts"}

    References:

    getUsedRange method: https://www.grapecity.com/spreadjs/api/v15/classes/GC.Spread.Sheets.Worksheet#getusedrange

    usedRangeType Enumeration: https://www.grapecity.com/spreadjs/api/v15/enums/GC.Spread.Sheets.UsedRangeType

    Regards,

    Ankit

  • Posted 27 August 2023, 11:18 pm EST

    @ankit.kumar

    • Hi, Thanks you so much for your help
Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels