Nader Hisham
Nader Hisham

Reputation: 5414

Dropdown binding with angular

Suppose I have this controller:

myApp.controller('testCtrl', function ($scope) {
    $scope.cars = [
        { carId: '1', carModel: 'BMW', carOwner: 'Nader' },
        { carId: '2', carModel: 'Mercedes', carOwner: 'Hisham' },
        { carId: '3', carModel: 'Opel', carOwner: 'Saad' }
    ];
});

and this HTML:

<select ng-options="car as car.carModel for car in cars" ng-model="car"></select>
<br />
<label> Car ID </label> <input type="text" ng-model="car.carId" />
<br />
<label> Car Model </label> <input type="text" ng-model="car.carModel" />
<br />
<label> Car Owner </label> <input type="text" ng-model="car.carOwner" />

When a user selects a car it should automatically bind values of the selected car to the text boxes, which already happens in this case. However, when I change the value in the text box for the carModel, the carModel name in the dropdown changes.

How can I change the input for the carModel without changing the value in the dropdown? Note that I want to bind the information of the currently selected car to the textboxes whenever the user selects a different value from the dropdown.


Use Case

Suppose a list of cars is retrieved from a database and I want the user to edit the selected car, so first I want to show the car information when the user selects it from from the dropdown, then change whatever he wants and call a web service to update the selected car.

Upvotes: 4

Views: 197

Answers (3)

changtung
changtung

Reputation: 1624

This is also possible by using directives. Pass car as string parameter. Directive template shows form. Variable in select won't change since it's Object variables are passed as string to directive.

template.html

<br />
<label> Car ID </label> <input type="text" ng-model="carId" />
<br />
<label> Car Model </label> <input type="text" ng-model="carModel" />
<br />
<label> Car Owner </label> <input type="text" ng-model="carOwner" />

html view

 <select ng-options="car as car.carModel for car in cars" ng-model="car"></select>
 <ca car-id="{{car.carId}}" car-model="{{car.carModel}}" car-owner="{{car.carOwner}}"></ca>

And the directive which You can customize.

.directive('ca', function() {
  return {
    scope:{
            carId:'@',
            carModel:'@',
            carOwner:'@'
        },
    templateUrl: 'template.html'
  };
});

plunker

This example may work with Angular 2.0 or be easier to migrate.

Upvotes: 1

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

You can use angular.copy for this:

JavaScript: define callTest function in your testCtrl

$scope.cars = [ ... ];

$scope.callTest = function(objCar) {
  console.log(objCar);
  $scope.carModel = angular.copy(objCar); // this carModel is used in the html
};

HTML:

<select ng-change="callTest(car)" ng-options="car as car.carModel for car in cars" ng-model="car"></select>
<br />
<label> Car ID </label>
<input type="text" ng-model="carModel.carId" />
<br />
<label> Car Model </label>
<input type="text" ng-model="carModel.carModel" />
<br />
<label> Car Owner </label>
<input type="text" ng-model="carModel.carOwner" />

Use ng-change event on select and call callTest() function in the controller.

Here is the Plunker

Upvotes: 4

charlietfl
charlietfl

Reputation: 171679

The basic steps I would use would be:

  1. Use ng-change event of <select> to create copy of car using angular.copy()
  2. Bind copied object to text boxes ng-model="carCopy.propName"
  3. Edit the car
  4. On save, use angular.extend() to merge updates back to original car

Upvotes: 2

Related Questions