AngularJS: disabling all form controls between submit and server response
Asked Answered
D

2

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);
    };
});
Diastase answered 7/2, 2014 at 21:28 Comment(4)
which service are you using to send the datas from the form? $http or $resource?Extravert
Its actually $http as i don't need to deal with anything outstanding.Diastase
Disabled fieldsets don't work in IE , ie not a solution. I use a Bootstrap modal and set the backdrop to static.Ploughshare
Note that at time of writing there is a bug where fieldset cannot be used as a flexbox containerUnific
S
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.

Seduction answered 7/2, 2014 at 21:57 Comment(11)
Seems like it really works fine even with <button>! Thanks a lot Sasha.Diastase
Didn't even know about ng-disabled. What I was working on just got an order of magnitude easier... Thanks!Vigilant
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.aspEsp
@Esp 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/fieldsetSeduction
Input type button, text and file not disabled in IE11 :-(, also button is grayed out but angular ng-click-handler still fires.Pock
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.Ploughshare
Confirmed on 10 and 11Ploughshare
@im1dermike Can you create a jsfiddle, reproducing the problem you experience? It works well for me in IE10 and IE11.Seduction
Sure. With Angular: jsfiddle.net/HB7LU/16165 and without Angular: jsfiddle.net/gf4g0z4n . You can edit the field in IE.Ploughshare
@AlexanderPuchkov: Did you have time to take a look at my fiddles/screencast?Ploughshare
@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/…Seduction
W
-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.

Weinberger answered 12/5, 2017 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.