Partha Sarathi Ghosh Partha Sarathi Ghosh - 1 year ago 86
AngularJS Question

Change HTML input field to label by defining custom angular directive

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
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;

EditButtonClickEvent () {
set localStorage.viewMode = false;

editPagesModule.directive('input', {
if(localStorage.viewMode != true)
//Keep all existing functionality with ng-model
else {
//replace input with span or label.

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download