angular: how do I make a dependent required field country->state? - angularjs

I have a field country. Some countries in the list like the US or Canada are divided into states. When such countries are selected, a second select appears and is required.
HTML:
<label>Country*</label>
<select name="country" class="gu3" ng-model="companyCriteria.country" ng-options="country.label for country in countries" required=""></select>
<div class="row" ng-show="stateAvailable">
<label>Province*</label>
<select name="state" class="gu3" ng-model="companyCriteria.state" required="">
<option ng-repeat="state in states" value="{{state.code}}">{{state.label}}</option>
</select>
</div>
Controller:
app.controller('CompanyController', function ( $scope, companies , Countries, States ... ) {
//...
$scope.countries = Countries;
$scope.states = [];
$scope.stateAvailable = false;
$scope.$watch( 'companyCriteria.country', function( after, before ) {
if ( searchCompanyCriteria.country && searchCompanyCriteria.country.div ) {
$scope.states = States.get( after.code );
$scope.stateAvailable = true;
} else {
$scope.states = [];
$scope.stateAvailable = false;
}
} );
$scope.search = function () {
if ( !$scope.companyForm.$valid ) return; //Returns when states are hidden
//Do search ...
};
the problem is that $scope.companyForm.$valid is false when the state select is hidden. I'm not sure how to proceed to code it in an angular and elegant way (without having to hack with the dom the jquery way).
Note: Angular v1.2.0-rc.3

Instead of ng-show use ng-if (assuming you're using angular 1.1.5 or higher):
<div class="row" ng-if="stateAvailable">
<label>Province*</label>
<select name="state" class="gu3" ng-model="companyCriteria.state" required>
<option ng-repeat="state in states" value="{{state.code}}">{{state.label}}</option>
</select>
</div>
Or, just use ng-required:
<select name="state" ng-model="companyCriteria.state" ng-required="stateAvailable">
<option ng-repeat="state in states" value="{{state.code}}">{{state.label}}</option>
</select>

You can use ng-required to resolve an angular expression and set the field to required:
<label>Country*</label>
<select name="country" class="gu3" ng-model="companyCriteria.country" ng-options="country.label for country in countries" required=""></select>
<div class="row" ng-show="stateAvailable">
<label>Province*</label>
<select name="state" class="gu3" ng-model="companyCriteria.state" ng-required="companyCriteria.country">
<option ng-repeat="state in states" value="{{state.code}}">{{state.label}}</option>
</select>
</div>
This will only require the state, if the country has been set with a value. However, you can put in any scoped expression here (so if you want to call a controller function returning a boolean, that would work as well).
The documentation for ng-required is here.

Related

AngularJs: Ng-model object and single model Together

I do not have enough English to describe it, but I think you will understand it from the codes.
Basically my problem is that ng-model = "" ng-options = "" does not come up with form data when used together.
<select class="form-control" name="car_id" ng-model="car_id" ng-options="I.car_brand_code as I.car_brand_name for I in CarList" ng-change="GetState()" >
<option value="">Select Car</option>
</select>
The selection box for the brands of these cars
<div class="form-group">
<label class="mtb10">Model Year</label>
<input type="text" name="modelYear" class="form-control" ng-model="data.modelYear" placeholder="Car Year...">
</div>
This is the other form objects. Where ng-model is a different data "data." I can get it. How can I get the value in the selection box.
I need to get the "car_id" value.
Try this :
On change of the dropdown options pass the selected value into the function as a param.
Use array.filter() method to fetch the model year for the selected car based on the car id.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',function($scope) {
$scope.CarList = [
{
"car_brand_code": 1,
"car_brand_name": "Maruti",
"model_year": 1990
},
{
"car_brand_code": 2,
"car_brand_name": "Ford",
"model_year": 2005
}
];
$scope.GetState = function(carId) {
var selectedCar = $scope.CarList.filter(function(item) {
return item.car_brand_code == carId;
});
$scope.data = {
"modelYear" : selectedCar[0].model_year
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<select class="form-control" name="car_id" ng-model="car_id" ng-options="I.car_brand_code as I.car_brand_name for I in CarList" ng-change="GetState(car_id)" >
<option value="">Select Car</option>
</select>
<div class="form-group">
<label class="mtb10">Model Year</label>
<input type="text" name="modelYear" class="form-control" ng-model="data.modelYear" placeholder="Car Year...">
</div>
</div>

How to append the dependable API in angular js?

<body ng-controller="myController">
<select ng-change="getData(currentSelected)" class="form-control" id="selection" ng-model="currentSelected" ng-options="selection as selection for selection in data">
<option value="" selected>Select the bankname</option>
</select>
<select ng-change="getData(currentSelectedstate)" class="form-control" id="selection" ng-model="currentSelectedstate" ng-options="my.state as my.state for my in newdata">
<option value="" selected>Select the state</option>
</select>
<select ng-change="getData1(currentSelecteddistrict)" class="form-control" id="selection" ng-model="currentSelecteddistrict" ng-options="my.district as my.district for my in data1">
<option value="" selected>Select the district</option>
</select>
</body>
JS code
<script>
var app=angular.module("mainApp",[]);
app.controller("myController", ["$scope", "$http",function ($scope,$http){
$http.get("company.in/ifsc/banklist").then(function(response){
$scope.data=response.data[0].data;
});
$scope.getData = function(name){
$http.get("company.in/ifsc/state/" +name).then(function(response) {
scope.newdata = response.data;
});
}
$scope.getData1= function(name1){
$http.get("company.in/ifsc/district/"+banklist+, +name).then(function(response) {
$scope.data1 = response.newdata;
});
}
}]);
</script>
First two API are working fine, When i select particular state in second drop down its not taking the value , How to append fetched bankname and state to the third API? so that i get the list of district in the third drop down....,I'm getting state value as null once i select the state..
Anyone please help how to append the third API?
Thank you

ng-repeat in AngularJS not working

Here is a simple Select done in Angular
<select ng-model="myCar">
<option ng-repeat="car in cars" value="{{car}}">{{car}}</option>
</select>
I have the following in my scope in angular.js
$scope.cars = ["Toyota", "Ford", "Rolls"];
why isn't the options showing up, instead I get {{car}}
You can try this.
<select ng-model="myCar" ng-options = "car for car in cars" ng-init="myCar = 'Rolls'">
</select>
or this
<select ng-model="myCar" ng-init="myCar = 'Rolls'">
<option ng-repeat="car in cars" value={{car}}>{{car}}</option>
</select>
Your's code is working fine. Only the default value isn't selected, so at the beginning it shows blank.
Refer here.
HTML:
<div ng-app="app" ng-controller="test">
<select ng-model="myCar">
<option value="">Select</option>
<option ng-repeat="car in cars" value="{{car}}">{{car}}</option>
</select>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.cars = ["Toyota", "Ford", "Rolls"];
});

Angularjs select value is undefined

Now I am trying to get the value from select dropdown, but it return undefined. The thing is in html level it works as expect, Here is my code:
<div class='subcontent'>
<input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y"><label for="me" class='choosemethod'>Me</label>
<input id="company" type="radio" ng-model="paymentmethod" value="N" class='choosemethod'><label for="company" class='choosemethod'>My Company</label><br/>
<span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>
<div class='paymentmethods subcontent' ng-switch on="paymentmethod">
<select ng-model='selectedmethod' ng-init="selectedmethod=Memethods[0]" id='methods' ng-switch-when='Y'>
<option ng-repeat="method in Memethods" value="{{method}}">{{method}}</option>
</select>
<select ng-model='selectedmethod' ng-init="selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
<option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
</select>
<div class='clear'></div>
<label for ='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>
In js:
$scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
$scope.companies = ['Company Paid','MyAMEX'];
it shows fine in page, but when I try to get the value, it shows undefined. any idea?
This is the classic "angular dot notation" issue.
Here is a working example
Basically, ng-switch creates a new scope, so when the select sets the selectedmethod property, it is doing so on the new scope, not the controller scope as you are expecting. One solution is to create a parent object for your model.
angular.module('app',[])
.controller('main', function($scope){
$scope.selection = {};
$scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
$scope.companies = ['Company Paid','MyAMEX'];
})
and note how it's referenced differently in the html:
<select ng-model='selection.selectedmethod' ng-init="selection.selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
<option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
</select>
A different (maybe better) way would be to use the "ControllerAs" syntax, which has the effect of doing this for you.
angular.module('app',[])
.controller('main', function($scope){
this.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
this.companies = ['Company Paid','MyAMEX'];
})
<body ng-app="app" ng-controller="main as main">
<div class='subcontent'>
<input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y">
<label for="me" class='choosemethod'>Me</label>
<input id="company" type="radio" ng-model="paymentmethod" value="N" class='choosemethod'>
<label for="company" class='choosemethod'>My Company</label>
<br/>
<span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>
<div class='paymentmethods subcontent' ng-switch on="paymentmethod">
<select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.Memethods[0]" id='methods' ng-switch-when='Y'>
<option ng-repeat="method in main.Memethods" value="{{method}}">{{method}}</option>
</select>
<select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.companies[0]" ng-switch-when='N' style='float:left'>
<option ng-repeat='companyoption in main.companies' value="{{companyoption}}">{{companyoption}}</option>
</select>
<div class='clear'></div>
<label for='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>
<div>{{main.selectedmethod}}</div>
</body>
you can refer to this simple example
html code :
<div ng-controller="Main" ng-app>
<div>selections = {{selections}}</div>
<div>
<p>Model doesn't get updated when selecting:</p>
<select ng-repeat="selection in selections" ng-model="selection" ng-options="i.id as i.name for i in items">
<option value=""></option>
</select>
</div>
js code:
function Main($scope) {
$scope.selections = ["", "id-2", ""];
$scope.reset = function() {
$scope.selections = ["", "", ""];
};
$scope.sample = function() {
$scope.selections = [ "id-1", "id-2", "id-3" ];
}
$scope.items = [{
id: 'id-1',
name: 'Name 1'},
{
id: 'id-2',
name: 'Name 2'},
{
id: 'id-3',
name: 'Name 3'}];
}
The ng-model inside value must have Initialize before it represents. So the ng-init comes before the ng-model. inside the options $first is used for select the first value.
<select ng-init= "selectedmethod=companies[0]" ng-model='selectedmethod' ng-switch-when='N' style='float:left'>
<option ng-repeat='companyoption in companies' value="{{companyoption}}" ng-selected="$first">{{companyoption}}
</option>
</select>

Generating proper options for select using ng-options

Trying to get the options in the select field to use the IDs in an array as values.
HTML looks like this:
<select class="form-control" name="activitySelector"
ng-model="item"
ng-change="changeActivity()"
ng-options="activity.id as activity.value for activity in activities">
<option value="">Nothing selected</option>
</select>
Controller:
angular.module('myApp')
.controller('ActivityCtrl', function ($scope, $rootScope) {
$scope.activities = [
{"id":"54be7f8","value":"Add New Activity"},
{"id":"5407968","value":"Activity 1"}
];
$scope.item = "";
$scope.changeActivity = function() {
console.log($scope.item); //prints undefined
}
});
Generated HTML looks like this:
<select ng-options="activity.id as activity.value for activity in activities" ng-change="changeActivity()" ng-model="item" class="form-control ng-pristine ng-valid">
<option value="" class="">Nothing selected</option>
<option value="0">Add New Activity</option>
<option value="1">Activity 1</option>
</select>
Questions that I have so far:
1- Why $scope.item prints undefined?
2- Why the options would use a consecutive value instead of the ID provided?
You can modify your code as follows in order for your html to render as you wish:
<select class="form-control" name="activitySelector"
ng-model="item"
ng-change="changeActivity()"
ng-options="activity.value for activity in activities track by activity.id">
<option value="">Nothing selected</option>
</select>
And in your controller now, you should change as follows:
$scope.changeActivity = function() {
console.log($scope.item.id);
console.log($scope.item.value);
}
Here is the Plunker: http://plnkr.co/edit/DWobFzvas9x4lhaoNfTI.

Resources