3

I have lots of input, textarea and select on some pages (angular templates). I want to redefine "input" directive such that It will take a value like ViewMode = true from either localStorage and convert all inputs as label. If I change the ViewMode then on page refresh input should behave properly.

But I do not want to edit any input tag on any angular template.

Means I want to override input, textarea and select as my own angular directive.

I am not able to start. Where from should I start? (I have experience of custom directive with new name, but not with any exciting HTML tag name)

Note: I do not want to use readonly (with proper style) since it requires editing all input tag. Not only that I have custom directives with isolated scope, so I need to pass the ViewMode value to all custom directives. More over if user press CTRL+A content readonly field is not being selected.

I am looking for a solution kind of as follows

ViewButtonClickEvent () {
   set localStorage.viewMode = true;
   callExistingEditMethod();
}

EditButtonClickEvent () {
  set localStorage.viewMode = false;
  callExistingEditMethod();
}

editPagesModule.directive('input', {
    if(localStorage.viewMode != true)
     //Keep all existing functionality with ng-model
    }
    else {
      //replace input with span or label.
    }
})
5
  • perhaps it is decorator you're looking for. Commented Dec 23, 2015 at 7:29
  • Angular directive can not only be an element but also an attribute or class, right? Just make a directive as an attribute or class that can be added to <input>, <textarea> or <select> will that serve your purpose? Commented Dec 23, 2015 at 17:09
  • ng-readonly is there but I dont like to use it because I have to update all input tag. I want some centralize approch. So that I don't need to tuch any thing. Commented Dec 24, 2015 at 7:51
  • 1
    Looks like you need 'in place edit' functionality. There are many examples over the Internet example (not mine). Commented Dec 28, 2015 at 11:29
  • Nice one. But it should not be with isolated scope. It should work with existing ng-model and others ng directive Commented Dec 28, 2015 at 11:43

1 Answer 1

3
+50

You could create directives called input, select and textarea, which would automatically be compiled without having to change your existing markup.

Working examples: JSFiddle & Plunker

It would look something like this:

angular.module('myApp', [])
  .directive('input', inputDirective)
  .directive('select', inputDirective)
  .directive('textarea', inputDirective)
  .factory('$editMode', editModeFactory)
;

inputDirective.$inject = ['$editMode'];
function inputDirective($editMode) {
  return {
    link: postLink
  };

  function postLink(scope, iElement, iAttr) {
    scope.$watch($editMode.get, function(edit) {
      if (iElement[0].nodeName === 'SELECT') {
        if (edit === 'true') iElement.removeAttr('disabled');
        else iElement.attr('disabled', true);
      }
      else {
        if (edit === 'true') iElement.removeAttr('readonly');
        else iElement.attr('readonly', true);
      }
    });
  }
}

editModeFactory.$inject = ['$window'];
function editModeFactory($window) {
  return {
    get: function() {
      return $window.localStorage.getItem('editMode');
    },
    set: function(value) {
      $window.localStorage.setItem('editMode', value);
    }
  };
}

I did use the readonly attribute (disabled for select), because the only other option I can think of would be to replace the entire input element with something like a div. You would also have to cache the original element, so you can restore it later...and doing that sort of thing would break your bindings so you'd have to recompile every input, every time. That just seems like a horrible idea.

Sign up to request clarification or add additional context in comments.

4 Comments

Very nice approach. But I am not able to open jsfiddle from my workplace. So can you please clone it on plunker? One more thing some of my user will not have edit permission so I do not need to recompile to edit view. More over view mode and edit mode are completely different flow so we do not need to come back vice versa any time.
I added a plunker to my answer. If you would prefer to change the inputs to divs, you might be able to do something like iElement.replaceWith('<div>' + iElement.val() + '</div>');, but you will lose any bindings, classes and other attribute values on the input (unless you explicitly add them to your html string).
Wow! that is great. I will try this and let you know what happens. Your plunker is blank URL here.
Sorry, I fixed the link for plnkr.co: plnkr.co/edit/6a5X9aRA6IXRsd9ZUteP?p=preview

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.