Disable an md-input - angularjs

I would like to disable the input under certain conditions.
Show the value, but not beeing able to modify it.
I tried to add an ng disable, or ng class, but it doesn't look to work for me.
<div ng-controller="SettingsController">
<md-input-container ng-class="{'md-block' : model.isDisable" ng-disabled="model.isDisabled">
<input ng-model="obj.name" aria-label="name" />
</md-input-container>
</div>
http://plnkr.co/edit/cReJQlhNOBzB7VihhRS5?p=preview

Move your ng-disabled to the input tag. It should work.
<div ng-controller="SettingsController">
<md-input-container ng-class="{'md-block' : model.isDisable" >
<input ng-model="obj.name" aria-label="name" ng-disabled="model.isDisabled" />
</md-input-container>
</div>
Also there is an out-of-place '{' in the ng-class that bothers me but the code still works so I didn't change it since I don't know if it is necessary.

Related

Angular ng-show is not executing with ng-message tag

Not sure what I am doing wrong here.
I want to display an ng-message after the user submit the form. However , the message is shown when the form is rendered. It seem like the ng-show is not evaluating.
I printed the field in the expression and it is false when I open the form. Also, I change it to ng-hide but I have the same issue.
Can you please have a look ..
<div class="small-12">
<label>first name
<span class="field-error"> *</span>
</label>
<input name="firstName"
type="text"
maxlength="25"
ng-disabled="isSubmitting" required
ng-model="candidate.firstName"
ng-class="{error:isFormSubmitted && contactForm.firstName.$error.required}" />
<div ng-messages="forms.contactForm.firstName.$error"
class="errorFormLabel" role='alert'>
<div ng-message="required"
ng-show="isFormSubmitted">This is a required field {{isFormSubmitted}}
</div>
</div>
</div>
Think about ng-messages as a switch clause, you can nest the /ng-show/ng-hide inside ng-message directive but not use them together
For example:
<div ng-messages="forms.contactForm.firstName.$error"
class="errorFormLabel" role='alert'>
<div ng-message="required">
<span ng-show="isFormSubmitted">This is a required field {{isFormSubmitted}}</span>
</div>
</div>
</div>
If you don't want an extra element: <span>, try ng-if, basically ng-if has the priority higher than any other angularjs directive and it will force the ng-message directive to be removed from the DOM tree if the expression is not positive.
<div ng-message="required"
ng-if="isFormSubmitted">This is a required field {{isFormSubmitted}}
</div>

How to use ng-messages within repeated md-input-container

With Angular 1.5.5 and Angular-Material 1.0.9 I have created a HTML form like this with a repeated input element. I want to use ngMessages for the error messages. The problem I have is that when I enter for example -1, the correct error message is shown in a tooltip, but not below the input element. The issue seems to be that the ng-messages attribute does not support interpolation like the input's name attribute. I could put a variable into the $scope which contains the correct name, but I am not happy with that option because then the input's name is defined in the HTML template and the JavaScript controller. Is there a way to do this more cleanly?
<form name="form">
<md-input-container ng-repeat="product in purchase.products">
<input type="number" min="0" max="9999" ng-model="product.quantity"
name="product[{{$index}}].quantity">
<div ng-messages="form.product[$index].quantity.$error" md-auto-hide="false">
<div ng-message="min">Please enter 0 or more</div>
<div ng-message="max">Please enter 9999 or less</div>
</div>
</md-input-container>
</form>
To be extra clear: In the rendered DOM, there is <input name="product[0].quantity" while ng-messages does not change and $index is not evaluated. I guess I would need an expression that evaluates to "product[0].quantity".
Change your name property to:
<input type="number" min="0" max="9999" required ng-model="product.quantity" name="product_{{$index}}">
And your ngMessages to:
<div ng-messages="form['product_' + $index].$error">
Now it should work.

How to make field required with k-ng-model?

I have validation issue if i use k-ng-model on field that field is not required with Angularjs validation , User can submit the form so below code field is required even i dont select the value user can still submit the form.. Any idea how to solve it ?
main.html
<div class="row">
<div class="form-group col-md-12">
<label for="themesList" class="required col-md-4">Themes:</label>
<div class="col-md-8">
<select class="multiselect" kendo-multi-select="themes"
k-options="challengThemesOptions" data-text-field="'text'"
data-value-field="'id'" name="themesList"
k-ng-model="challengesDTO.themesKyList" required
id="themesList"></select>
<p class="text-danger" ng-show="addChallengeForm.themesList.$touched && ddChallengeForm.themesList.$error.required">Theme(s) is required</p>
</div>
</div>
</div>
You can use ng-model with k-ng-model, Try assigning ng-model to a seperate variable and use ng-required.
<select class="multiselect" kendo-multi-select="themes"
k-options="challengThemesOptions" data-text-field="'text'"
data-value-field="'id'" name="themesList"
k-ng-model="challengesDTO.themesKyList" ng-model="challengesDTO.themesKyListValue" ng-required
id="themesList"></select>
This solution worked for me: kendo ui, angular require validation for numeric text box
Just create a hidden input for the each kendo widget and bind the model from your k-ng-model also to the ng-model of the hidden field. The k-ng-model seems to be no NgModelController, which is why the validators cannot hook into the models $validators and do their work.
<input kendo-date-time-picker k-ng-model="$ctrl.event.endDate"></input>
<input type="hidden" name="endDate" ng-model="$ctrl.event.endDate" required></input>

