Dynamic events handlers vs static ones?

I don’t know the difference between static event handlers from the properties panel or dynamic ones that you can find in the autocompletion when you write the element. I understand that, with dynamic ones, I can write more than one handler, but I could just do all of that in the same static handler.

Also, I don’t understand when I do have to declare $item = $w.at(event.context) or just use $w to select items. Is it in all handlers? Or just with repeater elements?

Thank you in advance.

Hi Dani :raised_hand_with_fingers_splayed:

With static handlers, you can only write one for each element, while dynamic handlers can be used as much as you want, for example, you want the button to redirect you to your profile if you’re logged in, or prompt you to login if you’re not, this behavior can be achieved with both handlers.

Also, dynamic handlers can completely change the core of the event handler, for example.

if (user.loggedIn) {
    $w('#loginButton').onClick((event) => {
        wixLocation.to('/profile')
    })
} else {
    $w('#loginButton').onClick((event) => {
        wixWindow.openLightbox('Sign Up')
    })
}

Notice how the behavior of the event handler changed dynamically based on some factors.

Now regarding the selectors ($w and $Item), the $w selector is a global selector, while the $Item is not, and typically used in repeaters with items to perform actions on some of the repeated item, and not all of them, for example, in a friends list, a repeater is used to display each member data, and a call-to-action button called “Follow”, and you only want to show this button for members who want to be followed.

If you use this code, it’ll enable all the buttons regardless of users decisions:

if (itemData.wantsToBeFollowed) {
    $w('#followBtn').enable();
}

But if you use this code, it’ll only enable the Follow button for those who wants to be followed.

if (itemData.wantsToBeFollowed) {
    $Item('#followBtn').enable();
}

Of course assuming that all of this code is inside a repeater’s onItemReady() function.

Hope that gives you better understanding.
Ahmad

I have one question. Can I do a ‘group’ event handler by creating an array with checkbox elements and doing the following thing:

array.forEach(element=>{
    element.onClick(()=>{
    //Do whatever here
    })
})

It is not working for me.

Thank you!

By the way, that was an awesome explanation! Got it perfectly!! Thanks again!

If you have their ID in the array, yes you can, but I prefer using a For…loop instead, here’s how:

for (let i = 1; i < array.length; i++) {
    let id = `element${i}`;
    
    $w(id).onClick((event) => {
        // And onClick event that will run for each and every     element
    })
}

Hey Ahmad! Thanks again. I don’t quite understand the second line of code.
What are element${1}, element${2}, etc?

My arrays are like this:

const instrMig = [$w('#violi'),$w('#viola'),$w('#cello'),$w('#piano')];
const assigMig = [$w('#jm1'),$w('#jm2'),$w('#rm')]

Should I just have the id’s in the array? And if so, with or without the #?

What I want is that while any ‘assigMig’ is checked, to be able to interact with instrMig since it’s at first disabled.

Thank you :slight_smile:

I didn’t know what is the exact structure of your arrays, I just gave a general example.

Here’s a piece of code that will work for you:

const instrMig;
const assigMig;

$w.onReady(async () => {

   instrMig = [$w('#violi'), $w('#viola'), $w('#cello'), $w('#piano')];
    assigMig = [$w('#jm1'), $w('#jm2'), $w('#rm')]

    for (let i =0; i < instrMig.length; i++) {
        let element = instrMig[i];
        
        element.onChange(async(event) => {
            if (element.checked) {
                await enableElements();
            } else {
                await checkElements();
        }}
     )}
})


function enableElements() {
    for (let j =0; j < assigMig.length; j++) {
        let element = assigMig[i];
        
        element.enabled = true;
    }
}

function checkElements() {
      let allChecked;
      for (let i =0; i < instrMig.length; i++) {
          let element = instrMig[i];
          
          if (element.checked) {
              allChecked = true;
          }
      }
      
      if (allChecked) {
          await enableElements();
      }
}

This will create an onChange() event handler to enable all the other elements if it was checked, and check if there’s any other checked elements, and if there is, enable all.

Hope that helped!
Ahmad

That’s perfect! Thank you :slight_smile:

You’re welcome Dani