kittu
kittu

Reputation: 7008

Edit table with array of objects on double click in angular

I have array of objects like this:

$scope.rows = 
[{
    num1: 56,
    num2: 78,
    num3: 89
}, {
    num1: 56,
    num2: 78,
    num3: 89
}, {
    num1: 56,
    num2: 78,
    num3: 89
}, {
    num1: 56,
    num2: 78,
    num3: 89
}];

Table created using ng-repeat:

<div id="structure">
    <table border='1|1'>
        <tr ng-repeat="item in rows">
            <td>
                <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num1}}</span>
                <input ng-show="item.editing" ng-blur="doneEditing(item)" autofocus/>
            </td>
            <td>
                <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num2}}</span>
                <input ng-show="item.editing" ng-blur="doneEditing(item)" autofocus/>
            </td>
            <td>
                <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num3}}</span>
                <input ng-show="item.editing" ng-blur="doneEditing(item)" autofocus/>
            </td>
        </tr>
    </table>
</div>

Edit functions:

$scope.editItem = function (item) {
    item.editing = true;
};

$scope.doneEditing = function (item) {
    item.editing = false;
};

The problem is all the keys names are same in each object, how to double click and update the table values?

Upvotes: 1

Views: 1294

Answers (1)

cнŝdk
cнŝdk

Reputation: 32145

You just need to use Angular's ng-model directive with your inputs, so they update the respective item, so each input value is binded to its corresponding item number.

For example in the fisrt column you define it like this:

<input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num1" autofocus/>

This is how should be your HTML:

    <tr ng-repeat="item in rows">
      <td>
        <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num1}}</span>
        <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num1" autofocus/>
      </td>
      <td>
        <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num2}}</span>
        <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num2" autofocus/>
      </td>
      <td>
        <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num3}}</span>
        <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num3" autofocus/>
      </td>
    </tr>

Demo:

function myCtrl($scope) {

  $scope.rows = [{
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }];

  $scope.editItem = function(item) {
    item.editing = true;
  };

  $scope.doneEditing = function(item) {
    item.editing = false;
  };

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app>
  <div ng-controller="myCtrl">
    <div id="structure">
      <table border='1|1'>
        <tr ng-repeat="item in rows">
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num1}}</span>
            <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num1" autofocus/>
          </td>
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num2}}</span>
            <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num2" autofocus/>
          </td>
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item)">{{item.num3}}</span>
            <input ng-show="item.editing" ng-blur="doneEditing(item)" ng-model="item.num3" autofocus/>
          </td>
        </tr>
      </table>
    </div>
  </div>
</div>


Edit:

To fix the problem you stated in comments, this is an updated Demo snippet that takes into account affecting only, clicked column instead of the whole row.

function myCtrl($scope) {
  
  $scope.editableColumn = 0;

  $scope.rows = [{
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }, {
    num1: 56,
    num2: 78,
    num3: 89
  }];

  $scope.editItem = function(item, col) {
    item.editing = true;
    $scope.editableColumn = col;
  };

  $scope.doneEditing = function(item) {
    item.editing = false;
    $scope.editableColumn = 0;
  };

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app>
  <div ng-controller="myCtrl">
    <div id="structure">
      <table border='1|1'>
        <tr ng-repeat="item in rows">
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item, 1)">{{item.num1}}</span>
            <input ng-show="item.editing && editableColumn == 1" ng-blur="doneEditing(item)" ng-model="item.num1"/>
          </td>
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item, 2)">{{item.num2}}</span>
            <input ng-show="item.editing && editableColumn == 2" ng-blur="doneEditing(item)" ng-model="item.num2"/>
          </td>
          <td>
            <span ng-hide="item.editing" ng-dblclick="editItem(item, 3)">{{item.num3}}</span>
            <input ng-show="item.editing && editableColumn == 3" ng-blur="doneEditing(item)" ng-model="item.num3"/>
          </td>
        </tr>
      </table>
    </div>
  </div>
</div>

I just added an editableColumn variable in the scope that will be always updated with the number of the column to be edited.

Upvotes: 1

Related Questions