Disable all form elements inside table with ng-disabled

19,253

Solution 1

There is a way to do this, so you can have an ng-disabled attribute on a table (or any element, for that matter), and leave all the markup of any form elements inside it unchanged:

<table ng-disabled="disabled">
  <tbody>
    <tr>
      <td><input type="text"></td>
      <td><button>A button</button></td>
      <td>
        <select>
          <option>An option</option>
          <option>Another option</option>
        </select>
      </td>
      <td>
        <textarea>Textarea</textarea>
      </td>
    </tr>
  </tbody>
</table>

You can extend Angular's ngDisabled directive, to expose the value in its ng-disabled attribute on a controller:

app.directive('ngDisabled', function() {
  return {
    controller: function($scope, $attrs) {
      var self = this;
      $scope.$watch($attrs.ngDisabled, function(isDisabled) {
        self.isDisabled = isDisabled;
      });      
    }
  };
});

You can then access the controller's isDisabled attribute from any input, select, button or textarea elements inside of it, creating a watcher for each:

function reactToParentNgDisabled(tagName) {
  app.directive(tagName, function() {
    return {
      restrict: 'E',
      require: '?^ngDisabled',
      link: function(scope, element, attrs, ngDisabledController) {
        if (!ngDisabledController) return;
        scope.$watch(function() {
          return ngDisabledController.isDisabled;
        }, function(isDisabled) {
          element.prop('disabled', isDisabled);
        });
      }
    };
  });   
}

['input', 'select', 'button', 'textarea'].forEach(reactToParentNgDisabled);

You can see this working in this Plunker

I can't speak to its efficiency though: there will be a watcher for the element on <table> and then an extra watcher for each form element in the table.

I did consider a single watch + scope events, but I hit an issue that since the element with the attribute with ng-disabled might share its scope with parent/sibling elements, and so any scope events it broadcasts could be sent to elements outside of it.

Alternatively to remove the need for a watcher for each of the form elements, the controller of the extended ngDisabled directive could maintain a list of the form elements inside of it, and change all of their disabled attributes at once.

Solution 2

According to Angular's documentation for ng-disabled it can be used only on INPUT elements. See - ng-disabled

So using this tag on table will not make any effect. If you want to disable each element in a table you can use ng-disabled for each element.

As for making the table "not clickable" consider defining a custom CSS class for the elements and use ng-class for dynamically assigning the class when you want.

CSS for disabling text selection:

.myClass {
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
}

See -

Related post

ngClass documentatin

Share:
19,253
Sadeghbayan
Author by

Sadeghbayan

Front-end developer at Webpen.ir

Updated on June 05, 2022

Comments

  • Sadeghbayan
    Sadeghbayan about 2 years

    Is there any way to disable entire table with ng-disabled?

    fiddle

    $scope.isDisabled = false;
    $scope.disableClick = function() {
      $scope.isDisabled = true;
    }
    
    • JB Nizet
      JB Nizet over 9 years
      How do you define a disabled table? I can understand what a disabled button is: nothing happens when you click on the button. But a disabled table?
    • Michal Charemza
      Michal Charemza over 9 years
      Do you mean disabling all form elements inside the table?
    • Sadeghbayan
      Sadeghbayan over 9 years
      i added ng-disabled in table tag , i want to disable it (not clickable)
    • JB Nizet
      JB Nizet over 9 years
      No, you can't do that. use ng-disabled="isDisabled" on every form element contained in the table.
    • Sadeghbayan
      Sadeghbayan over 9 years
      oh no , i don't want to , ok thanks guys
    • Or Guz
      Or Guz over 9 years
      Edited my answer to give you an idea how to make an element which is not a button "un clickable".
  • Sadeghbayan
    Sadeghbayan over 9 years
    oh maaaan, you're perfect
  • swateek
    swateek over 8 years
    This somehow isn't working when I put it in my code. New to AngularJS, I am unsure where I am going wrong.