<!DOCTYPE html>
<html ng-app="modal.editing">

  <head>
    <link data-require="ui-grid@3.0.0RC20" data-semver="3.0.0RC20" rel="stylesheet" href="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.20/ui-grid.css" />
    <link data-require="bootstrap@*" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
    <script data-require="angular.js@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
    <script data-require="angular.js@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-sanitize.js"></script>
    <script data-require="ui-grid@3.0.0RC20" data-semver="3.0.0RC20" src="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.20/ui-grid.js"></script>
    <script data-require="ui-bootstrap@*" data-semver="0.12.1" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.js"></script>
    <script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
    
    <script src="https://cdn.rawgit.com/mike-marcacci/objectpath/v1.1.0/lib/ObjectPath.js"></script>
    <script src="https://cdn.rawgit.com/geraintluff/tv4/v1.1.9/tv4.min.js"></script>
    <script src="https://cdn.rawgit.com/Textalk/angular-schema-form/0.8.0/dist/schema-form.js"></script>
    <script src="https://cdn.rawgit.com/Textalk/angular-schema-form/0.8.0/dist/bootstrap-decorator.js"></script>
    
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl as vm">
    <div class="grid" ui-grid="vm.gridOptions" ui-grid-edit></div>
  </body>

</html>
// Code goes here

angular.module('modal.editing', ['ui.grid', 'ui.grid.edit', 'ui.bootstrap', 'schemaForm'])

.constant('PersonSchema', {
  type: 'object',
  properties: {
    name: { type: 'string', title: 'Name' },
    company: { type: 'string', title: 'Company' },
    phone: { type: 'string', title: 'Phone' },
    'address.city': { type: 'string', title: 'City' }
  }
})

.controller('MainCtrl', MainCtrl)
.controller('RowEditCtrl', RowEditCtrl)
.service('RowEditor', RowEditor)
;

MainCtrl.$inject = ['$http', 'RowEditor'];
function MainCtrl ($http, RowEditor) {
  var vm = this;
  
  vm.editRow = RowEditor.editRow;
  
  vm.gridOptions = {
    columnDefs: [
      { field: 'id', name: '', cellTemplate: 'edit-button.html', width: 34 },
      { name: 'name' },
      { name: 'company' },
      { name: 'phone' },
      { name: 'City', field: 'address.city' },
    ]
  };
  
  $http.get('http://ui-grid.info/data/500_complex.json')
    .success(function (data) {
      vm.gridOptions.data = data;
    });
}

RowEditor.$inject = ['$rootScope', '$modal'];
function RowEditor($rootScope, $modal) {
  var service = {};
  service.editRow = editRow;
  
  function editRow(grid, row) {
    $modal.open({
      templateUrl: 'edit-modal.html',
      controller: ['$modalInstance', 'PersonSchema', 'grid', 'row', RowEditCtrl],
      controllerAs: 'vm',
      resolve: {
        grid: function () { return grid; },
        row: function () { return row; }
      }
    });
  }
  
  return service;
}

function RowEditCtrl($modalInstance, PersonSchema, grid, row) {
  var vm = this;
  
  vm.schema = PersonSchema;
  vm.entity = angular.copy(row.entity);
  vm.form = [
    'name',
    'company',
    'phone',
    {
      'key': 'address.city',
      'title': 'City'
    },
  ];
  
  vm.save = save;
  
  function save() {
    // Copy row values over
    row.entity = angular.extend(row.entity, vm.entity);
    $modalInstance.close(row.entity);
  }
}

/*

{
    "id": 0,
    "guid": "de3db502-0a33-4e47-a0bb-35b6235503ca",
    "isActive": false,
    "balance": "$3,489.00",
    "picture": "http://placehold.it/32x32",
    "age": 30,
    "name": "Sandoval Mclean",
    "gender": "male",
    "company": "Zolavo",
    "email": "sandovalmclean@zolavo.com",
    "phone": "+1 (902) 569-2412",
    "address": {
        "street": 317,
        "city": "Blairstown",
        "state": "Maine",
        "zip": 390
    },
    "about": "Fugiat velit laboris sit est. Amet eu consectetur reprehenderit proident irure non. Adipisicing mollit veniam enim veniam officia anim proident excepteur deserunt consectetur aliquip et irure. Elit aliquip laborum qui elit consectetur sit proident adipisicing.\r\n",
    "registered": "1991-02-21T23:02:31+06:00",
    "friends": [
        {
            "id": 0,
            "name": "Rosanne Barrett"
        },
        {
            "id": 1,
            "name": "Nita Chase"
        },
        {
            "id": 2,
            "name": "Briggs Stark"
        }
    ]
}
    
*/
/* Styles go here */

body {
  padding: 5px;
}

.grid {
  height: 450px;
  width: 100%;
}

# Test
<div class="ui-grid-cell-contents">
  <button type="button" class="btn btn-xs btn-primary" ng-click="grid.appScope.vm.editRow(grid, row)">
    <i class="fa fa-edit"></i>
  </button>
</div>
<div>
  <div class="modal-header">
      <h3 class="modal-title">Edit Row</h3>
  </div>
  <div class="modal-body">
    <form sf-schema="vm.schema" sf-form="vm.form" sf-model="vm.entity"></form>
  </div>
  <div class="modal-footer">
      <button class="btn btn-success" ng-click="vm.save()">Save</button>
      <button class="btn btn-warning" ng-click="$close()">Cancel</button>
  </div>
</div>