123

I have a dilemma about what is the best (and correct) approach if I want to disable form controls (or at least make them unavailable for user interaction) during a period of time when user clicks sort of "Save" or "Submit" button and data travelling over the wire. I don't want to use JQuery (which is evil!!!) and query all elements as array (by class or attribute marker) The ideas I had so far are:

  • Mark all elements with cm-form-control custom directive which will subscribe for 2 notifications: "data-sent" and "data-processed". Then custom code is responsible for pushing second notification or resolve a promise.
  • Use promiseTracker that (unfortunatelly!) enforces to produce extremely stupid code like ng-show="loadingTracker.active()". Obviously not all elements have ng-disabled and I don't want to user ng-hide/show to avoid "dancing" buttons.
  • Bite a bullet and still use JQuery

Does any one have a better idea? Thanks in advance!

UPDATED: The fieldset idea DOES work. Here is a simple fiddle for those who still want to do the same http://jsfiddle.net/YoMan78/pnQFQ/13/

HTML:

<div ng-app="myApp">
    <ng-form ng-controller="myCtrl">
        Saving: {{isSaving}}
        <fieldset ng-disabled="isSaving">
            <input type="text" ng-model="btnVal"/>
            <input type="button" ng-model="btnVal" value="{{btnVal}}"/>
            <button ng-click="save()">Save Me Maybe</button>
        </fieldset>
    </ng-form>
</div>

and JS:

var angModule = angular.module("myApp", []);

angModule.controller("myCtrl", function ($scope, $filter, $window, $timeout) {
    $scope.isSaving = undefined;
    $scope.btnVal = 'Yes';
    $scope.save = function()
    {
        $scope.isSaving = true;
        $timeout( function()
             {
                 $scope.isSaving = false;
                 alert( 'done');
             }, 10000);
    };
});
Greg B
  • 13,819
  • 18
  • 78
  • 132
YoMan78
  • 1,288
  • 2
  • 9
  • 14

2 Answers2

285

Wrap all your fields in fieldset and use ngDisabled directive like this:

<fieldset ng-disabled="isSaving"> ... inputs ...</fieldset>

It will automatically disable all inputs inside the fieldset.

Then in controller set $scope.isSaving to true before http call and to false after.

EverPresent
  • 1,813
  • 16
  • 17
Alexander Puchkov
  • 5,763
  • 4
  • 30
  • 46
  • Seems like it really works fine even with – YoMan78 Feb 09 '14 at 06:22
  • Didn't even know about `ng-disabled`. What I was working on just got an order of magnitude easier... Thanks! – aendrew Jul 29 '14 at 12:03
  • 9
    It's a good tip, though unfortunately the disabled attribute on a fieldset is not supported in IE or Safari http://www.w3schools.com/tags/att_fieldset_disabled.asp – kiwiaddo Oct 21 '14 at 22:47
  • 5
    @kiwiaddo It works well in IE9+ in my tests. By the way w3schools.com is not the best reference website. Better check this page https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset – Alexander Puchkov Oct 22 '14 at 13:57
  • 3
    Input type button, text and file not disabled in IE11 :-(, also button is grayed out but angular ng-click-handler still fires. – Sebastian Jan 15 '15 at 08:12
  • This doesn't work at all in IE. This is why IE is the bane of my existence as well as why this shouldn't be the answer. – im1dermike Aug 06 '15 at 20:56
  • Confirmed on 10 and 11 – im1dermike Aug 07 '15 at 01:29
  • @im1dermike Can you create a jsfiddle, reproducing the problem you experience? It works well for me in IE10 and IE11. – Alexander Puchkov Aug 07 '15 at 01:31
  • Sure. With Angular: http://jsfiddle.net/HB7LU/16165/ and without Angular: http://jsfiddle.net/gf4g0z4n/ . You can edit the field in IE. – im1dermike Aug 07 '15 at 12:44
  • @AlexanderPuchkov: Did you have time to take a look at my fiddles/screencast? – im1dermike Aug 10 '15 at 15:40
  • 3
    @im1dermike you right, it doesn't work in IE indeed. The field is visually styled as disabled, but the user can still interact with it and edit it as if it was enabled. There's a bug in IE for this already submitted and it was fixed, but not shipped yet. It will be available in the next IE major release https://connect.microsoft.com/IE/feedbackdetail/view/962368/can-still-edit-input-type-text-within-fieldset-disabled – Alexander Puchkov Aug 10 '15 at 15:56
-5

There is an simple solution in modern browsers:

  1. define a css class

    .disabled {
      pointer-events: none;
      ... ...
    }
    
  2. add this class to ng-form

    <ng-form data-ng-class="{ 'disabled': isSaving }"> ... inputs ... </ng-form>
    

Here is the pointer-events support chart.

Note: even if you set pointer-events: none, you can still tab to input element with your keyboard.

legoscia
  • 37,068
  • 22
  • 103
  • 148
Raoh
  • 1
  • 3