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?

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);
    };
});
4
  • which service are you using to send the datas from the form? $http or $resource? Commented Feb 7, 2014 at 21:43
  • Its actually $http as i don't need to deal with anything outstanding. Commented Feb 9, 2014 at 5:41
  • Disabled fieldsets don't work in IE , ie not a solution. I use a Bootstrap modal and set the backdrop to static. Commented Aug 12, 2015 at 1:41
  • Note that at time of writing there is a bug where fieldset cannot be used as a flexbox container Commented Feb 12, 2016 at 16:41

2 Answers 2

286

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.

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

11 Comments

Seems like it really works fine even with <button>! Thanks a lot Sasha.
It's a good tip, though unfortunately the disabled attribute on a fieldset is not supported in IE or Safari w3schools.com/tags/att_fieldset_disabled.asp
@kiwiaddo It works well in IE9+ in my tests. By the way w3schools.com is not the best reference website. Better check this page developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Input type button, text and file not disabled in IE11 :-(, also button is grayed out but angular ng-click-handler still fires.
@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 connect.microsoft.com/IE/feedbackdetail/view/962368/…
|
-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.

Comments

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.