Angular form validation using the controllerAs syntax

I am currently facing the following problem:
I would like to validate my form input using the Angular ngModel directives.
When using those together with $scope they work fine.
Now, working with the controllerAs syntax, they fail to work.
This problem is poorly documented, the only help I could find is this article.
Here is a small example of my code:
The template gets called with myController as vm
<form name="vm.signUpForm" ng-submit="vm.signup(vm.user)">
<label for="name">Name</label>
<input type="text"
class="form-control"
id="name"
name="name"
placeholder="Full name"
ng-model="vm.user.name"
ng-minlength="2" required />
<div ng-show="vm.signUpForm.$submitted || vm.signUpForm.name.$touched">
<span ng-show="vm.signUpForm.name.$error.required">Please fill in your name</span>
<span ng-show="vm.signUpForm.name.$error.minlength">A minimum of 2 [...]</span>
</div>
[...]
</form>
Am I forced to use $scope to validate the form? Or did I miss something ?
Thanks in advance!
Solution by: Andrew Gray
I had to change the following lines to get this to work:
<form name="vm.signUpForm" ... >
<!-- To -->
<form name="signUpForm" ...>
<div ng-show="vm.signUpForm.$submitted || vm.signUpForm.name.$touched">
<!-- To -->
<div ng-if="signUpForm.name.$invalid">
<span ng-show="vm.signUpForm.name.$error.required" ... >
<!-- To -->
<span ng-show="signUpForm.name.$error.required" ... >
First things first - you don't need the vm. on the form.
<form novalidate name="someForm">
<label>
Some Text:
<span class="danger-text" ng-if="someForm.someText.$invalid">
ERROR!
</span>
</label>
<input type="text" name="someField" />
</form>
The way it winds up working, is that there's a validation object that is not tied to the scope. The controllerAs syntax is just spinning off a instance of the controller as a scope variable.
Try shaving off the vm. from the form and child elements' names, and you should be OK.

Validating nested form in angular

Having this ordinary (name attribute is requred by server) form with angular and can't figured out how to make validations work. What should i put into ng-show="TODO"
http://jsfiddle.net/Xk3VB/7/
<div ng-app>
<form ng-init="variants = [{duration:10, price:100}, {duration:30, price:200}]">
<div ng-repeat="variant in variants" ng-form="variant_form">
<div>
<label>Duration:</label>
<input name="variants[{{$index}}][duration]" ng-model="variant.duration" required />
<span ng-show="TODO">Duration required</span>
</div>
<div>
<label>Price:</label>
<input name="variants[{{$index}}][price]" ng-model="variant.price" />
<span ng-show="TODO">Price required</span>
</div>
</div>
</form>
</div>
ps: this is just piece of form, which is more complicated
Thanks
AngularJS relies on input names to expose validation errors.
Unfortunately, as of today it is not possible (without using a custom directive) to dynamically generate a name of an input. Indeed, checking input docs we can see that the name attribute accepts a string only.
Long story short you should rely on ng-form to validate dynamically created inputs. Something like :
<div ng-repeat="variant in variants" >
<ng-form name="innerForm">
<div>
<label>Duration:</label>
<input name="duration" ng-model="variant.duration" required />
<span ng-show="innerForm.duration.$error.required">Duration required</span>
</div>
<div>
<label>Price:</label>
<input name="price" ng-model="variant.price" required/>
<span ng-show="innerForm.price.$error.required">Price required</span>
</div>
</ng-form>
Working fiddle here
UPDATE : Base on your serverside requirement why not do something like that :
<input type="hidden" name="variants[{{$index}}][duration]" ng-model="variant.duration"/>
<input name="duration" ng-model="variant.duration" required />
The hidden input will be the one read by the server while the other one will be used to do the client side validation (later discarded by server). It s kind of an hack but should work.
PS : Be sure that your form is valid before actually submitting it. Can be done with ng-submit

Resources