0

I can add validators to fields. But I want that validator to be active only when I use the like operator.

In this example, if I used the like or unlike operators in the phoneNumber field, I expect it to be invalid since I did not use the % sign. If I used the or = operator, I should not be able to use the % sign.

How can I set this depending on the operator used?

NOTE: Also defaultValidator is not working. I think it's because I use this "import { QueryBuilderAntD } from '@react-querybuilder/antd';" . I am not sure

import React, {useEffect, useState} from 'react';
import {Button, Modal, Row} from "antd";
import {formatMessage} from "umi";
import {CloseCircleOutlined, SelectOutlined} from "@ant-design/icons";
import TextArea from "antd/es/input/TextArea";
import {QueryBuilder, defaultValidator, formatQuery, parseSQL} from "react-querybuilder";
import 'react-querybuilder/dist/query-builder.css';
import {QueryBuilderAntD} from "@react-querybuilder/antd";

const options = [
    { name: '=', label: '=' },
    { name: '!=', label: '!=' },
    { name: 'like', label: 'like' },
    { name: 'notLike', label: 'not like' },
];

const fields = [
    {name: 'phoneNumber', validator: ({ value }) => /^(%)[0-9]*$/.test(value) , label: formatMessage({id: 'label.phoneNumber'}), operators: options},
    {name: 'passportNumber', label: formatMessage({id: 'label.passportNumber'}), operators: options, inputType: 'number'},
];

const initialQuery = {
    combinator: 'and',
    rules: [
        {
            field: 'phoneNumber',
            value: '7788',
            operator: 'notLike',
        },
        {
            combinator: 'and',
            rules: [
                {
                    field: 'passportNumber',
                    value: '3334445566',
                    operator: '=',
                },
                {
                    field: 'phoneNumber',
                    value: '%6665544',
                    operator: 'like',
                },
            ],
        },
        {
            combinator: 'or',
            rules: [
                {
                    field: 'phoneNumber',
                    value: '3334445566',
                    operator: '=',
                },
            ],
        },
    ]
};

const Panel = (props) => {
    const [query, setQuery] = useState(initialQuery)
    const [queryText, setQueryText] = useState(null)

    useEffect(()=>{
        let text = formatQuery(query, 'sql')
        setQueryText(text === "(1 = 1)" ? "" : text)
    },[query]);

    useEffect(()=> {
        if (props.filterValue){
            let sorgu = parseSQL(props.filterValue)
            setQuery(sorgu)
        }
    }, [props.filterValue]);

    const onModalSelectBtnClick = () => {
        if (props.callValue) {
            props.callValue(query);
        }
        props.closeModal();
    };

    const onModalCancelBtnClick = () => {
        props.closeModal();
    };

    const clearQuery = () => {
        setQuery(initialQuery)
    };

    const selectQuery = () => {
        let text = formatQuery(query, 'sql')

        props.callValue(text === "(1 = 1)" ? null : text)
        props.closeModal();
    };

    return (
        <Modal
            title={formatMessage({id: 'label.LEXP_CDR'})}
            visible={props.visibleCallModal}
            onCancel={onModalCancelBtnClick}
            destroyOnClose={true}
            width="35%"
            style={{top: '5%'}}
            footer={[
                <Button type="primary" onClick={clearQuery} style={{marginRight: '362px'}}>
                    {formatMessage({id: 'button.clear'})}
                </Button>,
                <Button type="primary" onClick={selectQuery} icon={<SelectOutlined/>}>
                    {formatMessage({id: 'button.select'})}
                </Button>,
                <Button type="primary" onClick={onModalCancelBtnClick} icon={<CloseCircleOutlined/>}>
                    {formatMessage({id: 'button.cancel'})}
                </Button>
            ]}>
            <div>

                <QueryBuilderAntD>
                    <QueryBuilder
                        fields={fields}
                        query={query}
                        onQueryChange={q => setQuery(q)}
                        validator={defaultValidator}
                    />
                </QueryBuilderAntD>

                <Row gutter={3}>
                    <TextArea name="query" value={queryText}/>
                </Row>

            </div>
        </Modal>
    );
};


export default Panel;

1 Answer 1

1

If you don't destructure the value here "validator: ({ value })" and just pass the whole object as a operator, like that "validator: (query)", then you can access your operator like query.operator and you can use it for conditional validation based on the operator. It worked for me when I used the validator.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.