[RESOLVED] Accordion prevent open?

Hi there,

I have an accordion list, where I’d like to add a check condition to each item, which decides whether to allow the accordion to open or not. If the condition fulfills, then there’s one futher step: I’d like to invoke an ajax call to get the content data of the accordion. As I see the accordion’s code, there’s no such event (beforeOpen or anything like that).
Is there a way to achieve a result like this?

Thanks,
Bálint

You are right, there is no such thing. Just pushed commit where added accordion:beforeopen event with a prevent open method as argument

Gosh, this was fast as lightning! :slight_smile:

Found a small typo, sent a PR to fix it:

Thanks,
Bálint

1 Like

Sorry, one more question here: how to get the reference of the item being opened and the prevent function in the eventhandler?

If the code looks like this, then I have no access to the prevent function in onBeforeOpen:

<f7-accordion-item v-for=“item in itemList” @accordion:beforeopen=“onBeforeOpen(item)”>

While if the code looks like this, then I have no access to the selected item in onBeforeOpen:

<f7-accordion-item v-for=“item in itemList” @accordion:beforeopen=“onBeforeOpen”>

I’d need both of them (the item and the prevent reference) - as I can only decide whether to prevent opening based on the item properties.

Cheers,
Bálint

<f7-accordion-item v-for="item in itemList" @accordion:beforeopen="onBeforeOpen">
{
  methods:{
    onBeforeOpen:function(e){
      console.log(e.target)
    }
  }
}

Or accordion:beforeopen=“onBeforeOpen(item, $prevent)”

Thanks for the advice, but I’m afraid e.target will be undefined as e is the prevent function reference itself.

Probably I’m totally misunderstanding how it should go, but if using this code:
@accordion:beforeopen="onBeforeOpen(item, $prevent)"

I get the following (fairly clear) error message:
[Vue warn]: Property or method "$prevent" is not defined on the instance but referenced during render.

methods:{
  onBeforeOpen:function(e){
    console.log(e.target)
    var flag=true;//or false
    if (flag) { e.detail.prevent(); }   
  }
}

Thanks, it was perfectly clear. I had two problems: first, as I wrote, e is not the event object, but only the prevent function reference - thus it doesn’t have a target prop. I fixed it in this PR.

On the other hand, if I get the event object in the eventhandler, than I lose the bound item object reference - even though it would be useful. This can be worked around by binding it’s certain properties to DOM dataset items which are necessary in the eventhandler to decide whether the open action should be prevented or not.

If there’s a more elegant way (e.g. passing both the event and the item instance as args), please let me know.

Thanks,
Bálint

i see

look like it is not possible
but only vladimir can confirm it

meanwhile:

<li class="accordion-item" 
    data-context='{"foo":"bar","prevent":true}' 
    @accordion:beforeopen="onBeforeOpen"
>
onBeforeOpen:function(e){
  var c=JSON.parse(this.$$(e.target).attr('data-context'));
  if (c.prevent) { e.detail.prevent(); }
}

My bad, in Vue inline event handler it is possible to pass event argument as $event keyworkd, so this will work:

@accordion:beforeopen="onBeforeOpen(item, $event)"

But it also possible to bypass all original event arguments like

@accordion:beforeopen="onBeforeOpen(item, ...arguments)"

So with latest commit handler will look like:

onBeforeOpen(item, event, prevent) {
  ...
}

Thanks, Vladimir!
Works as expected. :slight_smile: