How can we make dependent select boxes in select2 with angular? - angularjs

I am using select2 with angularjs for select boxes in my application. There is one parent select box where user can select multiple groups and there are many other child select boxes with the same group selection feature.
My problem is how to restrict child group search options according to
parent group selected option. i.e. say if parent groups are Group1,
Group2, Group3 then the child group search box should avail the
options selected in parent groups only.
HTML:
<body ng-app="myModule">
<div ng-controller="myCtrl">
<div ng-repeat="activity in activities">
<br><br><br><br>
<div>
Parent Group:
<select multiple class="full-width" ui-select2="groupSetup" ng-model="activity.act_group_id" ng-init="activity.act_group_id=split_custom(activity.act_group_id,',',1)" data-placeholder="Select Group">
<option ng-repeat="group in groups | orderBy:'text'" value="{{group.id}}">{{group.text}}</option>
</select>
<p>selected parent groups {{activity.act_group_id}}</p>
</div>
<br><br>
<div>
Child Group:
<select multiple class="full-width" ui-select2="groupSetup" ng-model="activity.act_auto_approve_group" ng-init="activity.act_auto_approve_group=split_custom(activity.act_auto_approve_group,',',1)" data-placeholder="Select Group">
<option ng-repeat="group in groups | orderBy:'text'" value="{{group.id}}">{{group.text}}</option>
</select>
<p>selected child group {{activity.act_auto_approve_group}}</p>
</div>
</div>
</div>
</body>
JS:
var activityModule = angular.module('myModule', ['ui']);
activityModule.controller('myCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.activities = [{"act_name": "activity1", "act_group_id": "62,68", "act_auto_approve_group": "62"}];
$scope.groups = [{"text": "Group1", "id": 2}, {"text": "Group2", "id": 62}, {"text": "Group3", "id": 68}, {"text": "Group4", "id": 74}, {"text": "Group5", "id": 98}, {"text": "Group6", "id": 104}, {"text": "Group7", "id": 107}, {"text": "Group8", "id": 139}, {"text": "Group9", "id": 149}, {"text": "Group10", "id": 154}];
$scope.groupSetup = {
multiple: true,
formatSearching: 'Searching the group...',
formatNoMatches: 'No group found'
};
// custom function to convert string into attay (string arra or integer array)
$scope.split_custom = function(string, spliter, is_integer) {
$scope.ret_arr = string.split(spliter); // convert string into array
if (is_integer==1)
$scope.ret_arr = $scope.ret_arr.map(Number); // convert string array into integer array
return $scope.ret_arr;
};
}]);
http://plnkr.co/edit/dpX7jNkEgRoPyRZpJV92?p=preview

After 6 hours struggle, I was able to achieve this using ng-change event in a tricky way:
HTML :
1.Parent select box:
<select ng-change="parent_group_changed(activity)" multiple class="full-width" ui-select2="groupSetup" ng-model="activity.act_group_id" ng-init="activity.act_group_id=split_custom(activity.act_group_id,',',1)" data-placeholder="Select Group" >
<option ng-repeat="group in groups" value="{{group.id}}">{{group.text}}</option>
</select>
2.Child select box:
<select multiple class="full-width" ui-select2="groupSetup" ng-model="activity.act_auto_approve_group" ng-init="activity.act_auto_approve_group=split_custom(activity.act_auto_approve_group,',',1)" data-placeholder="Select Group">
<option ng-repeat="group in activity.act_groups | orderBy:'text'" value="{{group.id}}">{{group.text}}</option>
</select>
JS
$scope.groups = [{"text": "Group1", "id": 2}, {"text": "Group2", "id": 62}, {"text": "Group3", "id": 68}, {"text": "Group4", "id": 74}, {"text": "Group5", "id": 98}, {"text": "Group6", "id": 104}, {"text": "Group7", "id": 107}, {"text": "Group8", "id": 139}, {"text": "Group9", "id": 149}, {"text": "Group10", "id": 154}];
$scope.groups2 = $scope.groups;
$scope.groupSetup = {
multiple: true,
formatSearching: 'Searching the group...',
formatNoMatches: 'No group found'
};
$scope.parent_group_changed = function(activity) {
activity.act_groups=[];
for(var i=0; i<activity.act_group_id.length; i++)
{
var x = activity.act_group_id[i];
activity.act_groups.push($filter('filter')($scope.groups2, {id:x})[0]);
}
};
Plunker
http://plnkr.co/edit/07Uj8EdDlAyT54AkuaRQ?p=info

