0

I am doing a form with inline editing. I found an example here: https://stackoverflow.com/a/16739227/169252

which I adapted to my needs. Here's some of the code (using nodejs, express and jade). The directive:

// Inline edit directive
app.directive('inlineEdit', function($timeout) {
  return {
    scope: {
      model: '=inlineEdit',
      handleSave: '&onSave',
      handleCancel: '&onCancel'
    },
    link: function(scope, elm, attr) {
      var previousValue;

      scope.edit = function() {
        scope.editMode = true;
        previousValue = scope.model;

        $timeout(function() {
          elm.find('input')[0].focus();
        }, 0, false);
      };
      scope.save = function() {
        scope.editMode = false;
        scope.handleSave({value: scope.model});
      };
      scope.cancel = function() {
        scope.editMode = false;
        scope.model = previousValue;
        scope.handleCancel({value: scope.model});
      };
    },
    templateUrl: 'partials/inline-edit'
  };
});

The controller:

 myControllers.controller('MyCtrl', ['$scope', '$http',
  function MyCtrl($scope, $http) {
    $scope.name          = "Name";
    $scope.surname       = "Surname";
    $scope.email         = "Email";

    $scope.save_user = function() {
        //What do I do here??
    };

The template for the directive ('partials/inline-edit'):

div(class="inline_edit_div")
  input(class="inline_edit_input" type="text" on-enter="save()" on-blur="cancel()" on-esc="cancel()" ng-model="model" ng-show="editMode")
  span(ng-mouseenter="showEdit = true" ng-mouseleave="showEdit = false")
    span(ng-hide="editMode" ng-click="edit()")
      div(class="inline_edit_text")
        {{model}}

And the form itself:

div(ng-controller="MyCtrl")
 form(id="user_form")
  div.inline.action_buttons
    button(class="buttons action_button" ng-click="save_user()") Save
  div.info
        div.element
          label(class="form") Name
          div.form(inline-edit="name")
        div.element
          label(class="form") Surname
          div.form(inline-edit="surname")
        div.info_element_bottom
          label(class="form") Email
          div.form(inline-edit="email")

My problem: As suggested here, How do I submit a form to a controller on the server? I could, on submit, post the data accessing the $scope, e.g. $scope.person.

However, with the inlineEdit directive, I am creating inherited scopes - so I've not been able to figure out how to access my form data from my controller. https://stackoverflow.com/a/13428220/169252 says you can't access child scopes from a parent scope.

In short, how can I submit with $http the whole form (preferrably I'd like to understand how to do it without a conventional POST with whole page reload)? The $scope.save_user in the controller gets called but from there I don't know any further.

Community
  • 1
  • 1
transient_loop
  • 5,984
  • 15
  • 58
  • 117
  • 1
    You are actually receiving the data you are sending from `scope.handleSave({value: scope.model});` into `$scope.save_user = function(data) { /*data.value...*/ }`. Then you can do a regular `$http.post('...', data)` to your server. – jpmorin Oct 25 '13 at 04:34
  • @jpmorin you're right, but doesn't handleSave just send the individual elements? – transient_loop Oct 25 '13 at 04:47
  • 1
    I understand now. I had miss read. The problem you are having with the scope is that you are binding to values (copy) instead of an object (reference). If you were to send an object like `$scope.person = { name:'',surname:'',email:'' }`, then the 2-way binding would work (the changes would happen also in your controller). But I understand that you want to apply your directive on single fields. I think you may want to change how you do it. – jpmorin Oct 25 '13 at 04:55
  • Angular updated their guide for directives (http://docs.angularjs.org/guide/directive), you should have a look at it. – jpmorin Oct 25 '13 at 04:56
  • actually @jpmorin I don't understand. Why does $scope.save_user get called when I hit enter in my input element? However, data is 'undefined' in save_user... – transient_loop Oct 25 '13 at 04:58
  • I dont think that it is your directive that triggers the function, but the form itself (like on submit). The directive is not linked to the save_user function as I thought (miss read). – jpmorin Oct 25 '13 at 05:00
  • 1
    To link it, you would have to do something like `div.form(inline-edit="surname" on-save="save_user")` to send it to your directive's scope. You would then receive the modified value and you could apply the change in your controller. Since you are using values instead of object, the 2-way binding won't work. – jpmorin Oct 25 '13 at 05:03

1 Answers1

0

This seems to work, one of @jpmarin 's comments suggested it to me:

 $scope.user = {
        names: 'Names',
        surnames: 'Surnames',
        email: 'Email'
    };

Then in the form

div.element
      label(class="form") Name
      div.form(inline-edit="user.name")
    div.element
      label(class="form") Surname
      div.form(inline-edit="user.surname")
    div.info_element_bottom
      label(class="form") Email
      div.form(inline-edit="user.email")

and the controller:

 $scope.save_user = function() {
        $http.put('/save_user',$scope.user).success(function() {
            alert("Callback!");
        }).error(function() {
            alert("Failed");
        });
    };

Only problem with this now is that when I hit enter on a single input element, it will trigger the form submit. Shouldn't be too difficult to fix. EDIT: This last problem has also been solved by just removing the form tag, i.e. remove form(id="user_form")

transient_loop
  • 5,984
  • 15
  • 58
  • 117
  • According to the docs, this is a normal behavior for angular forms and `enter` handling (http://docs.angularjs.org/api/ng.directive:form). – jpmorin Oct 25 '13 at 15:08
  • Maybe, but the docs are not easy to understand imho. Thanks a lot for assistance. – transient_loop Oct 25 '13 at 16:42