2

I would like each one of my list items to be editable via the input. Clicking on the list item fills in the input, but how do I then specify what item to update? I have the $watch working.

Any help is appreciated.

I have a plunker: https://plnkr.co/edit/mslpklTaStKEdo64FpZl?p=preview

Here is the code:

<body ng-app="myApp">

<div ng-controller="MyController">

    <ul ng-repeat="item in collection">
      <li ng-click="edit(item.name)">{{item.name}}</li>
    </ul>

    <input  name="myinput" ng-model="myinput"  />
</div>

</body>

JS:

var app = angular.module('myApp', [])

.controller('MyController', function($scope, $http) {

  $scope.collection = [
      {name:'foo'},
      {name:'bar'},
      {name:'foobar'},
      {name:'barfoo'},
    ];

  $scope.edit = function(current_name) {

    $scope.myinput = current_name;

    console.log(current_name);

  }

  $scope.$watch('myinput', function(NewValue, OldValue) {
    console.log(NewValue);
  }, true);  

})

3 Answers 3

3

Change your code to do this

<li ng-click="edit(item)">{{item.name}}</li>

And in your controller

$scope.edit = function(item) 
{
    $scope.selectedItem = item;
}

And finally back in your markup

<input  name="myinput" ng-model="selectedItem.name"  />

What that does is to switch the currently editable item to whatever you click on, and then when you click on it, whatever you type into the input will update that item.

Sign up to request clarification or add additional context in comments.

Comments

2

Instead of passing edit(item.name), pass item itself. Then angular will handle the rest for you, there is no need for $watch or $index

<body ng-app="myApp">

  <div ng-controller="MyController">

   <ul ng-repeat="item in collection">
     <li ng-click="edit(item)">{{item.name}}</li>
   </ul>

   <input  name="myinput" ng-model="myinput.name"  />
  </div>

</body>


JS:

var app = angular.module('myApp', [])
.controller('MyController', function($scope, $http) {

$scope.collection = [
  {name:'foo'},
  {name:'bar'},
  {name:'foobar'},
  {name:'barfoo'},
];

 $scope.edit = function(current_item) {

  $scope.myinput = current_name;

  console.log(current_name);

}

})

1 Comment

You haven't updated the code correctly. You are still calling edit(item.name) which passes the name property not the item.
0

You need to pass the $index to edit() as well, so you know which index of the array to update later:

var app = angular.module('myApp', [])

.controller('MyController', function($scope, $http) {

  $scope.collection = [
      {name:'foo'},
      {name:'bar'},
      {name:'foobar'},
      {name:'barfoo'},
    ];

  $scope.edit = function(current_name, current_index) {
    $scope.myinput = current_name;
    $scope.myindex = current_index;
  }
  
  $scope.$watch('myinput', function(NewValue) {
    if($scope.myindex) {
      $scope.collection[$scope.myindex].name = NewValue;
    }
  })

})
<script data-require="[email protected]" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular.js"></script>

<div ng-app="myApp">

  <div ng-controller="MyController">
    <ul ng-repeat="item in collection">
      <li ng-click="edit(item.name, $index)">{{item.name}}</li>
    </ul>
  
    <input  name="myinput" ng-model="myinput"  />
  </div>

</div>

Passing the actual item if possible instead, as the other answers say, is preferred tho.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.