Related

How to use ng-options in array with objects

I have a data source that looks like this:
var categories =
[{
{"name":"First Category","subcats":[
{"name":"Sub Category 1"},
{"name":"Sub Category 2"},
{"name":"Sub Category 3"}]
},{
{"name":"Second Category","subcats":[
{"name":"Sub Category 1"},
{"name":"Sub Category 2"},
{"name":"Sub Category 3"}]
}]
I couldn't figure out how to use ng-options to show sub categories grouped by main category. Result should look like this:
<select>
<optgroup>First Category
<option>Sub Category 1</option>
<option>Sub Category 2</option>
<option>Sub Category 3</option>
</optgroup>
<optgroup>Second Category
<option>Sub Category 1</option>
<option>Sub Category 2</option>
<option>Sub Category 3</option>
</optgroup>
</select>
1) Fix your categories array;
2) Flatten it to use with ngOptions and group by.
Example:
angular.module('plunker', [])
.controller('MainCtrl', function($scope) {
var categories =
[
{
"name": "First Category",
"subcats": [
{"name": "Sub Category 1"},
{"name": "Sub Category 2"},
{"name": "Sub Category 3"}
]
},
{
"name": "Second Category",
"subcats": [
{"name": "Sub Category 1"},
{"name": "Sub Category 2"},
{"name": "Sub Category 3"},
{"name": "Sub Category 4"}
]
}
];
$scope.options = [];
angular.forEach(categories, function (category){
angular.forEach(category.subcats, function (subCat){
subCat.categoryName = category.name;
$scope.options.push(subCat);
});
});
});
<script src="https://code.angularjs.org/1.6.2/angular.js" ></script>
<html ng-app="plunker">
<body ng-controller="MainCtrl">
<select ng-model="test.model"
ng-options="option.name group by option.categoryName for option in options">
</select>
</body>
</html>
this.categories =
[
{
"name": "First Category",
"subcats": [
{ "name": "Sub Category 1" },
{ "name": "Sub Category 2" },
{ "name": "Sub Category 3" }]
},
{
"name": "Second Category",
"subcats": [
{ "name": "Sub Category 4" },
{ "name": "Sub Category 5" },
{ "name": "Sub Category 6" }]
}
];
and in template:
<select>
<optgroup *ngFor="let category of categories;" label="{{category.name}}">
<option *ngFor="let sub of category.subcats;">{{sub.name}}</option>
</optgroup>

In Angular how can you dynamically add an input to be applied once

