Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependent/Cascading Dropdowns in Aurelia

I'd like to create dependent dropdowns in Aurelia.

What I mean by dependent dropdowns is if you click an item in the first dropdown, then the options in the second dropdown are filtered down based on what you click. If you look at my js-fiddle, you'll notice that if you select Toyota in the first dropdown, the second one populates with Toyota car models (Corolla, Camry, etc.). If you select Honda in the first dropdown, the second one populates itself with Honda models (Accord, Civic, etc.). You get the idea.

It is very simple and requires very little code to do this in Angular and I was wondering if doing this in Aurelia is also simple and straightforward. I wasn't able to find much as far as resources on how to do this in Aurelia. The fiddle below demonstrates exactly what I would like to accomplish (except I'd like to do it in Aurelia, not Angular, of course). Any help would be much appreciated. Thanks!

https://jsfiddle.net/nhunt3/wjvvjwzx/

HTML:

<div ng-app="myApp" ng-controller="myController">
My Cars
<br />
<table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>

  <tbody>
    <tr ng-repeat="car in myCars track by car.uid">
      <td>
        <select ng-model="car.MakeUID" ng-options="make.uid as make.name for make in makes" />
      </td>

      <td>
        <select
        ng-model="car.ModelUID"
        ng-options="model.uid as model.name for model in models | filter: { parentID: car.MakeUID } : true" />
      </td>
    </tr>
  </tbody>
</table>   
</div>

JavaScript:

// the main (app) module
var myApp = angular.module("myApp", []);

angular.module('myApp', []).controller('myController', function($scope) {
    $scope.makes = [
        {name:'Toyota', uid:1},
        {name:'Honda', uid:2},
        {name:'Ford', uid:3}
    ];

  $scope.models = [
            {name:'Yaris', uid:1, parentID:1},
        {name:'Corolla', uid:2, parentID:1},
        {name:'Camry', uid:3, parentID:1},
        {name:'Highlander', uid:4, parentID:1},
        {name:'Accord', uid:5, parentID:2},
        {name:'Civic', uid:6, parentID:2},
        {name:'Pilot', uid:7, parentID:2},
        {name:'Focus', uid:8, parentID:3},
        {name:'Fiesta', uid:9, parentID:3},
        {name:'Fusion', uid:10, parentID:3},
        {name:'F-150', uid:10, parentID:3}
    ];

  $scope.myCars = [
        {uid:1, MakeUID:1, ModelUID:2},
        {uid:2, MakeUID:1, ModelUID:3},
        {uid:3, MakeUID:3, ModelUID:8}
    ];
});
like image 874
Nick Avatar asked Mar 11 '23 00:03

Nick


1 Answers

For other users that find this thread:

app.html

<template>
  <require from="./filter"></require>
  <table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>
  <tbody>
    <tr repeat.for="car of myCars">
      <td>
        <select value.bind="car.MakeUID" change.delegate="resetModel(car)">
          <option value="0">select one of ...</option>
          <option repeat.for="make of makes" model.bind="make.uid">${make.name}</option>
        </select>
      </td>
      <td>
        <select value.bind="car.ModelUID">
          <option value="0">select one of ...</option>
          <option repeat.for="model of models | filter:'parentID':car.MakeUID" model.bind="model.uid">${model.name}</option>
        </select>
      </td>
    </tr> 
  </tbody>
</template>

app.js

export class App { 
    makes = [
        {name:'Toyota', uid:1},
        {name:'Honda', uid:2},
        {name:'Ford', uid:3}
    ];

    models = [
        {name:'Yaris', uid:1, parentID:1},
        {name:'Corolla', uid:2, parentID:1},
        {name:'Camry', uid:3, parentID:1},
        {name:'Highlander', uid:4, parentID:1},
        {name:'Accord', uid:5, parentID:2},
        {name:'Civic', uid:6, parentID:2},
        {name:'Pilot', uid:7, parentID:2},
        {name:'Focus', uid:8, parentID:3},
        {name:'Fiesta', uid:9, parentID:3},
        {name:'Fusion', uid:10, parentID:3},
        {name:'F-150', uid:10, parentID:3}
    ];

    myCars = [
        {uid:1, MakeUID:1, ModelUID:2},
        {uid:2, MakeUID:1, ModelUID:3},
        {uid:3, MakeUID:3, ModelUID:8}
    ];

    resetModel(car) {
      car.ModelUID = 0;
    }
}

filter.js

export class FilterValueConverter {
  toView(array, propertyName, filter_on) {
    return array.filter(i => i[propertyName] == filter_on);
  }
}

old answer

I think this does the same as your Angular code in Aurelia:

<template>
  <require from="./filter"></require>
  <table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>
  <tbody>
    <tr repeat.for="car of myCars">
      <td>
        <select value.bind="car.MakeUID" ref="selected_car">
          <option repeat.for="make of makes" value.bind="make.uid">${make.name}</option>
        </select>
      </td>

      <td>
        <select value.bind="car.ModelUID">
          <option repeat.for="model of models | filter:'parentID':selected_car.value">${model.name}</option>
        </select>
      </td>
    </tr> 
  </tbody>
</template>

And you also need this filter:

export class FilterValueConverter {
  toView(array, propertyName, filter_on) {
    return array.filter(i => i[propertyName] == filter_on);
  }
}

https://gist.run/?id=91b23375e0b73afe7f21825f67cfeabf

like image 79
Erik Lieben Avatar answered Mar 19 '23 14:03

Erik Lieben