Angular.js inline-editing
Asked Answered
H

3

9

I'm trying to find the best approach of inline-editing with angularjs. In my case it's kind of a data-grid with an "edit" button. So it's inside ng-repeat.

What I've seen people do is have both actual data and editing inputs in the same row, with editing inputs being hidden and shown on click of the edit button.

But it doesn't seem right. It's a lot of useless DOM in my opinion.

So I thought I would be better to do something like this. You click on the edit button, which is gonna have a directive, which would 1) hide the <td> with data 2) find buttons' parent, which should be the <tr>, and inject a template with into it 3) on save remove those editing <td>s and show the data <td>s again.

So I started with making the directive, inside I had element.click() function, which

// found the parent
var parent = element.closest('tr');
// found all the data tds
var tds = parent.find('td');
// hidden them  
tds.hide();

Now here's the problem, next I thought about doing something like this

// append input with editing tds into parent
parent.append('<td><input type="text" ng-model="entry.name" /> {{entry.name}} </td>');

But then it wouldn't bind or even parse the {{}} would it? What method would I have to use instead of jquery's append?

Docu on directives says this

template element - The element where the directive has been declared. It is safe to do template transformation on the element and child elements only.

So I can't use template transoformation on the element.parent()

Would it help if I made the directive on the <tr> and even if I did, I would then transform my whole <tr>, which means I'd lost the original template and I'd have to have another directive or something that would transform it back to the original state.. wouldn't I?

Edit

Since this questions seems pretty popular.. firstly my original worry of rendering additional element with each ng-repeat iteration is unfounded because 1) you can use ng-if, which means it's not gonna be rendered at all until the condition is true 2) you could append a template just as I intended, then just use $compile and it's gonna work just fine, it's definitely not gonna be "expensive", since you are doing it just for the one element. There are many many ways to approach this, but ng-if is the simpliest, if supermasher's way doesn't suit you, that is.

Harmonist answered 3/4, 2013 at 10:38 Comment(0)
T
11

Injecting a fresh template is quite an expensive way of doing things, especially if you have lots on instances of your inline editor.

There are lots of ways to do it, but the cleanest (and easiest) is to use the same element to edit and display your data, and simply toggle it's CSS using a directive to change how it appears in both states, like so:

myApp.directive('inlineEdit', function () {

return function (scope, element, attrs) {
    element.bind('click', function () {

        if (element.hasClass('inactive')) {
            element.removeClass('inactive');
        } else {
            element.addClass('inactive');
            $(element).blur()
        }
    });
};

});

Check out this fiddle for a full working example: http://jsfiddle.net/3EaY8/.

Trichloromethane answered 3/4, 2013 at 11:15 Comment(5)
..with disabling I meant making it look like it's not an input with cssHarmonist
In terms of CSS browser support, I don't see you having any significant problems with this approach. In terms of your plugins, this seems like another reason that you wouldn't want to change the DOM every time, as you will surely have to rebind your plugins as well.Trichloromethane
Yeah, but a) I'd have to make all my plugins not accept clicks when the class is inactive b) plugins like select2 actually hide the original input, and append own divs, so it wouldn't be easy.Harmonist
The outstanding problem is actually focused around issues that weren't stated in your original question. I would suggest that you accept my answer as it is a good solution to your original question and may be useful to somebody else, and then ask a new question, including your additional plugin requirements. Ideally, you should also provide a fiddle if possible to increase your chances of getting an answer.Trichloromethane
I've checked out several of these on SO and this one is my favorite. Thanks!Barmecide
K
2

Hi there I know that there is an accepted answer already but I have stumble upon this

http://vitalets.github.io/angular-xeditable/

recently, and I believe it is a very decent project that deals with editable controls in general.

Hope it helps some one.

Kitkitchen answered 24/2, 2014 at 10:27 Comment(0)
H
0

Just throwing this out there, if you used the new ng-if directive to "hide" those edit inputs and stuff, the "a lot of useless DOM" is not so much of a problem anymore, since ng-if doesn't render the html at all.

Harmonist answered 18/7, 2013 at 10:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.