Making all of the input field readonly on template binding doesn't appear to work for ng-repeat templates

4,476 views
Skip to first unread message

Jason Sobell

unread,
Jan 8, 2013, 2:47:30 AM1/8/13
to ang...@googlegroups.com
I've been looking for a simple way of making all input fields read-only when a record is flagged as read-only.
Obviously I can add ng-readonly to every field on the form, but thought that $watch would be a more concise solutions, so I added the following:

    $scope.$watch('quote.Metadata.status', function () {
            $('.disableable').find(':input:not(:disabled)').prop('disabled', ($scope.quote && $scope.quote.Metadata.Status == 2));
        });

The problem is that this does disable the fields in an ng-repeat template because the $watch is applied before the repeat has rendered the controls.
Is there a way to trigger changes after the templates have been applied, or is there an alternative (better) way to approach the problem?

Cheers,
 Jason

Joshua Miller

unread,
Jan 8, 2013, 3:20:05 AM1/8/13
to angular
Hi Jason!

It's bad juju to put knowledge of the DOM in the controller. Also, using jQuery with angular should be avoided where feasible because it adds an extra lifecycle you have to manage manually, which is part of the issue here. I get that you're going for a DRY approach, but I think the best solution really is putting an ng-readonly on all of the form elements. However, you should tie that together with your controller. E.g.:

    <input model="quote.name" ng-readonly="isReadOnly">

And in your controller, something like:

    $scope.isReadOnly = $scope.quote && $scope.quote.Metadata.Status == 2;

This maintains separation of concerns: your controller doesn't need know anything about the view and your view doesn't need to know anything about the business logic.

Josh


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Jason Sobell

unread,
Jan 8, 2013, 5:12:01 AM1/8/13
to ang...@googlegroups.com
Yes, as I mentioned, that's the obvious way, but with a form containing 40 input elements that's a lot of cludge work and it's easy to miss fields.
I'm sure they should be a way of creating some sort of directive that binds all children of an element to disable, allowing a ng-disable-children solution to the problem, but before I spend several hours learning to do this I thought I'd ask in case anyone has done this already.

Cheers,
 Jason

Peter Bacon Darwin

unread,
Jan 8, 2013, 5:57:37 AM1/8/13
to ang...@googlegroups.com
How about creating an "input" directive.  This will run alongside the core input directive on every input element?  You can then set up this directive to look on the scope or maybe in an enclosing form's directive controller for whether to be disabled or not?


Pawel Kozlowski

unread,
Jan 8, 2013, 6:00:38 AM1/8/13
to ang...@googlegroups.com
Hi!

On Tue, Jan 8, 2013 at 11:57 AM, Peter Bacon Darwin
<pe...@bacondarwin.com> wrote:
> How about creating an "input" directive. This will run alongside the core
> input directive on every input element? You can then set up this directive
> to look on the scope or maybe in an enclosing form's directive controller
> for whether to be disabled or not?

Great solution!

Cheers,
Pawel

--
Question? Send a fiddle
(http://jsfiddle.net/pkozlowski_opensource/Q2NpJ/) or a plunk
(http://plnkr.co/)
Need help with jsFiddle? Check this:
http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/

Looking for UI widget library for AngularJS? Here you go:
http://angular-ui.github.com/
Reply all
Reply to author
Forward
0 new messages