Angular Material mandatory form inputs pop up alert - angularjs

I'm creating a Material form and have a couple required fields that are rendering correctly after following the examples found on here: https://material.angularjs.org/latest/demo/input
However, in their example, when required inputs aren't filled out and a user presses Submit, a popup alert shows up and I'm not sure how this is done:
My code looks like this:
<div ng-switch-when="choice">
<md-input-container class="md-block">
<label style="font-size: 130%; white-space: normal;" for="{{element.section_element_name}}">{{element.section_element_label}}</label>
<md-select ng-if="element.mandatoryFlag==1" required id = {{element.section_element_name}} type="selectbasic" value={{element.q_value}} ng-model="element.answer">
<md-option ng-repeat="option in element.section_element_choices" value="{{option.element_choice_value}}" >
{{option.element_choice_label}}
</md-option>
</md-select>
<div ng-messages="element.answer.$error" role="alert">
<div ng-message="required" class="my-message">Please provide an answer.</div>
</div>
<md-select ng-if="element.mandatoryFlag==0" id = {{element.section_element_name}} type="selectbasic" value={{element.q_value}} ng-model="element.answer">
<md-option ng-repeat="option in element.section_element_choices" value="{{option.element_choice_value}}" >
{{option.element_choice_label}}
</md-option>
</md-select>
</md-input-container>
</div>
<md-button ng-click="submit()" class="md-fab md-mini">
<md-tooltip md-direction="top">Save or Submit Form</md-tooltip>
<i class="material-icons" style="vertical-align:middle;">send</i>
</md-button>
What do I have to do for that pop up to show up if things aren't filled out onSubmit?

There is a lot of discussion related to this in Chrome popup Please Fill Out this Field. However this isn't a duplicate as you are asking a bit of the opposite question.
The answer to this is that the HTML5 required attribute behavior for <input> elements is different than the required behavior for <select> elements.
This CodePen demonstrates the popup working for a <select> element, but not working for the <md-select> element.
One issue is that the Material Select doesn't have a blank entry for the first option. However, even adding that doesn't make the popup appear.
The second issue is that the required is not applied to the hidden <select> element in the DOM. So the browser can't add the popup.
<select class="md-visually-hidden" name="type" aria-hidden="true" tabindex="-1">
<option value="app">Application</option>
<option value="web">Website</option>
<option ng-value="project.type" selected="" aria-checked="false"></option>
</select>
After all of this, you may just want to handle validation messages in the Material Design style and disable the popup completely using the steps included in the first link in this answer.

Related

How to perform Protractor testing in md-option

I have the code in angular which is
<md-input-container>
<label>Country </label>
<md-select name="country" ng-model="country"required >
<md-optgroup label="Select Country">
<md-option ng-repeat="item in countryList" ng-value="item" >
{{item.countryName}}
</md-option>
</md-optgroup>
</md-select>
</md-input-container>
and in have used the code in Protractor as following
element(by.model("country")).click();
browser.sleep(2000);
element.all(by.repeater("item in countryList").row('1')).click();
and I am always getting the game error as
Failed: element not visible
in the code the element(by.model("country")).click() is working fine but not selecting the md-option in popup window
please help.
Try with below code (You should get 1st element selected.
element(by.model("country")).click();
browser.sleep(2000);
element.all(by.repeater("item in countryList").get(1)).click();
If still facing issue You can try to scroll till that element.
element(by.model("country")).click();
browser.sleep(2000);
var elementToSelect = element.all(by.repeater("item in countryList").get(1));
browser.executeScript('arguments[0].scrollIntoView(true)',elementToSelect.getWebElement());
elementToSelect.click();

md-virtual-repeat not working wiht md-select

I'm trying to implement md-virtual-repeat for md-select which has more than 2000 items to select. This not working with the md-option.
<md-input-container>
<md-select ng-model="break.start_time" md-on-open="vm.mdSelectOnOpen()">
<md-virtual-repeat-container id="vertical-container">
<md-option md-virtual-repeat="option in vm.time" value="option.value" >{{option.text}}</md-option>
</md-virtual-repeat-container>
</md-select>
</md-input-container>
What is the problem with this? I have updated a plunker with my problem. see
Updated Answer
Since you are using md-virtual select the check boxes you can refer the below codepen, there was no need to add a check box itself since md-select has an attribute called multiple which will add the check boxes
Code
<md-input-container>
<label>Select an option</label>
<md-select ng-model="selectedOption" md-on-open="mdSelectOnOpen()" multiple>
<md-virtual-repeat-container id="vertical-container">
<md-option md-virtual-repeat="option in options" ng-value="option" ng-selected="selectedOption.indexOf(option) > -1">{{option}}</md-option>
</md-virtual-repeat-container>
</md-select>
</md-input-container>
Codepen: here
Old Answer
You need to give ng-selected option and ng-value.
<md-input-container>
<md-select ng-model="break.start_time" md-on-open="vm.mdSelectOnOpen()">
<md-virtual-repeat-container id="vertical-container">
<md-option md-virtual-repeat="option in vm.time" ng-value="option.value" ng-selected="break.start_time==option.value">{{option.text}}</md-option>
</md-virtual-repeat-container>
</md-select>
</md-input-container>
Refer: codepen
I know this is an old thread, but maybe this can help to someone.
If the following did not work
$scope.$broadcast("$md-resize")
use this instead:
angular.element(window).triggerHandler('resize')

md-select not binding to the object referenced by ng-model

I have a form with some md-select dropdowns which im trying to bind with a scope object in my angular controller.
The html looks like that :
<div id="horizontal_form_category" class="row">
<div class="col-md-2 col-lg-2" data-ng-repeat="r in categories[general]" dir="rtl">
<md-input-container>
<label> {{ r.name }} </label>
<md-select ng-model="formObject[r.name]" class="md-no-underline">
<md-option ng-repeat="option in r.values" ng-value="option "> {{ option }} </md-option>
</md-select>
</md-input-container>
</div>
</div>
The controller has a definition of the object $scope.formObject = {}; (Although it should work without it)
But, unfortunately, the $scope.formObject object in my controller stays empty.
Any ideas what could cause such weird behavior ? I have some normal bootstrap components whom ng-model is written the same and are working just fine.
Thanks
Does this help in any way? - CodePen
The true as the last parameter for $watch checks for changes in the object formObject.
Markup
<div ng-controller="AppCtrl" ng-cloak="" ng-app="MyApp">
<md-input-container>
<label> Options </label>
<md-select ng-model="formObject['Options']" class="md-no-underline">
<md-option ng-repeat="option in options" ng-value="option "> {{ option }} </md-option>
</md-select>
</md-input-container>
</div>
JS
angular.module('MyApp',['ngMaterial'])
.controller('AppCtrl', function($scope) {
$scope.options = ["Earth", "Saturn", "Jupiter"];
$scope.$watch("formObject", function () {
console.log($scope.formObject);
}, true)
});
Apparently there wasnt any bug.
My form's md-select were empty and therefore the formObject was empty.
The minute I started puting values, the formObject got filled, one field at a time, containing only the fields that were set.
I added a default value and everything is now showing correctly, just to be sure this was the "bug".
In retrospect, this bevahiour actually saves me some lines of code so I adopted it :)
Gotta thank #camden_kid answer for the $watch tip, helped me figure it out in matter of seconds.

