3
votes

I am using Angular Formly, and try to build a form with a Select field which allows to pick the state of a country. The second field is a typeahead field, which allows to enter valid area names belonging to this state. However, I am failing to dynamically change the typeahead options array.

I have taken the Typeahead type definition from the Formly Examples, and works fine with a static array of options:

formlyConfig.setType({
  name: 'typeahead',
  template: '<input type="text" ng-model="model[options.key]" ' +
        'uib-typeahead="item for item in to.options | filter:$viewValue | limitTo:8" ' +
        'class="form-control">',
  wrapper: ['bootstrapLabel', 'bootstrapHasError'],
});

This is my form definition:

$scope.selectZoneFormFields = [

  {
    key: 'stateid',
    type: 'select',
    templateOptions:{
      label: Constants.DIVPOL,
      valueProp: 'id',
      labelProp: 'nombre',
      options: StatesManager.get()
    }
  },
  {
    key: 'zoneName',
    type: 'typeahead',
    templateOptions: {
      label: 'Zona',
      options: $scope.zoneNames
    }
  }
];

Then, I watch changes in stateid and refresh $scope.zoneNames:

$scope.$watch('geo.stateid', function(newValue, oldValue) {
  if (newValue === undefined || newValue.length !== 2 || newValue === oldValue )
    return;
  console.log(' !!! STATE change detected: ' + oldValue + '-->' + newValue);
  refreshZones(newValue);
});

The problem is that the options for the typeahead field remain those which are loaded at the beginning (initial value of $scope.zoneNames)

I have tried to use a controller inside formly field definition, but with no success.

Ideas?

1
The easiest way is going to be to use ExpressionProperties. See Below Answer - MattE

1 Answers

1
votes
  {
    key: 'zoneName',
    type: 'typeahead',
    templateOptions: {
      label: 'Zona',
      options: []
    },
    expressionProperties: {
       'templateOptions.options': function($viewValue, $modelValue, $scope){
           $scope.to.options = []; //set to an empty array
           if($scope.model.stateid) { //if the state has been selected
             $scope.to.options = //whatever code you use to get the zones
             return $scope.to.options; //return the options
           }               
        }
    }
  }