I have searched the web and found no example. I wonder if someone could help.
I have two instances of a dropdown or maybe more and I want to apply the add input dynamically to only that form but it applies to everyone with that ng-model everywhere on the web page.
The code is here https://plnkr.co/edit/PPDYKjztPF528yli9FbN
HTML:
<div class="main-content__right" ng-controller="QuestionController">
<div ng-repeat="element in questionList">
<fieldset>
<div ng-repeat="choice in formOptionData track by $index">
<a class="remove-field remove u-pull-right" ng-click="remove()">Remove</a>
<input id="input{{choice.name}}" placeholder="{{choice.label}}" type="number" name="{{choice.name}}">
</div>
<div id="add-more" class="well">
<div class="field">
<div style="width:100%;" class="dropdown">
<select name="{{options.name}}" id="select" data-ng-model="selectedValue" data-ng-options="options as options.label for options in element.inputElement | orderBy:'label'" ng-change="onCategoryChange(selectedValue)">
<option value="" data-id="null" disabled="" selected="">Select an item...</option>
</select>
</div>
</div>
{{formData}}
</div>
</fieldset>
</div>
</div>
APP.js
var app = angular.module("cab", []);
app.controller('QuestionController', function($scope) {
$scope.formOptionData = [];
$scope.selectedValue = {};
$scope.questionList = [{
"sectionTitle": "Travel",
"inputType": "select",
"inputElement": [{
"label": "Public transport",
"name": "travelOutgoing",
"helpInfo": "include train journeys",
"type": "select"
}, {
"label": "Taxis",
"name": "travelOutgoing",
"type": "select"
}
]
},
{
"sectionTitle": "Leisure",
"title": "Enter the amount you spend on entertainment and leisure. Leave them blank if they don\"t apply to you.",
"inputType": "select",
"inputElement": [
{
"label": "Eating out",
"name": "leisureOutgoing",
"helpInfo": "Include coffees, teas and snacks",
"type": "select"
},
{
"label": "Going out",
"name": "leisureOutgoing",
"helpInfo": "Include drinks, taxis, admission charges",
"type": "select"
}
] }
];
$scope.onCategoryChange = function(selectedItem) {
this.formOptionData.push(selectedItem);
};
$scope.remove = function(element) {
this.formData.splice(element,1);
};
});

How to add multiple input box dynamically with dropdown in angularjs

I am having this problem which I can't find the solution to.
1) I have a dropdown list which the data is pull in from a json file
2) When the user selects a item I want to dynamically add a input box without a button.
Got a jQuery code but wanted to do it the angular way, but read that ng-Change is not the same as jquery .change?
Can anyone help or point me into the right direction of how to do this.
HTML
<div class="main-content__right" ng-controller="QuestionController">
<div ng-repeat="element in questionList">
<fieldset>
<div id="add-more" class="well">
<div class="field">
<div style="width:100%;" class="dropdown">
<select name="{{options.name}}" id="select" data-ng-model="formData"
data-ng-options="options as options.label for options in element.inputElement | orderBy:'label'"
ng-change="onCategoryChange(formData)">
<option value="" data-id="null" disabled="" selected="">Select an item...</option>
</select>
</div>
</div>
{{formData}}
</div>
</fieldset>
</div>
app.js
var app = angular.module("cab", []);
app.controller('QuestionController', function($scope) {
var $scope.formData = {};
$scope.questionList = [{
"sectionTitle": "Travel",
"subTitle": "How much do you spend on these items for your car?",
"inputType": "select",
"inputElement": [{
"label": "Public transport",
"name": "travelOutgoing",
"helpInfo": "include train journeys",
"type": "select"
}, {
"label": "Taxis",
"name": "travelOutgoing",
"type": "select"
}, {
"label": "Bicycle",
"name": "travelOutgoing",
"helpInfo": "general running costs such as repair or rental",
"type": "select"
}, {
"label": "Car rental",
"name": "travelOutgoing",
"helpInfo": "include fuel, parking charges and tolls",
"type": "select"
}
]
}];
$scope.onCategoryChange = function () {};
});
can be found on http://plnkr.co/edit/PPDYKjztPF528yli9FbN?p=preview
Your controller function needs to add each selection to an array on scope:
Controller
app.controller('QuestionController', function($scope) {
$scope.formData = [];
$scope.selectedValue = {};
$scope.questionList = [{
"sectionTitle": "Travel",
"subTitle": "How much do you spend on these items for your car?",
"inputType": "select",
"inputElement": [{
"label": "Public transport",
"name": "travelOutgoing",
"helpInfo": "include train journeys",
"type": "select"
}, {
"label": "Taxis",
"name": "travelOutgoing",
"type": "select"
}, {
"label": "Bicycle",
"name": "travelOutgoing",
"helpInfo": "general running costs such as repair or rental",
"type": "select"
}, {
"label": "Car rental",
"name": "travelOutgoing",
"helpInfo": "include fuel, parking charges and tolls",
"type": "select"
}]
}];
$scope.onCategoryChange = function(selectedItem) {
$scope.formData.push(selectedItem)
};
});
Then you can use an ng-repeat to render all of the items in formData.
HTML
<fieldset>
<div id="add-more" class="well">
<div class="field">
<div style="width:100%;" class="dropdown">
<select name="{{options.name}}" id="select" data-ng-model="selectedValue" data-ng-options="options as options.label for options in element.inputElement | orderBy:'label'" ng-change="onCategoryChange(selectedValue)">
<option value="" data-id="null" disabled="" selected="">Select an item...</option>
</select>
</div>
</div>
<div ng-repeat="item in formData track by $index">
<input ng-model="item.label" />
</div>
</div>
</fieldset>