$invalid not working in ng-if condition

In Angular 1.5, I have the following setup:
<form name="linksForm">
<md-input-container>
<label>Region</label>
<md-select ng-model="$ctrl.user.region">
<md-option ng-repeat="region in $ctrl.allRegions" value="{{region.id}}" ng-bind="region.name"></md-option>
</md-select>
</md-input-container>
<md-input-container ng-if="$ctrl.user.region">
<label>Territory</label>
<md-select ng-model="$ctrl.user.territory" name="territory" required>
<md-option ng-repeat="territory in $ctrl.getTerritories($ctrl.user.region)" value="{{territory.id}}" ng-bind="territory.name"></md-option>
</md-select>
</md-input-container>
<md-input-container ng-if="linksForm.territory.$valid">
<label>House</label>
<md-select ng-model="$ctrl.user.house">
<md-option ng-repeat="house in $ctrl.allHouses" value="{{house.id}}" ng-bind="house.name"></md-option>
</md-select>
</md-input-container>
</form>
Here is the logic:
At first, only the regions list is visible.
When a region is selected, the territory list appears with a list of territories from the selected region.
When a territory is selected, the house list appears.
So far, so good. The thing works. The only problem is when I change the region, here is what happens:
The territory list changes, and since ngModel cannot match any of the new options, the territory selector is now unset. This is working as expected, but...
The house list does not disappear, despite the territory selector being required, therefore the territory field should be invalid.

Using md-chips in forms with other inputs

I am trying to make use of md-chips alongside other inputs in a form that are inside md-input-containers.
I have had to add my own css hacks to get the placeholder text of the input, plus padding and margin applied to get it to look as close enough to an input inside an md-input-container as best I can.
I know I can't get md-chips to work inside an md-input-container (I dont think its supported yet)
Here is how I have an input followed by an md-chips appearing:
<div layout="row">
<md-input-container flex>
<label translate>Name</label>
<input ng-model="ctrl.name">
</md-input-container>
<div class="chips-container" flex>
<md-chips ng-model="ctrl.fruitNames">
<md-chip-template>
<span><strong>{{$chip}}</strong></span>
</md-chip-template>
<input type="text" placeholder="Enter Something">
<button md-chip-remove class="chip">
<md-icon class="material-icons">clear</md-icon>
</button>
</md-chips>
</div>
</div>
Working Codepen
Has anyone faced a similar situation needing to get md-chips with inputs aligning correctly alongside other inputs in similar layouts?
Just looking for suitable solutions, I can't see any combination examples on the Angular Material input demos.
Thanks

Resources