Reputation: 13892
I am working with Angular Material, I need to make a radio group required, so that the user has to select a radio button, before he can submit the form. So the form should be invalid while no radio button is selected.
this is the code
<form id="pipelineForm" name="pipelineForm" ng-submit="processForm()" flex layout="column" novalidate>
<md-radio-group ng-model="parameters.selected" ng-required="true" name="analyzerRG"
<md-radio-button ng-value="choiceObj" ng-repeat="choiceObj in parameters.choices" ng-required>
{{choiceObj.text}}
</md-radio-button>
</md-radio-group>
</form>
i have tried making individual <md-radio-button>
required, giving name
to the radio group and using ng-messages
for required
, but to no avail.
When i check the md-radio-group
in chrome element inspector, it always has the class="ng-valid ng-valid-required"
.
I can probably check the parameters.selected
property for validating the form on my own, but i would like if the correct classes are applied to the md-radio-group
and so the form is automatically invalid.
P.S. : There is a similar issue on Angular Material Github, but it seems to be closed now and the suggestions do not seem to work for me.
Upvotes: 6
Views: 9865
Reputation: 1059
Check the solution on CodePen (https://codepen.io/jakobadam/pen/xqZoBR) as mentioned in the issue thread
https://github.com/angular/material/issues/1305#issuecomment-350047026
<md-input-container class="md-input-has-value"
ng-class="{ 'md-input-invalid' : form.fruit.$invalid && form.$submitted }">
<label class="md-required" translate>Fruit</label>
<md-radio-group md-autofocus name="fruit" ng-model="fruit" layout="row" required>
<md-radio-button value="Apple" class="md-primary">Apple</md-radio-button>
<md-radio-button value="Banana"> Banana </md-radio-button>
<md-radio-button value="Mango">Mango</md-radio-button>
</md-radio-group>
<div ng-messages="form.fruit.$error">
<div ng-message="required" translate>Yo. Select some fruit.</div>
</div>
</md-input-container>
Upvotes: 4
Reputation: 6693
Regarding the lack of ng-messages, I am not 100% certain but I think this is down to ng-messages not being aware of custom controls like md-radio-group/md-radio-button. Here's an updated approach that uses an obscured text field attached to the same model value. This allows the messages to appear as expected.
Note that novalidate
has been added to the form element here to stop browser native form validation from kicking in. Rather than disabling the submit button (which prevents any possibility of the messages being shown since there is no way to trigger the form validation), the ng-submit
expression now checks myForm.$valid
before invoking the submit method.
<html lang="en">
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script language="javascript">
angular
.module('firstApplication', ['ngAnimate', 'ngAria', 'ngMaterial', 'ngMessages'])
.controller('myController', function($scope) {
$scope.statuses = ['Planned', 'Confirmed', 'Cancelled'];
$scope.options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', '...'];
$scope.submit = function(obj) {
// submit code goes here
console.log(obj);
};
$scope.reset = function() {
$scope.obj = {
status: ""
}
}
$scope.reset();
});
</script>
</head>
<body ng-app="firstApplication">
<form name="myForm" ng-app="myApp" ng-controller="myController" class="container-fluid" ng-submit="myForm.$valid && submit(obj)" novalidate>
<div class="row">
<div class="col-xs-8">
<md-input-container>
<md-radio-group id="status" ng-model="obj.status" class="">
<md-radio-button ng-repeat="s in statuses" ng-value="s">{{s}}</md-radio-button>
</md-radio-group>
<input type="text" ng-model="obj.status" name="status" style="max-height:0; opacity: 0; border: none" ng-required="true" aria-label="Status">
<div ng-messages="myForm.status.$error" role="alert">
<div ng-message="required">Status is required.</div>
</div>
</md-input-container>
</div>
</div>
<md-button type="button" ng-click="reset()">RESET</md-button>
<md-button class="md-primary" type="submit">SUBMIT</md-button>
</form>
</body>
</html>
Upvotes: 0
Reputation: 54
I try ng-disabled with material angular it works (in your case try to delete 'novalidate' attribut in your form balise)
Snippet:
<html lang="en">
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script language="javascript">
angular
.module('firstApplication', ['ngAnimate', 'ngAria', 'ngMaterial', 'ngMessages'])
.controller('myController', function($scope) {
$scope.statuses = ['Planned', 'Confirmed', 'Cancelled'];
$scope.options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', '...'];
$scope.submit = function(obj) {
// submit code goes here
console.log(obj);
};
$scope.reset = function() {
$scope.obj = {
name: "",
myselect: "",
status: ""
}
}
$scope.reset();
});
</script>
</head>
<body ng-app="firstApplication">
<form name="myForm" ng-app="myApp" ng-controller="myController" class="container-fluid" ng-submit="submit(obj)">
<div class="row">
<div class="col-xs-8">
<md-input-container>
<label>Name</label>
<input name="name" id="name" ng-model="obj.name" ng-required="true">
<div ng-messages="myForm.name.$error">
<div ng-message="required">Campaign Name is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container>
<md-select name="myselect" id="myselect" placeholder="myselect" ng-model="obj.myselect" ng-required="true">
<md-option ng-repeat="o in options" ng-value="o">{{o}}</md-option>
</md-select>
<div ng-messages="myForm.myselect.$error">
<div ng-message="required">myselect is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container>
<md-radio-group name="status" id="status" ng-model="obj.status" ng-required="true" class="">
<md-radio-button ng-repeat="s in statuses" ng-value="s">{{s}}</md-radio-button>
</md-radio-group>
<div ng-messages="myForm.status.$error">
<div ng-message="required">myselect is required.</div>
</div>
</md-input-container>
</div>
</div>
<md-button type="button" ng-click="reset()">RESET</md-button>
<md-button class="md-primary" type="submit" ng-disabled="myForm.$invalid">SUBMIT</md-button>
</form>
</body>
</html>
Upvotes: -1