Update <select> tag inside ng-if in angularjs

I would like to update the list of states on selection of country. I have researched a bit into this where it was recommended to use $parent as ng-if does not work on controller scope.But that too is not working for me.
Can someone please help me understand how to get the values into state select control.
Also I would also like to know what if there are multiple ng-if in my HTML. (again nested $parent.$parent.$parent... is not working)
Plunker Link : Plunker Link
"use strict";
var app = angular.module("app", []);
function CountriesController($scope) {
$scope.condition = true;
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
}
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="CountriesController">
<div ng-if="condition">
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()">
<option value="">Select country</option>
</select>
<br>
<select data-ng-model="state" data-ng-options="state.name for state in availableStates">
<option value="">Select state</option>
</select>
<br> Country: {{country}}
<br> State: {{state}}
</div>
</body>
</html>
Instead of making a separate list, you can use your country list by filtering
filter: {countryId: $parent.country.id}
"use strict";
var app = angular.module("app", []);
function CountriesController($scope) {
$scope.condition = true;
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
}
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="CountriesController">
<div ng-if="condition">
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="">
<option value="">Select country</option>
</select>
<br>
<select data-ng-model="state" data-ng-options="state.name for state in states | filter:{countryId: country.id}:true">
<option value="">Select state</option>
</select>
<br> Country: {{country}}
<br> State: {{state}}
</div>
</body>
</html>
Here is simplest way to init selected option:
for blank form, just init with option value that you want (don't forget the double single quotes)
<select ng-model="$ctrl.data.userlevel" ng-init="$ctrl.data.userlevel='0'">
<option value="0">User</option>
<option value="1">Admin</option>
</select>
for loaded data form, just init using that loaded model data, like below:
<select ng-model="$ctrl.data.userlevel" ng-init="$ctrl.data.userlevel=''+$ctrl.data.userlevel">
<option value="0">User</option>
<option value="1">Admin</option>
</select>
i think, init value should be string. so they need to concat with double single quotes.

Display Groupname with selected item on Dropdown using angularjs?

This is my Code
var app = angular.module('myExample', []);
function myCtrl($scope) {
$scope.myOptions = [{
"id": 106,
"group": "Employee",
"label": "Id"
},{
"id": 107,
"group": "Employee",
"label": "Name"
},{
"id": 110,
"group": "Department",
"label": "Id"
}];
$scope.getSelectedField=function(){
//$scope.myOption=$scope.myOption;
alert($scope.myOption);
};
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="myCtrl">
<select
ng-model="myOption"
ng-options="value.group+'.'+value.label as value.label group by value.group for value in myOptions" ng-change="getSelectedField()" >
<option>--</option>
</select>
<div>
selected value: {{myOption}}
</div>
</div>
The above code selected Item display on dropdown , But I want to display Groupname with Selected Item on Dropdown.for example when user select id now display 'Employee.id' on Dropdown.
Try
Here value.group+'.'+value.label will display on dropdown. Before you were displaying only value.label.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="myCtrl">
<select
ng-model="myOption"
ng-options="value.group+'.'+value.label as value.group+'.'+value.label group by value.group for value in myOptions" ng-change="getSelectedField()" >
<option>--</option>
</select>
<div>
selected value: {{myOption}}
</div>
</div>

Resources