conditionize2.js icon indicating copy to clipboard operation
conditionize2.js copied to clipboard

Trigger an event after the state of a condition changed

Open Seb33300 opened this issue 3 years ago • 6 comments

Hello,

I need to detect when a condition has been triggered in order to run some extra process.

I tried to do something like this:

$('...').conditionize({
    ifTrue: [
        // ...
        function ($s) { $s.trigger('my-event-name'); }
    ],
    ifFalse: [
        // ...
        function ($s) { $s.trigger('my-event-name'); }
    ]
});

But unfortunately, the event is fired as many times as we have elements related to the condition. (If I have 10 elements using the same data-condition, the event is triggered 10 times, every time the condition has changed)

It will be very useful if conditionize2 could natively fire some events that we can listen when conditions are triggered (eg conditionize.before / conditionize.after)

Seb33300 avatar Nov 19 '22 10:11 Seb33300

Hello,

Thank you for your feedback. I am not sure, I am getting your idea.

  1. You can relate a specific element separately, i.e.
$('#your_specific_element').conditionize(...)
$('.other_elements').condidtionize(...)
  1. How conditionize.before / conditionize.after is different from
$('...').conditionize({
    ifTrue: [
        // ...
        function ($s) { $s.trigger('my-event-name'); }
    ],
    ifFalse: [
        // ...
        function ($s) { $s.trigger('my-event-name'); }
    ]
});

?

rguliev avatar Nov 19 '22 23:11 rguliev

Hello,

I checked again and I can confirm this is working properly.

The issue I am encountering is a little bit different and made me confused. In reality, I am looking for a "state changed" event.

This is a specific case that can occur for example when working with multiple values input (returning an array of values). If I put a condition based on a specific element from the list. My event is triggered every time any element of the list is modified. Even if this is not changing the state of my condition (it was false before, and remains false after)

Here is an exemple to make this clearer: https://jsfiddle.net/8jy16go7/

Seb33300 avatar Nov 20 '22 05:11 Seb33300

Another way to fix this could be to not rerun condition functions if the state did not change.

Seb33300 avatar Nov 20 '22 11:11 Seb33300

From your example, I feel like the problem is that you are combining two different conditions but then want to trigger an event only for one specific condition. I.e. for your example, I would suggest:

$('.conditional1').conditionize( //here you trigger your event// )
$('.conditional2').conditionize( //here you do not trigger the event// )

rguliev avatar Nov 20 '22 11:11 rguliev

Actually, the same issue happens also with a single condition. See https://jsfiddle.net/Lzuqets7/

What happens:

On page load:

  1. conditionize is initialized on the <p> and data-condition returns false
  2. Current state of <p> is undefined (it's page load, we dont know the element state yet)
  3. false !== undefined => conditionize executes functions defined in the ifFalse option (working as expected)

On checkbox change:

  1. If I click on checkbox 2, it triggers conditionize on <p> and data-condition still returns false
  2. Current state of <p> is already false (initialized on page load)
  3. false === false => nothing should happen here, because the <p> is already in the state false so we can skip to execute functions defined in the ifFalse option
  4. But this is not what happens, the execution of functions defined in ifFalse is triggered all the time, even if the element is already in the same state, resulting in my event fired.

ifFalse / ifTrue should be executed only in case of different state:

  1. If I click on checkbox 1, it triggers conditionize on <p> and data-condition returns true
  2. Current state of <p> is false
  3. true !== false => conditionize executes functions defined in the ifTrue option

Seb33300 avatar Nov 20 '22 14:11 Seb33300

Thank you for the explanation. Now I got it. A simple workaround at the moment could be:

let state = null;
$('.conditional1').conditionize({
  ifTrue: [
    'show',
    function ($s) {
      if (!state) {
        state = true;
        $s.trigger('my-event-name'); 
      }
    }
  ],
  ifFalse: [
    'hide',
    function ($s) {
      if (state) {
        state = false;
        $s.trigger('my-event-name'); 
      }
    }
  ]
});

However, I agree that it would be a good improvement to the package. I will keep this issue open.

rguliev avatar Nov 21 '22 22:11 rguliev