0

I'm using jQuery QueryBuilder, and I noticed that when changing the left-hand side field, the operator resets automatically. I understand this is built-in behavior since different fields may support different operators.

Looking into the source code, I found this behavior in core.js:

// set the operator without triggering update event  
if (rule.filter.default_operator) {  
    rule.__.operator = this.getOperatorByType(rule.filter.default_operator);  
}  
else {  
    rule.__.operator = operators[0];  
}

(Reference: QueryBuilder Source Code)

However, in my use case, I'd like to retain the previously selected operator whenever possible.

Is there a way to override this behavior and prevent the operator from resetting unnecessarily? Any suggestions or workarounds would be greatly appreciated!

2 Answers 2

0

You can fix this by adding some JavaScript that listens for when you change the filter in QueryBuilder. Here's how to do it:

$('#builder').on('afterUpdateRuleFilter.queryBuilder', function(e, rule, previousFilter) {
    // Only try to preserve the operator if there was a previous filter
    if (previousFilter && rule.filter) {
        var previousOperator = rule.operator;

        // Get the list of valid operators for the new filter
        var newOperators = rule.queryBuilder.getOperators(rule.filter);

        // Check if the old operator is still good with the new filter
        var operatorFound = newOperators.find(function(op) {
            return op.type === previousOperator.type;
        });

        if (operatorFound) {
            // If it's good, keep using the old operator
            rule.$el.find(QueryBuilder.selectors.rule_operator).val(previousOperator.type);
            rule.operator = previousOperator;
        }
    }
});

What this code does is it checks every time you change a filter to see if you can keep using the same operator (like equals, not equals, etc.). If the operator can still be used with the new filter, it doesn't change it.

This way, the operator won't reset every time you change the filter, making things less annoying and more consistent.

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

Comments

0

We can fix this by keeping track of the operator for each rule.

const [ruleOperators, setRuleOperators] = useState({});

We can do that by using afterUpdateRuleOperator.queryBuilder

   $('#builder').on('afterUpdateRuleOperator.queryBuilder', (e, rule) => {
       setRuleOperators(prev => ({
          ...prev,
          [rule.id]: rule.operator,
       }));
    });

Then update the rule with previous operator immediately after changing the field using afterUpdateRuleFilter.queryBuilder

   $('#builder').on('afterUpdateRuleFilter.queryBuilder', (e, rule) => {
      const prevOp = ruleOperators[rule.id];

      if (prevOp) {
        rule.operator = prevOp;
        $('#builder').queryBuilder('trigger', 'afterUpdateRuleOperator', rule);
      }
    });

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.