2

I'm trying to create a mini-spreadsheet for an angular app. I want to recreate a common spreadsheet feature that allows the user to click on a spreadsheet cell and then change that cell's value using a larger input at the top of the sheet. Ideally I would like to assign the model for a given cell to the large input on-the-fly when the user clicks on one of the cells, but I'm having trouble figuring out how to do this.

There are some finer details to work out with blurring and focus of the cells. Also, the example I gave is simplified greatly; there can be any number of rows and columns. My main question is: how do I dynamically assign a cell's model to the large input so it can act as a sort of proxy-input to a cell? If this isn't possible/practical, is there a better way to handle this?

This is what I have so far. I don't even know if this is possible, specifically with the approach I'm taking in this directive. Any ideas?

http://plnkr.co/edit/6tTsilCGSepYyCfbvidp?p=preview

index.html

<table ng-controller="SpreadsheetCtrl" custom-spreadsheet>
  <thead>
    <tr>
      <th colspan="3">
        <input type="text" style="width: 100%" />
      </th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in rows">
      <td>
        <input ng-model="row.A" type="text" />
      </td>
      <td>
        <input ng-model="row.B" type="text" />
      </td>
      <td>
        <input ng-model="row.C" type="text" />
      </td>
    </tr>
  </tbody>
</table>

script.js

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

app.controller('SpreadsheetCtrl', function($scope) {
  $scope.rows = [
    {A: 'a', B: 'b', C: 'c'},
    {A: 'a', B: 'b', C: 'c'},
    {A: 'a', B: 'b', C: 'c'}
  ];
}); 

app.directive('customSpreadsheet', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      var primary = element.find('thead input');
      element.on('focus', 'tbody input', function () {
        // of course, this won't work! but it shows the (basic) idea
        // of what I'm trying to do
        primary.attr('ng-model', $(this).attr('ng-model'));
      });
    }
  };
})

1 Answer 1

5

I would toss the directive and utilize the ng-click. Here is a working PLUNKER.

Note

<input ng-model="row.A" type="text" ng-click="choose(row, 'A')"/>

And

<input type="text" ng-model="selected[attr]" style="width: 100%" />

With

$scope.choose = function(row, attr) {
    $scope.selected = row;
    $scope.attr = attr;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Nice. Trying forever to get that.
Yeah, the scope is tricky to figure out, hence the need to save the attr too. Good luck!

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.