Bcx-aurelia-reorderable-repeat supresses click


#1

With the following code the reorderable-repeat.for supresses the click in the <a> element.
How should I get the click to bubble-up?

        <div class="list-group">
          <a class="list-group-item ${item.active ? 'active' : ''}" 
             reorderable-repeat.for="item of costing.items"
             reorderable-after-reordering="onOrderChanged" 
             route-href="route: costingEditItem; params.bind:{id: costing.id, index: $index}">
            <div>${item.name}</div>
          </a>
        </div>

Many thanks
Jeremy


#2

Based on my testing, it doesn’t block route-href.

Did you see any error in your console log?


#3

I think you mean params.bind:{id: item.id, index: $index}, not costing.id.


#4

Hi,

No, there is no error in the log, but the route-href is blocked.

params.bind :{id: item.id, index: $index} is correct. The model is:

export class Costing {
id: string;
items: CostingItems[]
}

I need to edit the costing.items[$index] in a separate view. The current view loads the entire costing and then the user selects the costingItem (costing.items[$index])).

I couldn’t work out how to move to a new view (a new page) to edit the costing item which is already loaded as part of costing, so I ended up hacking it by moving to the new route and reloading the costing using the costing.id, and passing through the $index to only show /edit the costing.item[$index]. It’s a stupid way to do it since I already have the correct costing in the first view.

I’m sure that there is a much smarter way to do this, but can’t work it out.

Getting back to the problem with reorderable-repeat.for - it does block the route-href. If I remove the reorderable it works as expected.

The complete code is:

<div class="card">
      <div class="card-header">
        <div class="d-flex justify-content-between mb-2">
          <select class="custom-select" value.bind="selectedCostingItem">
            <option repeat.for="item of costingItems" model.bind="item">${item.name}</option>
          </select>
          <button type="button" class="btn btn-primary ml-2 mr-2" click.delegate="addCostingItem()">
            <i class="fas fa-fw fa-plus"></i>Add costing
          </button>
        </div>
      </div>
      <div class="card-body">
        <div class="list-group">
          <a class="list-group-item ${item.active ? 'active' : ''}" reorderable-repeat.for="item of costing.items"
             reorderable-after-reordering="onOrderChanged" route-href="route: costingEditItem; params.bind:{id: costing.id, index: $index}">
            <div class="">${item.name} </div>
            <div if.bind="!item.isPercent">${item.currency | toCurrency} ${item.value | numberFormat: "0,0.00"} per
              ${item.unit |
              toPerUnit}</div>
            <div else>
              Calculates ${item.percent/100 | numberFormat: "0.00%"} for preceding items
            </div>
            <div>Text for calculation of derived values</div>
          </a>
        </div>
      </div>
   </div>

which produces

<a reorderable-after-reordering="onOrderChanged" route-href="route: costingEditItem; params.bind:{id: costing.id, index: $index}" class="au-target list-group-item" au-target-id="70" href="#/costings/edit/item/-LMH9lAbQBsvLfskNzqQ/1">
            <div class="">Certificate of origin </div>
            <div>CFA 35,000.00 per
              container</div><!--anchor-->
            <!--anchor-->
            <div>Text for calculation of derived values</div>
          </a>

#5

I could not reproduce your problem, it is working fine in my testing code.

Could you try

<div class="card-body" click.trigger="someMethodToLogClick()">...

With normal repeat and reorderable-repeat, to check whether the click is bubbling up?


#6

Oh - I just discovered something interesting.

I am using Chrome - Developer tools.

When I use the device-toolbar to emulate an iPhone the route is blocked. However, if I disable the emulator the route is not blocked.

I just deployed the app and the behaviour continues in the actual app - i.e. on Chrome on my Samsung S7 the route is blocked, but in the browser on my PC it works fine.

I also tried changing the <a> element to button and using this.router.navigateToRoute("costingEditItem", { id: this.costing.id, index }); but it made no difference


#7

OK - I added the
<div class="card-body" click.trigger="someMethodToLogClick()">...

The click bubbles up in the browser but not in mobile.

Removing the reorderable the click bubbles up as expected.


#8

Got it! The bad news is I don’t know how to fix it.

On mobile devices, bcx-aurelia-dnd (reorderable-repeat uses) attached touch event listener to the anchor elements. This prevents mobile browser to simulate normal click event when the anchor is touched.

The mobile browser think: ok you got a touch listener, means you know how to deal with mobile, I don’t need to fall back to legacy click.

Update: bcx-aurelia-dnd only attachs touch event listener at document level. I need to investigate more, maybe there is a solution.


#9

Oh dear!

I really need the functionality of reorderable…

Can you think of a workaround for this?


#10

OK found the workaround (which works fine). I’m just using the handler

         <a class="list-group-item list-group-item-action ${item.active ? 'active' : ''}" route-href="route: costingEditItem; params.bind:{id: costing.id, index: $index}"
             reorderable-repeat.for="item of costing.items" reorderable-after-reordering="onOrderChanged" reorderable-dnd-handler-selector=".handler">
            <div class="">${item.name} </div>
            <div if.bind="!item.isPercent">${item.currency | toCurrency} ${item.value | numberFormat: "0,0.00"} per
              ${item.unit |
              toPerUnit}</div>
            <div else>
              Calculates ${item.percent/100 | numberFormat: "0.00%"} for preceding items
            </div>
            <div>Text for calculation of derived values</div>
            <button class="btn btn-sm btn-primary handler">Drag</button>
          </a>

#11

Use dnd-handler to limit the area responsive to touchstart. Like this:

<a 
  reorderable-repeat.for="item of [1,2,3]"
  reorderable-dnd-handler-selector=".handler"
  route-href="route: dashboard"
>
    <div><span class="handler">[ ]</span> ${item}</div>
</a>

#12

You were faster than me :slight_smile:


#13

Thanks so much for your help - you’re a life saver