1

I'm creating an application using Aurelia, and in part of that application I have a grid that lists users, and specifically that users active status.

To allow the active state to be edited I've created a slide button control (Similar to those seen in iOS) where, sliding to the left is true, and to the right is false.

What I'd like to do is use this control in my user grid, so that people using it, can just click on the custom slide button to enable/disable the user, but I need that control to feed it's value when it changes back to the row it's placed in.

Something like this:

Imagine my table looks like this

<table>
  <thead> 
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Email</th>
      <th>Is Active?</th>
    </tr>
  </thead>
  <tbody>
    <tr repeat.for="user of userList">
      <td>${user.id}</td>
      <td>${user.name}</td>
      <td>${user.email}</td>
      <td><slidebutton active="${user.active}"></slidebutton></td>
    </tr>
  </tbody>
</table>

This works great in so much that the slide button gets set to a default value based on the active status of the user as expected.

However when the slide button is changed, I would like for the row to be notified in someway, so that I can tell it to update the back end and change the status.

I'm not against passing in the user id to the custom component EG:

<td><slidebutton active="${user.active}" uid="${user.id}"></slidebutton></td>

But i'd rather not have the control make the call, or be doing anything that prevents me from using it in other places, such as on other grids that might have different items of toggle-able information.

I had thought of an event based way of doing it, then I looked at one of the user tables and saw there was a potential for a table with over 500 rows in it, and tracking/managing 500 events from 500 slide buttons didn't really seem like something I'd particularly want to do.

If there's a way of reflecting the value back into the attribute, then that I think would be a great start, but what I'd actually like if at all possible, is for the custom control to directly change the underlying view model on the row if at all possible.

shawty
  • 5,729
  • 2
  • 37
  • 71

1 Answers1

5

You can easily set up two-way databinding. First off, you should probably switch over to using the .bind syntax instead of using string interpolation to pass values in. This is because using string interpolation will convert your values to strings, while the .bind syntax can preserve the type of whatever you are passing in. It also works for binding in objects and the such.

 <td><slidebutton active.bind="user.active" uid.bind="user.id"></slidebutton></td>

We can change .bind to .two-way in the example code above, and this will tell Aurelia that these bindings need to be two-way. That will accomplish what you want, but it would be annoying to always have to do this:

 <td><slidebutton active.two-way="user.active" uid.bind="user.id"></slidebutton></td>

Note that I only set the active property to be two-way databound, as I'm guessing the uid property isn't changed inside the slidebutton control, and thus there's no need to do two way databinding on it.

But we can set this up to default to two-way databinding. Let's look at how to do this. I'm sure you've already created the bindable properties for active and uid in the slidebutton custom element. I'm betting they look like this (in ESNext):

 @bindable active;
 @bindable uid;

If we add a bit of configuration to these, we can set these properties to default to two-way databinding, and then you'll get the two-way databinding that you seek by default.

 @bindable({ defaultBindingMode: bindingMode.twoWay }) active;
 @bindable uid;

Note that I'm using bindingMode.twoWay above. You'll need to import this enum from the aurelia-framework module. Thus, you might have something like the following line at the top of the slidebutton's view model file:

 import {bindable, bindingMode} from 'aurelia-framework';

Once you've done this, you can go back to using active.bind="user.active" and Aurelia will handle the two-way databinding for you.

Ashley Grant
  • 10,879
  • 24
  • 36
  • Awesome, and yet again Ashley your there on the ball :-) Let me go play with that and see what happens. I'm actually having a problem with the @binding on another component at the moment, and your reply may ALSO have sorted that one too ;-) – shawty Apr 07 '17 at 15:35
  • JUst to let you know, Iv'e not forgotten this. I'm slowly getting back to it. I got side tracked on the project I'm on and had to work on different functionality that the stakeholders deemed more important. :-) – shawty Apr 27 '17 at 14:32
  • Ok, sooooo I implemented this, and it works fantastically. Well all accept for one thing, but that I feel is going to have to be a different question (If you want to keep your eyes open) , as far as all the binding stuff goes, this is a winner. – shawty Apr 27 '17 at 15:31
  • 1
    oh and as an added bonus, you got an upvote here: http://stackoverflow.com/questions/39055388/in-aurelia-can-i-bind-a-function-from-my-containing-view-model-to-be-called-by/39056533#39056533 to. as that was the solution to my other question. Well done sir. /me tips my hat. – shawty Apr 27 '17 at 18:41